Π”Ρ€ΡƒΠΆΠΈΠΌ ELK ΠΈ Exchange. Π§Π°ΡΡ‚ΡŒ 2

Π”Ρ€ΡƒΠΆΠΈΠΌ ELK ΠΈ Exchange. Π§Π°ΡΡ‚ΡŒ 2

Π― ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°ΡŽ свой рассказ ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ ΠΏΠΎΠ΄Ρ€ΡƒΠΆΠΈΡ‚ΡŒ Exchange ΠΈ ELK (Π½Π°Ρ‡Π°Π»ΠΎ Ρ‚ΡƒΡ‚). Напомню, Ρ‡Ρ‚ΠΎ эта комбинация способна Π±Π΅Π· ΠΊΠΎΠ»Π΅Π±Π°Π½ΠΈΠΉ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ ΠΎΡ‡Π΅Π½ΡŒ большоС количСство Π»ΠΎΠ³ΠΎΠ². На это Ρ€Π°Π· ΠΌΡ‹ ΠΏΠΎΠ³ΠΎΠ²ΠΎΡ€ΠΈΠΌ ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ Π½Π°Π»Π°Π΄ΠΈΡ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ Exchange с ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°ΠΌΠΈ Logstash ΠΈ Kibana.

Logstash Π² стСкС ELK ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π»ΠΎΠ³ΠΎΠ² ΠΈ ΠΈΡ… ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠΈ ΠΊ Ρ€Π°Π·ΠΌΠ΅Ρ‰Π΅Π½ΠΈΡŽ Π² Elastic Π² Π²ΠΈΠ΄Π΅ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ², Π½Π° основС ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΡƒΠ΄ΠΎΠ±Π½ΠΎ ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ Π²ΠΈΠ·ΡƒΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π² Kibana.

Установка

Бостоит ΠΈΠ· Π΄Π²ΡƒΡ… этапов:

  • Установка ΠΈ настройка ΠΏΠ°ΠΊΠ΅Ρ‚Π° OpenJDK.
  • Установка ΠΈ настройка ΠΏΠ°ΠΊΠ΅Ρ‚Π° Logstash.

Установка ΠΈ настройка ΠΏΠ°ΠΊΠ΅Ρ‚Π° OpenJDK

ΠŸΠ°ΠΊΠ΅Ρ‚ OpenJDK Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡΠΊΠ°Ρ‡Π°Ρ‚ΡŒ ΠΈ Ρ€Π°ΡΠΏΠ°ΠΊΠΎΠ²Π°Ρ‚ΡŒ Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½Π½ΡƒΡŽ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΡŽ. Π—Π°Ρ‚Π΅ΠΌ ΠΏΡƒΡ‚ΡŒ Π΄ΠΎ этой Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ внСсти Π² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ $env:Path ΠΈ $env:JAVA_HOME ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠΉ систСмы Windows:

Π”Ρ€ΡƒΠΆΠΈΠΌ ELK ΠΈ Exchange. Π§Π°ΡΡ‚ΡŒ 2

Π”Ρ€ΡƒΠΆΠΈΠΌ ELK ΠΈ Exchange. Π§Π°ΡΡ‚ΡŒ 2

ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΈΠΌ Π²Π΅Ρ€ΡΠΈΡŽ Java:

PS C:> java -version
openjdk version "13.0.1" 2019-10-15
OpenJDK Runtime Environment (build 13.0.1+9)
OpenJDK 64-Bit Server VM (build 13.0.1+9, mixed mode, sharing)

Установка ΠΈ настройка ΠΏΠ°ΠΊΠ΅Ρ‚Π° Logstash

