Вопрос или проблема
Я пытался передать логи из приложения Windows, которые уже отформатированы в формате JSON, в logstash через NXlog.
Когда я отправляю файл в Logstash через NXLOG, я получаю множество ошибок в logstash.log:
:message=>"Произошла ошибка. Закрытие подключения",
:client=>"10.xxx.xxx.147:61047",
:exception=>#<IndexError: строка не найдена>
Полный текст ошибки:
{:timestamp=>"2015-04-25T15:15:37.084000-0900", :message=>"Произошла ошибка. Закрытие подключения", :client=>"10.xxx.xxx.147:61047", :exception=>#<IndexError: строка не найдена>, :backtrace=>["org/jruby/RubyString.java:3910:in `[]='", "/opt/logstash/lib/logstash/event.rb:62:in `initialize'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-codec-json_lines-0.1.6/lib/logstash/codecs/json_lines.rb:37:in `decode'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-codec-line-0.1.5/lib/logstash/codecs/line.rb:36:in `decode'", "org/jruby/RubyArray.java:1613:in `each'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-codec-line-0.1.5/lib/logstash/codecs/line.rb:35:in `decode'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-codec-json_lines-0.1.6/lib/logstash/codecs/json_lines.rb:35:in `decode'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-input-tcp-0.1.3/lib/logstash/inputs/tcp.rb:116:in `handle_socket'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-input-tcp-0.1.3/lib/logstash/inputs/tcp.rb:145:in `client_thread'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-input-tcp-0.1.3/lib/logstash/inputs/tcp.rb:143:in `client_thread'"], :level=>:error}
{:timestamp=>"2015-04-25T15:15:38.097000-0900", :message=>"Ошибка разбора JSON. Переход на обычный текст", :error=>#<LogStash::Json::ParserError: Неожиданный конец ввода: ожидается закрывающий маркер для ОБЪЕКТА (из [Источник: [B@26f64966; строка: 1, столбец: 2])
at [Источник: [B@26f64966; строка: 2, столбец: 5]>, :data=>" {\r\n", :level=>:info}
Вот моя конфигурация NXLOG:
## Пожалуйста, установите ROOT в папку, в которую был установлен ваш nxlog,
## иначе он не запустится.
define ROOT C:\Program Files (x86)\nxlog
Moduledir %ROOT%\modules
CacheDir %ROOT%\data
Pidfile %ROOT%\data\nxlog.pid
SpoolDir %ROOT%\data
LogFile %ROOT%\data\nxlog.log
<Extension json>
Module xm_json
</Extension>
# Внутренние логи Nxlog
<Input internal>
Module im_internal
Exec $EventReceivedTime = integer($EventReceivedTime) / 1000000; to_json();
</Input>
# Журнал событий Windows
<Input eventlog>
Module im_msvistalog
Exec $EventReceivedTime = integer($EventReceivedTime) / 1000000; to_json();
</Input>
# Логи сервера
<Input Selected_Directory>
Module im_file
File 'E:\\ELK\\logs\\*.json'
SavePos False
</Input>
#Вывод журнала событий
<Output out>
Module om_tcp
Host 10.xxx.xxx.127
Port 3515
</Output>
#<output perf_out>
# Module om_tcp
# Host 10.xxx.xxx.127
# Port 3517
#</Output>
#Вывод JSON
<Output out2>
Module om_tcp
Host 10.xxx.xxx.127
Port 3516
</Output>
<Route 1>
Path internal, eventlog => out
</Route>
<Route 2>
Path Selected_Directory => out2
</Route>
Конфигурация LogStash:
input {
tcp {
type => "eventlog"
port => 3515
codec => json_lines
}
tcp {
type => "log"
port => 3516
codec => json
}
}
output {
elasticsearch {
cluster => "MyElkCluster"
host => "127.0.0.1"
}
}
Пример формата JSON файла приложения:
[
{
"timestamp":"19:54:01.117_0005",
"type":"N",
"calllevel":0,
"thread":772,
"topic":"ExmpleTopic",
"level":61,
"file":"//blah/blah/blah.cpp",
"function":"functiontext",
"line":312,
"message":"Example Message Text",
"attributes":
{
"ThreadName":"1234"
}
},
{
"timestamp":"20:07:54.038_0691",
"type":"N",
"calllevel":0,
"thread":2324,
"topic":"ExampleTopic",
"level":61,
"file":"//blah/blah/blah.cpp",
"function":"ExampleFunction",
"line":2962,
"message":"Example Message Text",
"attributes":
{
"ThreadName":"1234"
}
}
]
У меня есть два дополнительных вопроса, помимо очевидного “помогите разобраться с этой ошибкой”
- В чем разница между json_lines и json в контексте ввода logstash? Я считал, что json_lines предназначен для потокового текста, а json подразумевает, что я отправлю весь файл сразу.
- Нужно ли мне добавлять “exec to_json();” в мой nxlog input с именем ‘selected_directory’?
Я бы посоветовал попробовать tcp input, забыть об определении кодека во входных данных, это, как правило, плохая идея, как я выяснил:
input {
tcp {
type => "eventlog"
port => 3515
}
}
filter {
multiline {
pattern => "^\s"
what => "previous"
}
json {
"source" => "message"
}
}
output {
elasticsearch {
cluster => "MyElkCluster"
host => "127.0.0.1"
}
}
Так что в этой конфигурации она будет принимать трафик на определенном tcp порту, не устанавливая кодек, затем передавать входные данные в многострочный фильтр, который будет искать строки, которые начинаются с пробела, и если найдет, будет присоединять их к предыдущей строке. Эта новая строка, созданная многострочным фильтром, затем будет передана в json фильтр, который должен быть способен разобрать запись.
Я также получал ошибку при использовании кодека json_lines, которая говорила:
IndexError: строка не найдена
и решил ее, убедившись, что генерируемая мною JSON строка не содержит символов новой строки (например, “\n”), кроме тех случаев, когда они следуют сразу после JSON объекта, в качестве разделителя.
.
Ответ или решение
Передача JSON логов приложения на удаленный LogStash через NXLog на Windows является важной задачей, особенно в условиях, когда необходимо настроить централизованное управление логами на предприятии. В данном случае ошибки, получаемые при попытке передачи логов, требуют детального анализа и устранения. Давайте рассмотрим возможные причины возникновения ошибок и предложим способы их устранения.
Теория
Передача логов в формате JSON через NXLog к LogStash предполагает использование различных компонентов конфигурации, таких как модули для захвата и передачи логов, а также специфичных настроек для обработки JSON формата.
Основные компоненты конфигурации:
- NXLog: утилита для сбора логов, которая может передавать данные в различные сервисы, включая LogStash.
- LogStash: инструмент для обработки и анализа больших объемов данных, получаемых из множества источников.
- JSON форматы: необходимо четко понимать различие между
json
иjson_lines
.json
предполагает передачу одной или нескольких JSON объектов, тогда какjson_lines
предполагает потоковую передачу, где каждый объект занимает отдельную строку.
В рассматриваемом случае, ошибки могут быть вызваны несоответствием входящего формата данных и ожидаемого формата LogStash.
Пример
В приложенном примере конфигурации содержатся несколько ключевых элементов:
-
Конфигурация NXLog
- Определены модули для чтения внутренних логов, логов событий Windows и файлов JSON.
- Выходные модули, настроенные с применением
om_tcp
, передают логи на указанный хост и порты.
-
Конфигурация LogStash
- Определены входы, использующие разные кодеки:
json_lines
иjson
. - Логи направляются в Elasticsearch для дальнейшей обработки.
- Определены входы, использующие разные кодеки:
Ошибки возникают при попытке LogStash проанализировать входящие данные. В частности, ошибка IndexError: string not matched
может быть связана с несовпадением форматов строк, тогда как ошибка JSON parse failure
указывает на проблему распознавания структуры JSON.
Применение
Устранение ошибок начинается с внесения изменений в конфигурацию для корректной обработки JSON данных.
-
Проверьте формат ваших JSON данных. Убедитесь, что ваши JSON строки не содержат несовместимых символов, таких как разрывы строк, которые могут повлиять на анализ JSON в LogStash.
-
Измените конфигурацию LogStash. Согласно предложению в дополнительной информации, попробуйте убрать задание кодеков в
tcp
входах LogStash и используйте фильтры для управления входными данными. Этот подход может помочь избежать ошибок, связанных с разбором данных.input { tcp { type => "eventlog" port => 3515 } } filter { multiline { pattern => "^\s" what => "previous" } json { source => "message" } } output { elasticsearch { cluster => "MyElkCluster" host => "127.0.0.1" } }
-
Убедитесь в целостности передаваемых JSON объектов. Если ваши JSON данные содержат массив объектов, убедитесь, что каждый объект отправляется в правильной форме. Это может включать добавление
\n
в конце каждой JSON строки, что требуется форматуjson_lines
. -
Конфигурация NXLog. Проверьте, нужно ли добавлять
exec to_json();
для вашейselected_directory
конфигурации. Если логи уже в формате JSON, дополнительное преобразование может вызвать дублирование или искажение данных. -
Тестирование. Проведите тестирование изменений в изолированной среде, чтобы наблюдать, устранились ли ошибки и корректность обработки данных сохраняется.
Настройка передачи логов корректного формата и конфигурация фильтров являются ключевыми шагами для успешной интеграции системы управления логами с использованием NXLog и LogStash. Эти изменения могут значительно улучшить чистоту и управляемость логов в вашей IT-инфраструктуре.