2017-02-01 4 views
1

Я пытаюсь использовать Logstash и ГРОК разобрать грязный CSV файл.Logstash Грязный CSV файл

Первоначально я использовал CSV-фильтр, но это означало, что мне пришлось сначала удалить кучу данных заголовка в предварительной обработке.

В идеале я хотел бы снова использовать CSV-фильтр из-за его простоты. Я не контролирую, как поступают файлы CSV. В идеале мне бы хотелось Logstash для обработки всего без предварительной обработки.

Ниже приведен пример моего CSV файла:

1,2,3,4,5,6,7 
"text" 
"text" 

"01-Jan-2012" 
"" 

0,0,0,0,0,0,0,0,0,0 

"col1Header",[...],col17Header" 
"col1UoM",[...],col17UoM" 

01-Jan-2012 11:00:01,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 
01-Jan-2012 11:00:02,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 
01-Jan-2012 11:00:03,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 
01-Jan-2012 11:00:04,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 

Это мой Logstash конфигурации, он выдает ошибку, показанную в комментариях:

input{ 
file{ 
    path => ["/opt/docs/*"] 
    type => "log" 
    start_position => "beginning" 
    sincedb_path => "/dev/null" 
    ignore_older => 0 
    } 
} 
filter{ 
    grok{ 
     # error being returned here 
     # error is: "Expected one of #, {, } at line 27, column 110 (byte 906) after filter{\n\t\n\n\t 
# the regex following is to match all the header data that I don't want. 
     match => {"header_data" => "(?<header_data>[0-9].*\n.*\n.*\n.*\n.*\n.*\n.*\n.*\n.*\n.*\n.*\n.*\n.*\n.*\n.*"\n)"} 
    } # my plan was to then drop the header_data field (not implemented) and the data would be sent to the csv filter 
    csv{ 
     columns => ["col17Header",[...],"col17Header] 
    } 
    mutate{ 
     convert => {"col2" => "float",[...] => "float","col17" => "float"} 
    } 
    date{ 
     match => ["col1","dd-MMM-YYYY HH:mm:ss"] 
    } 
} 


output{ 
    elasticsearch{ 
     action => "index" 
     hosts => ["192.168.1.118:9200"] 
     index => "foo-logs" 
    } 
} 

Для ясности здесь есть ошибка:

«Ожидаемая одна из #, {,} в строке 27, столбец 110 (байт 906) после фильтр {\ n \ t \ n \ n \ t # следующее регулярное выражение соответствует всем данным заголовка, я хочу. матч => { "header_data" => «(? [0-9]. \ п. \ п. \ п. \ п. \ п. \ п. \ п. \ п . \ п. \ п. \ п. \ п. \ п. \ п. * "\ п)"}

Я хотел бы, чтобы удалить все данные выше датированных 4 строки внизу. Я сделал (что я считаю неэффективным) regex шаблоны для поиска заголовка и CSV данные.

Все, что мне нужно от CSV файл - это последние 4 строки в файле примера, вот все необходимые мне данные.

Мои мысли, что я сейчас не собираюсь делать это правильно, поэтому я открыт для любых предложений.

ответ

0

Из вашего примера, строки, которые вы хотите иметь уникальный шаблон:

^%{MONTHDAY}-%{MONTH}-%{YEAR} 

ГРОК для этой модели. Для строк, которые не совпадают, вы получите grokparsefailure и затем можете использовать фильтр drop {}, чтобы игнорировать их.

+0

Удивительно, спасибо за помощь! Просто для уточнения для других читателей, это часть моей конфигурации, что я изменил и добавил: 'фильтр { \t ГРОК { \t \t матч => { "сообщение"=>«^% {MONTHDAY} -% {МЕСЯЦ} -% {ГОД} "} \t} \t если "_grokparsefailure" в [теги] { не \t \t падение {} \t} \t CSV {' Мой реальный вопрос я не понимал, что если шаблон grok соответствовал части линии, тогда он соответствовал остальной части события и передавал его в поле «сообщение» t o следующий фильтр, фильтр CSV в моем случае. P.S. Я бы поддержал ваш ответ, но моя репутация n00bish не позволяет этого. – RossM