Π€Π°ΠΉΠ»-Π°Ρ€Ρ…ΠΈΠ² с дистрибутивом Logstash скачайтС ΠΎΡ‚ΡΡŽΠ΄Π°. Архив Π½ΡƒΠΆΠ½ΠΎ Ρ€Π°ΡΠΏΠ°ΠΊΠΎΠ²Π°Ρ‚ΡŒ Π² ΠΊΠΎΡ€Π΅Π½ΡŒ диска. Π Π°ΡΠΏΠ°ΠΊΠΎΠ²Ρ‹Π²Π°Ρ‚ΡŒ Π² ΠΏΠ°ΠΏΠΊΡƒ C:Program Files Π½Π΅ стоит, Logstash откаТСтся Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ Π·Π°ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒΡΡ. Π—Π°Ρ‚Π΅ΠΌ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ внСсти Π² Ρ„Π°ΠΉΠ» jvm.options ΠΏΡ€Π°Π²ΠΊΠΈ, ΠΎΡ‚Π²Π΅Ρ‡Π°ΡŽΡ‰ΠΈΠ΅ Π·Π° Π²Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½ΠΎΠΉ памяти для процСсса Java. Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΡŽ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ ΠΏΠΎΠ»ΠΎΠ²ΠΈΠ½Ρƒ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½ΠΎΠΉ памяти сСрвСра. Если Ρƒ Π½Π΅Π³ΠΎ Π½Π° Π±ΠΎΡ€Ρ‚Ρƒ 16 Π“Π± ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²ΠΊΠΈ, Ρ‚ΠΎ ΠΊΠ»ΡŽΡ‡ΠΈ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ:

-Xms1g
-Xmx1g

Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π½Π°:

-Xms8g
-Xmx8g

ΠšΡ€ΠΎΠΌΠ΅ этого, цСлСсообразно Π·Π°ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ строку -XX:+UseConcMarkSweepGC. ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ ΠΎΠ± этом Ρ‚ΡƒΡ‚. Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ шаг β€” созданиС ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π² Ρ„Π°ΠΉΠ»Π΅ logstash.conf:

input {
 stdin{}
}
 
filter {
}
 
output {
 stdout {
 codec => "rubydebug"
 }
}

ΠŸΡ€ΠΈ использовании этой ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ Logstash считываСт Π΄Π°Π½Π½Ρ‹Π΅ ΠΈΠ· консоли, пропускаСт Ρ‡Π΅Ρ€Π΅Π· пустой Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ ΠΈ Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ Π² консоль. ΠŸΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ этой ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚ΠΎΡΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡ‚ΡŒ Logstash. Для этого запустим Π΅Π³ΠΎ Π² ΠΈΠ½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΠΌ Ρ€Π΅ΠΆΠΈΠΌΠ΅:

PS C:...bin> .logstash.bat -f .logstash.conf
...
[2019-12-19T11:15:27,769][INFO ][logstash.javapipeline    ][main] Pipeline started {"pipeline.id"=>"main"}
The stdin plugin is now waiting for input:
[2019-12-19T11:15:27,847][INFO ][logstash.agent           ] Pipelines running {:count=>1, :running_pipelines=>[:main], :non_running_pipelines=>[]}
[2019-12-19T11:15:28,113][INFO ][logstash.agent           ] Successfully started Logstash API endpoint {:port=>9600}

Logstash ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ запустился Π½Π° ΠΏΠΎΡ€Ρ‚Ρƒ 9600.

Π€ΠΈΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ шаг установки: запуск Logstash Π² Π²ΠΈΠ΄Π΅ сСрвиса Windows. Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΏΠ°ΠΊΠ΅Ρ‚Π° NSSM:

PS C:...bin> .nssm.exe install logstash
Service "logstash" installed successfully!

ΠžΡ‚ΠΊΠ°Π·ΠΎΡƒΡΡ‚ΠΎΠΉΡ‡ΠΈΠ²ΠΎΡΡ‚ΡŒ

Π‘ΠΎΡ…Ρ€Π°Π½Π½ΠΎΡΡ‚ΡŒ Π»ΠΎΠ³ΠΎΠ² ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π΅ с исходного сСрвСра обСспСчиваСтся ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠΎΠΌ Persistent Queues.

Как Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚

Π‘Ρ…Π΅ΠΌΠ° располоТСния ΠΎΡ‡Π΅Ρ€Π΅Π΄Π΅ΠΉ Π² процСссС ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π»ΠΎΠ³ΠΎΠ²: input β†’ queue β†’ filter + output.

Плагин input ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ Π΄Π°Π½Π½Ρ‹Π΅ ΠΎΡ‚ источника Π»ΠΎΠ³ΠΎΠ², записываСт ΠΈΡ… Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ ΠΈ отправляСт источнику ΠΏΠΎΠ΄Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π΅Π½ΠΈΠ΅ получСния Π΄Π°Π½Π½Ρ‹Ρ….

БообщСния ΠΈΠ· ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ΡΡ Logstash, проходят Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ ΠΈ ΠΏΠ»Π°Π³ΠΈΠ½ output. ΠŸΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ ΠΎΡ‚ output подтвСрТдСния ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ Π»ΠΎΠ³Π° Logstash удаляСт ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Π½Π½Ρ‹ΠΉ Π»ΠΎΠ³ ΠΈΠ· ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ. Если Logstash останавливаСтся, Ρ‚ΠΎ всС Π½Π΅ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Π½Π½Ρ‹Π΅ сообщСния ΠΈ сообщСния, ΠΏΠΎ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ Π½Π΅ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΎ ΠΏΠΎΠ΄Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π΅Π½ΠΈΠ΅ ΠΎΠ± ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ΅, ΠΎΡΡ‚Π°ΡŽΡ‚ΡΡ Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ, ΠΈ Logstash ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚ ΠΈΡ… ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ ΠΏΡ€ΠΈ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ запускС.

Настройка

РСгулируСтся ΠΊΠ»ΡŽΡ‡Π°ΠΌΠΈ Π² Ρ„Π°ΠΉΠ»Π΅ C:Logstashconfiglogstash.yml:

  • queue.type: (Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ значСния β€” persisted ΠΈ memory (default)).
  • path.queue: (ΠΏΡƒΡ‚ΡŒ Π΄ΠΎ ΠΏΠ°ΠΏΠΊΠΈ с Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ ΠΎΡ‡Π΅Ρ€Π΅Π΄Π΅ΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ хранятся Π² C:Logstashqueue).
  • queue.page_capacity: (ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€ страницы ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ, Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ β€” 64mb).
  • queue.drain: (true/false β€” Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚/Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ остановку ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ ΠΏΠ΅Ρ€Π΅Π΄ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ Logstash. НС Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΡŽ Π²ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒ, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ это прямо скаТСтся Π½Π° скорости Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ сСрвСра).
  • queue.max_events: (максимально число событий Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ, ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ β€” 0 (Π½Π΅ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΎ)).
  • queue.max_bytes: (ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ Π² Π±Π°ΠΉΡ‚Π°Ρ…, ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ β€” 1024mb (1gb)).

Если настроСны queue.max_events ΠΈ queue.max_bytes, Ρ‚ΠΎ сообщСния ΠΏΠ΅Ρ€Π΅ΡΡ‚Π°ΡŽΡ‚ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒΡΡ Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ ΠΏΡ€ΠΈ достиТСнии значСния любой ΠΈΠ· этих настроСк. ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ ΠΏΡ€ΠΎ Persistent Queues рассказано Ρ‚ΡƒΡ‚.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ части logstash.yml, ΠΎΡ‚Π²Π΅Ρ‡Π°ΡŽΡ‰Π΅ΠΉ Π·Π° настройку ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ:

queue.type: persisted
queue.max_bytes: 10gb

Настройка

ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ Logstash ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ состоит ΠΈΠ· Ρ‚Ρ€Ρ‘Ρ… частСй, ΠΎΡ‚Π²Π΅Ρ‡Π°ΡŽΡ‰ΠΈΡ… Π·Π° Ρ€Π°Π·Π½Ρ‹Π΅ Ρ„Π°Π·Ρ‹ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ входящий Π»ΠΎΠ³ΠΎΠ²: ΠΏΡ€ΠΈΡ‘ΠΌ (сСкция input), парсинг (сСкция filter) ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ° Π² Elastic (сСкция output). НиТС ΠΌΡ‹ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ рассмотрим ΠΊΠ°ΠΆΠ΄ΡƒΡŽ ΠΈΠ· Π½ΠΈΡ….

Input

Входящий ΠΏΠΎΡ‚ΠΎΠΊ с сырыми Π»ΠΎΠ³Π°ΠΌΠΈ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅ΠΌ ΠΎΡ‚ Π°Π³Π΅Π½Ρ‚ΠΎΠ² filebeat. ИмСнно этот ΠΏΠ»Π°Π³ΠΈΠ½ ΠΌΡ‹ ΠΈ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ Π² сСкции input:

input {
  beats {
    port => 5044
  }
}

ПослС Ρ‚Π°ΠΊΠΎΠΉ настройки Logstash Π½Π°Ρ‡ΠΈΠ½Π°Π΅Ρ‚ ΠΏΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Ρ‚ΡŒ ΠΏΠΎΡ€Ρ‚ 5044, ΠΈ ΠΏΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ Π»ΠΎΠ³ΠΎΠ² ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ ΠΈΡ… согласно настройкам сСкции filter. ΠŸΡ€ΠΈ нСобходимости ΠΌΠΎΠΆΠ½ΠΎ ΠΊΠ°Π½Π°Π» получСния Π»ΠΎΠ³ΠΎΠ² ΠΎΡ‚ filebit Π·Π°Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ Π² SSL. ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ ΠΎ настройках ΠΏΠ»Π°Π³ΠΈΠ½Π° beats написано Ρ‚ΡƒΡ‚.

Filter

ВсС интСрСсныС для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ тСкстовыС Π»ΠΎΠ³ΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ Exchange, ΠΈΠΌΠ΅ΡŽΡ‚ csv-Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ с описанными Π² самом Ρ„Π°ΠΉΠ»Π΅ Π»ΠΎΠ³ΠΎΠ² полями. Для парсинга csv-записСй Logstash ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π΅Ρ‚ Π½Π°ΠΌ Ρ‚Ρ€ΠΈ ΠΏΠ»Π°Π³ΠΈΠ½Π°: dissect, csv ΠΈ grok. ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ β€” самый быстрый, Π½ΠΎ справляСтся с парсингом Ρ‚ΠΎΠ»ΡŒΠΊΠΎ самых простых Π»ΠΎΠ³ΠΎΠ².
НапримСр, ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ запись ΠΎΠ½ Ρ€Π°Π·ΠΎΠ±ΡŒΡ‘Ρ‚ Π½Π° Π΄Π²Π΅ (ΠΈΠ·-Π·Π° наличия Π²Π½ΡƒΡ‚Ρ€ΠΈ поля запятой), ΠΈΠ·-Π·Π° Ρ‡Π΅Π³ΠΎ Π»ΠΎΠ³ Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π·ΠΎΠ±Ρ€Π°Π½ Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ:

…,"MDB:GUID1, Mailbox:GUID2, Event:526545791, MessageClass:IPM.Note, CreationTime:2020-05-15T12:01:56.457Z, ClientType:MOMT, SubmissionAssistant:MailboxTransportSubmissionEmailAssistant",…

Π•Π³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΈ парсингС Π»ΠΎΠ³ΠΎΠ², Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, IIS. Π’ этом случаС сСкция filter ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

filter {
  if "IIS" in [tags] {
    dissect {
      mapping => {
        "message" => "%{date} %{time} %{s-ip} %{cs-method} %{cs-uri-stem} %{cs-uri-query} %{s-port} %{cs-username} %{c-ip} %{cs(User-Agent)} %{cs(Referer)} %{sc-status} %{sc-substatus} %{sc-win32-status} %{time-taken}"
      }
      remove_field => ["message"]
      add_field => { "application" => "exchange" }
    }
  }
} 

ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ Logstash позволяСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ условныС ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹, поэтому ΠΌΡ‹ Π² ΠΏΠ»Π°Π³ΠΈΠ½ dissect ΠΌΠΎΠΆΠ΅ΠΌ Π½Π°ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π»ΠΎΠ³ΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±Ρ‹Π»ΠΈ ΠΏΠΎΠΌΠ΅Ρ‡Π΅Π½Ρ‹ filebeat тэгом IIS. Π’Π½ΡƒΡ‚Ρ€ΠΈ ΠΏΠ»Π°Π³ΠΈΠ½Π° ΠΌΡ‹ сопоставляСм значСния ΠΏΠΎΠ»Π΅ΠΉ с ΠΈΡ… названиями, удаляСм исходноС ΠΏΠΎΠ»Π΅ message, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ содСрТало запись ΠΈΠ· Π»ΠΎΠ³Π°, ΠΈ ΠΌΠΎΠΆΠ΅ΠΌ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½ΠΎΠ΅ ΠΏΠΎΠ»Π΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π±ΡƒΠ΄Π΅Ρ‚, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ имя прилоТСния ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΌΡ‹ собираСм Π»ΠΎΠ³ΠΈ.

Π’ случаС с Π»ΠΎΠ³Π°ΠΌΠΈ трэкинга Π»ΡƒΡ‡ΡˆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠ»Π°Π³ΠΈΠ½ csv, ΠΎΠ½ ΡƒΠΌΠ΅Π΅Ρ‚ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ слоТныС поля:

filter {
  if "Tracking" in [tags] {
    csv {
      columns => ["date-time","client-ip","client-hostname","server-ip","server-hostname","source-context","connector-id","source","event-id","internal-message-id","message-id","network-message-id","recipient-address","recipient-status","total-bytes","recipient-count","related-recipient-address","reference","message-subject","sender-address","return-path","message-info","directionality","tenant-id","original-client-ip","original-server-ip","custom-data","transport-traffic-type","log-id","schema-version"]
      remove_field => ["message", "tenant-id", "schema-version"]
      add_field => { "application" => "exchange" }
    }
}

Π’Π½ΡƒΡ‚Ρ€ΠΈ ΠΏΠ»Π°Π³ΠΈΠ½Π° ΠΌΡ‹ сопоставляСм значСния ΠΏΠΎΠ»Π΅ΠΉ с ΠΈΡ… названиями, удаляСм исходноС ΠΏΠΎΠ»Π΅ message (Π° Ρ‚Π°ΠΊΠΆΠ΅ поля tenant-id ΠΈ schema-version), ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ содСрТало запись ΠΈΠ· Π»ΠΎΠ³Π°, ΠΈ ΠΌΠΎΠΆΠ΅ΠΌ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½ΠΎΠ΅ ΠΏΠΎΠ»Π΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π±ΡƒΠ΄Π΅Ρ‚, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ имя прилоТСния ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΌΡ‹ собираСм Π»ΠΎΠ³ΠΈ.

На Π²Ρ‹Ρ…ΠΎΠ΄Π΅ ΠΈΠ· стадии Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π°Ρ†ΠΈΠΈ ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Ρ‹ Π² ΠΏΠ΅Ρ€Π²ΠΎΠΌ ΠΏΡ€ΠΈΠ±Π»ΠΈΠΆΠ΅Π½ΠΈΠΈ Π³ΠΎΡ‚ΠΎΠ²Ρ‹Π΅ ΠΊ Π²ΠΈΠ·ΡƒΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π² Kibana. НС Ρ…Π²Π°Ρ‚Π°Ρ‚ΡŒ Π½Π°ΠΌ Π±ΡƒΠ΄Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ:

  • ЧисловыС поля Π±ΡƒΠ΄ΡƒΡ‚ распознаны ΠΊΠ°ΠΊ тСкст, Ρ‡Ρ‚ΠΎ Π½Π΅ позволяСт Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ с Π½ΠΈΠΌΠΈ. А ΠΈΠΌΠ΅Π½Π½ΠΎ, поля time-taken Π»ΠΎΠ³Π° IIS, Π° Ρ‚Π°ΠΊΠΆΠ΅ поля recipient-count ΠΈ total-bites Π»ΠΎΠ³Π° Tracking.
  • Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚Π½Ρ‹ΠΉ Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΡˆΡ‚Π°ΠΌΠΏ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π° Π±ΡƒΠ΄Π΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ врСмя ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π»ΠΎΠ³Π°, Π° Π½Π΅ врСмя записи Π΅Π³ΠΎ Π½Π° сторонС сСрвСра.
  • ПолС recipient-address Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ ΠΎΠ΄Π½ΠΎΠΉ стройкой, Ρ‡Ρ‚ΠΎ Π½Π΅ позволяСт ΠΏΡ€ΠΎΠ²ΠΎΠ΄ΠΈΡ‚ΡŒ Π°Π½Π°Π»ΠΈΠ· с подсчётом ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚Π΅Π»Π΅ΠΉ писСм.

Настало врСмя Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΠΌΠ°Π³ΠΈΠΈ Π² процСсс ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π»ΠΎΠ³ΠΎΠ².

ΠšΠΎΠ½Π²Π΅Ρ€Ρ‚Π°Ρ†ΠΈΡ числовых ΠΏΠΎΠ»Π΅ΠΉ

Плагин dissect ΠΈΠΌΠ΅Π΅Ρ‚ ΠΎΠΏΡ†ΠΈΡŽ convert_datatype, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для ΠΊΠΎΠ½Π²Π΅Ρ€Ρ‚Π°Ρ†ΠΈΠΈ тСкстового поля Π² Ρ†ΠΈΡ„Ρ€ΠΎΠ²ΠΎΠΉ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚. НапримСр, Ρ‚Π°ΠΊ:

dissect {
  …
  convert_datatype => { "time-taken" => "int" }
  …
}

Π‘Ρ‚ΠΎΠΈΡ‚ ΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ этот ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² Ρ‚ΠΎΠΌ случаС, Ссли ΠΏΠΎΠ»Π΅ Ρ‚ΠΎΡ‡Π½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ строку. Null-значСния ΠΈΠ· ΠΏΠΎΠ»Π΅ΠΉ опция Π½Π΅ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ ΠΈ вываливаСтся Π² ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅.

Для Π»ΠΎΠ³ΠΎΠ² трэкинга Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ convert Π»ΡƒΡ‡ΡˆΠ΅ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ поля recipient-count ΠΈ total-bites ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ пустыми. Для ΠΊΠΎΠ½Π²Π΅Ρ€Ρ‚Π°Ρ†ΠΈΠΈ этих ΠΏΠΎΠ»Π΅ΠΉ Π»ΡƒΡ‡ΡˆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠ»Π°Π³ΠΈΠ½ mutate:

mutate {
  convert => [ "total-bytes", "integer" ]
  convert => [ "recipient-count", "integer" ]
}

Π Π°Π·Π±ΠΈΠ΅Π½ΠΈΠ΅ recipient_address Π½Π° ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚Π΅Π»Π΅ΠΉ

Π­Ρ‚Ρƒ Π·Π°Π΄Π°Ρ‡Ρƒ ΠΌΠΎΠΆΠ½ΠΎ Ρ‚Π°ΠΊΠΆΠ΅ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΏΠ»Π°Π³ΠΈΠ½Π° mutate:

mutate {
  split => ["recipient_address", ";"]
}

ИзмСняСм timestamp

Π’ случаС с Π»ΠΎΠ³Π°ΠΌΠΈ трэкинга Π·Π°Π΄Π°Ρ‡Π° ΠΎΡ‡Π΅Π½ΡŒ просто Ρ€Π΅ΡˆΠ°Π΅Ρ‚ΡΡ ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠΌ date, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΎΠΏΠΈΡΠ°Ρ‚ΡŒ Π² ΠΏΠΎΠ»Π΅ timestamp Π΄Π°Ρ‚Ρƒ ΠΈ врСмя Π² Π½ΡƒΠΆΠ½ΠΎΠΌ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ ΠΈΠ· поля date-time:

date {
  match => [ "date-time", "ISO8601" ]
  timezone => "Europe/Moscow"
  remove_field => [ "date-time" ]
}

Π’ случаС с Π»ΠΎΠ³Π°ΠΌΠΈ IIS Π½Π°ΠΌ Π±ΡƒΠ΄Π΅Ρ‚ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎΠ»Π΅ΠΉ date ΠΈ time с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΏΠ»Π°Π³ΠΈΠ½Π° mutate, ΠΏΡ€ΠΎΠΏΠΈΡΠ°Ρ‚ΡŒ Π½ΡƒΠΆΠ½ΡƒΡŽ Π½Π°ΠΌ Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ Π·ΠΎΠ½Ρƒ ΠΈ ΠΏΠΎΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ этот Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΡˆΡ‚Π°ΠΌΠΏ Π² timestamp с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΏΠ»Π°Π³ΠΈΠ½Π° date:

mutate { 
  add_field => { "data-time" => "%{date} %{time}" }
  remove_field => [ "date", "time" ]
}
date { 
  match => [ "data-time", "YYYY-MM-dd HH:mm:ss" ]
  timezone => "UTC"
  remove_field => [ "data-time" ]
}

Output

БСкция output ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Π½Π½Ρ‹Ρ… Π»ΠΎΠ³ΠΎΠ² Π² ΠΏΡ€ΠΈΡ‘ΠΌΠ½ΠΈΠΊ Π»ΠΎΠ³ΠΎΠ². Π’ случаС ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ Π² Elastic ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΏΠ»Π°Π³ΠΈΠ½ elasticsearch, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ указываСтся адрСс сСрвСра ΠΈ шаблон ΠΈΠΌΠ΅Π½ΠΈ индСкса для ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ сформированного Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°:

output {
  elasticsearch {
    hosts => ["127.0.0.1:9200", "127.0.0.2:9200"]
    manage_template => false
    index => "Exchange-%{+YYYY.MM.dd}"
  }
}

Π˜Ρ‚ΠΎΠ³ΠΎΠ²Π°Ρ конфигурация

Π˜Ρ‚ΠΎΠ³ΠΎΠ²Π°Ρ конфигурация Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

input {
  beats {
    port => 5044
  }
}
 
filter {
  if "IIS" in [tags] {
    dissect {
      mapping => {
        "message" => "%{date} %{time} %{s-ip} %{cs-method} %{cs-uri-stem} %{cs-uri-query} %{s-port} %{cs-username} %{c-ip} %{cs(User-Agent)} %{cs(Referer)} %{sc-status} %{sc-substatus} %{sc-win32-status} %{time-taken}"
      }
      remove_field => ["message"]
      add_field => { "application" => "exchange" }
      convert_datatype => { "time-taken" => "int" }
    }
    mutate { 
      add_field => { "data-time" => "%{date} %{time}" }
      remove_field => [ "date", "time" ]
    }
    date { 
      match => [ "data-time", "YYYY-MM-dd HH:mm:ss" ]
      timezone => "UTC"
      remove_field => [ "data-time" ]
    }
  }
  if "Tracking" in [tags] {
    csv {
      columns => ["date-time","client-ip","client-hostname","server-ip","server-hostname","source-context","connector-id","source","event-id","internal-message-id","message-id","network-message-id","recipient-address","recipient-status","total-bytes","recipient-count","related-recipient-address","reference","message-subject","sender-address","return-path","message-info","directionality","tenant-id","original-client-ip","original-server-ip","custom-data","transport-traffic-type","log-id","schema-version"]
      remove_field => ["message", "tenant-id", "schema-version"]
      add_field => { "application" => "exchange" }
    }
    mutate {
      convert => [ "total-bytes", "integer" ]
      convert => [ "recipient-count", "integer" ]
      split => ["recipient_address", ";"]
    }
    date {
      match => [ "date-time", "ISO8601" ]
      timezone => "Europe/Moscow"
      remove_field => [ "date-time" ]
    }
  }
}
 
output {
  elasticsearch {
    hosts => ["127.0.0.1:9200", "127.0.0.2:9200"]
    manage_template => false
    index => "Exchange-%{+YYYY.MM.dd}"
  }
}

ΠŸΠΎΠ»Π΅Π·Π½Ρ‹Π΅ ссылки:

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com