Aféierung
Beim Ofbau vun engem anere System ware mir konfrontéiert mat der Bedierfnes fir eng grouss Zuel vu verschiddene Logbicher ze veraarbecht. ELK gouf als Tool gewielt. Dësen Artikel wäert eis Erfarung diskutéieren beim Ariichten vun dësem Stack.
Mir setzen net en Zil fir all seng Fäegkeeten ze beschreiwen, mä mir wëllen eis speziell op d'Léisung vu praktesche Problemer konzentréieren. Dëst ass wéinst der Tatsaach, datt och wann et eng zimlech grouss Quantitéit vun Dokumentatioun a prett-feieren Biller ass, sinn et relativ vill Fallen, op d'mannst hu mir se fonnt.
Mir hunn de Stack iwwer Docker-compose ofgesat. Ausserdeem hate mir eng gutt geschriwwen docker-compose.yml, déi eis erlaabt de Stack bal ouni Problemer ze erhéijen. An et huet eis geschéngt datt d'Victoire scho no wier, elo wäerte mir et e bëssen upassen fir eise Besoinen ze passen an dat ass et.
Leider war de Versuch de System ze konfiguréieren fir Logbicher vun eiser Applikatioun ze kréien an ze veraarbechten net direkt erfollegräich. Dofir hu mir décidéiert datt et derwäert wier all Komponent separat ze studéieren, an dann zréck op hir Verbindungen.
Also hu mir ugefaang mat Logstash.
Ëmfeld, Deployment, Lafen Logstash an engem Container
Fir Deployment benotze mir Docker-compose; d'Experimenter, déi hei beschriwwe ginn, goufen op MacOS an Ubuntu 18.0.4 duerchgefouert.
D'Logstash-Bild dat an eisem Original docker-compose.yml registréiert gouf ass docker.elastic.co/logstash/logstash:6.3.2
Mir wäerten et fir Experimenter benotzen.
Mir hunn eng separat docker-compose.yml geschriwwen fir Logstash ze lafen. Natierlech war et méiglech d'Bild vun der Kommandozeil ze lancéieren, awer mir hunn e spezifesche Problem geléist, wou mir alles aus Docker-compose lafen.
Kuerz iwwer Configuratiounsdateien
Wéi aus der Beschreiwung follegt, kann Logstash entweder fir ee Kanal lafen, an deem Fall muss et d'*.conf Datei passéieren, oder fir verschidde Kanäl, an deem Fall muss et d'Pipelines.yml Datei passéieren, déi am Tour , wäert op d'Fichier'en .conf fir all Kanal verbannen.
Mir hunn den zweete Wee gemaach. Et schéngt eis méi universell a skalierbar ze sinn. Dofir hu mir pipelines.yml erstallt, an e Pipelines-Verzeichnis gemaach, an deem mir .conf-Dateien fir all Kanal setzen.
Am Container gëtt et eng aner Konfiguratiounsdatei - logstash.yml. Mir beréieren et net, mir benotzen et wéi et ass.
Also, eis Verzeechnesstruktur:
Fir Inputdaten ze kréien, gi mir elo un datt dëst tcp um Hafen 5046 ass, a fir Output benotze mir stdout.
Hei ass eng einfach Konfiguratioun fir den éischte Start. Well déi éischt Aufgab ass ze starten.
Also, mir hunn dës docker-compose.yml
version: '3'
networks:
elk:
volumes:
elasticsearch:
driver: local
services:
logstash:
container_name: logstash_one_channel
image: docker.elastic.co/logstash/logstash:6.3.2
networks:
- elk
ports:
- 5046:5046
volumes:
- ./config/pipelines.yml:/usr/share/logstash/config/pipelines.yml:ro
- ./config/pipelines:/usr/share/logstash/config/pipelines:ro
Wat gesi mer hei?
- Netzwierker a Bänn goufen aus dem Original docker-compose.yml geholl (deen wou de ganze Stack lancéiert gëtt) an ech mengen datt se d'Gesamtbild hei net vill beaflossen.
- Mir kreéieren ee Logstash Service (en) vum docker.elastic.co/logstash/logstash:6.3.2 Bild an nennen et logstash_one_channel.
- Mir weider port 5046 am Container, op déi selwecht intern port.
- Mir mapen eis Päifkonfiguratiounsdatei ./config/pipelines.yml op d'Datei /usr/share/logstash/config/pipelines.yml am Container, wou de Logstash et ophëlt an et nëmme liesen, just am Fall.
- Mir mapen den ./config/pipelines Verzeichnis, wou mir Dateien mat Kanalastellungen hunn, an den /usr/share/logstash/config/pipelines Verzeichnis a maachen et och nëmme liesen.
Pipelines.yml Datei
- pipeline.id: HABR
pipeline.workers: 1
pipeline.batch.size: 1
path.config: "./config/pipelines/habr_pipeline.conf"
Ee Kanal mat dem HABR Identifizéierer an de Wee zu senger Konfiguratiounsdatei ginn hei beschriwwen.
A schliisslech d'Datei "./config/pipelines/habr_pipeline.conf"
input {
tcp {
port => "5046"
}
}
filter {
mutate {
add_field => [ "habra_field", "Hello Habr" ]
}
}
output {
stdout {
}
}
Loosst eis elo net op seng Beschreiwung goen, loosst eis probéieren et auszeféieren:
docker-compose up
Wat gesi mir?
De Container huet ugefaang. Mir kënnen hir Operatioun kontrolléieren:
echo '13123123123123123123123213123213' | nc localhost 5046
A mir gesinn d'Äntwert an der Containerkonsole:
Awer gläichzäiteg gesi mir och:
logstash_one_channel | [2019-04-29T11:28:59,790][ERROR][logstash.licensechecker.licensereader] Kann net Lizenzinformatioun vum Lizenzserver recuperéieren {:message=>“Elasticsearch Unreachable: [http://elasticsearch:9200/][Manticore ::ResolutionFailure] elasticsearch", ...
logstash_one_channel | [2019-04-29T11:28:59,894][INFO ][logstash.pipeline ] Pipeline huet erfollegräich ugefaang {:pipeline_id=>".monitoring-logstash", :thread=>"# "}
logstash_one_channel | [2019-04-29T11:28:59,988][INFO ][logstash.agent ] Pipelines lafen {:count=>2, :running_pipelines=>[:HABR, :".monitoring-logstash"], :non_running_pipelines=>[ ]}
logstash_one_channel | [2019-04-29T11:29:00,015][ERROR][logstash.inputs.metrics] X-Pack ass op Logstash installéiert awer net op Elasticsearch. Installéiert w.e.g. X-Pack op Elasticsearch fir d'Iwwerwaachungsfunktioun ze benotzen. Aner Funktiounen kënne verfügbar sinn.
logstash_one_channel | [2019-04-29T11:29:00,526][INFO ][logstash.agent ] Logstash API Endpunkt gestart {:port=>9600}
logstash_one_channel | [2019-04-29T11:29:04,478][INFO ][logstash.outputs.elasticsearch] Lafen Gesondheetscheck fir ze kucken ob eng Elasticsearch Verbindung funktionnéiert {:healthcheck_url=>http://elasticsearch:9200/, :path=> "/"}
logstash_one_channel | [2019-04-29T11:29:04,487][WARN ][logstash.outputs.elasticsearch] Versicht d'Verbindung op dout ES Instanz erëmbeliewen, awer krut e Feeler. {:url=>“
logstash_one_channel | [2019-04-29T11:29:04,704][INFO ][logstash.licensechecker.licensereader] Lafen Gesondheetscheck fir ze kucken ob eng Elasticsearch Verbindung funktionnéiert {:healthcheck_url=>http://elasticsearch:9200/, :path=> "/"}
logstash_one_channel | [2019-04-29T11:29:04,710][WARN ][logstash.licensechecker.licensereader] Versicht d'Verbindung op dout ES Instanz erëmbeliewen, awer krut e Feeler. {:url=>“
An eise Logbicher kräischen déi ganzen Zäit.
Hei hunn ech a gréng de Message markéiert datt d'Pipeline erfollegräich lancéiert ass, a rout d'Fehlermeldung a giel de Message iwwer e Versuch ze kontaktéieren
Dëst geschitt well logstash.conf, am Bild abegraff, e Scheck fir elasticsearch Disponibilitéit enthält. No all, iwwerhëlt logstash datt et als Deel vun der Elk Stack Wierker, mä mir getrennt et.
Et ass méiglech ze schaffen, awer et ass net bequem.
D'Léisung ass dës Scheck iwwer d'XPACK_MONITORING_ENABLED Ëmfeldvariabel auszeschalten.
Loosst eis eng Ännerung op docker-compose.yml maachen a lafen et nach eng Kéier:
version: '3'
networks:
elk:
volumes:
elasticsearch:
driver: local
services:
logstash:
container_name: logstash_one_channel
image: docker.elastic.co/logstash/logstash:6.3.2
networks:
- elk
environment:
XPACK_MONITORING_ENABLED: "false"
ports:
- 5046:5046
volumes:
- ./config/pipelines.yml:/usr/share/logstash/config/pipelines.yml:ro
- ./config/pipelines:/usr/share/logstash/config/pipelines:ro
Elo ass alles gutt. De Container ass prett fir Experimenter.
Mir kënnen erëm an der nächster Konsole tippen:
echo '13123123123123123123123213123213' | nc localhost 5046
A kuckt:
logstash_one_channel | {
logstash_one_channel | "message" => "13123123123123123123123213123213",
logstash_one_channel | "@timestamp" => 2019-04-29T11:43:44.582Z,
logstash_one_channel | "@version" => "1",
logstash_one_channel | "habra_field" => "Hello Habr",
logstash_one_channel | "host" => "gateway",
logstash_one_channel | "port" => 49418
logstash_one_channel | }
Schafft an engem Kanal
Also hu mir lancéiert. Elo kënnt Dir d'Zäit huelen fir de Logstash selwer ze konfiguréieren. Loosst eis de Pipelines.yml Fichier fir elo net beréieren, kucke wat mir kënne kréien andeems Dir mat engem Kanal schafft.
Ech muss soen datt den allgemenge Prinzip fir mat der Kanalkonfiguratiounsdatei ze schaffen ass gutt an der offizieller Handbuch beschriwwen, hei
Wann Dir op Russesch wëllt liesen, hu mir dëst benotzt
Loosst eis sequenziell vun der Input Sektioun goen. Mir hu schonn Aarbecht op tcp gesinn. Wat kéint hei nach interessant sinn?
Test Messagen mat Häerzschlag
Et gëtt sou eng interessant Geleeënheet fir automatesch Testmeldungen ze generéieren.
Fir dëst ze maachen, musst Dir den Heartbean Plugin an der Input Sektioun aktivéieren.
input {
heartbeat {
message => "HeartBeat!"
}
}
Maacht et un, fänkt un eemol pro Minutt ze kréien
logstash_one_channel | {
logstash_one_channel | "@timestamp" => 2019-04-29T13:52:04.567Z,
logstash_one_channel | "habra_field" => "Hello Habr",
logstash_one_channel | "message" => "HeartBeat!",
logstash_one_channel | "@version" => "1",
logstash_one_channel | "host" => "a0667e5c57ec"
logstash_one_channel | }
Wa mir méi dacks wëlle kréien, musse mir den Intervallparameter derbäisetzen.
Dëst ass wéi mir all 10 Sekonnen e Message kréien.
input {
heartbeat {
message => "HeartBeat!"
interval => 10
}
}
Recuperéieren Daten aus enger Datei
Mir hunn och decidéiert de Dateimodus ze kucken. Wann et gutt mat der Datei funktionnéiert, da gëtt vläicht keen Agent gebraucht, gutt, op d'mannst fir lokal Benotzung.
Laut der Beschreiwung soll de Betribsmodus ähnlech wéi Schwanz -f sinn, d.h. liest nei Zeilen oder, als Optioun, liest de ganze Fichier.
Also wat mir wëllen kréien:
- Mir wëllen Zeilen kréien, déi un eng Logdatei bäigefüügt ginn.
- Mir wëllen Daten kréien, déi op e puer Logdateien geschriwwe sinn, wärend mir fäeg sinn ze trennen wat vu wou kritt gëtt.
- Mir wëllen sécherstellen datt wann de Logstash nei gestart gëtt, et dës Donnéeën net erëm kritt.
- Mir wëllen iwwerpréiwen datt wann de Logstash ausgeschalt ass, an d'Daten weider op Dateien geschriwwe ginn, da wa mir se lafen, kréien mir dës Donnéeën.
Fir den Experiment ze maachen, loosst eis eng aner Zeil op docker-compose.yml derbäisetzen, de Verzeichnis opmaachen an deem mir d'Dateien setzen.
version: '3'
networks:
elk:
volumes:
elasticsearch:
driver: local
services:
logstash:
container_name: logstash_one_channel
image: docker.elastic.co/logstash/logstash:6.3.2
networks:
- elk
environment:
XPACK_MONITORING_ENABLED: "false"
ports:
- 5046:5046
volumes:
- ./config/pipelines.yml:/usr/share/logstash/config/pipelines.yml:ro
- ./config/pipelines:/usr/share/logstash/config/pipelines:ro
- ./logs:/usr/share/logstash/input
A änneren d'Input Rubrik an habr_pipeline.conf
input {
file {
path => "/usr/share/logstash/input/*.log"
}
}
Loosst eis ufänken:
docker-compose up
Fir Logbicher ze kreéieren an ze schreiwen benotze mir de Kommando:
echo '1' >> logs/number1.log
{
logstash_one_channel | "host" => "ac2d4e3ef70f",
logstash_one_channel | "habra_field" => "Hello Habr",
logstash_one_channel | "@timestamp" => 2019-04-29T14:28:53.876Z,
logstash_one_channel | "@version" => "1",
logstash_one_channel | "message" => "1",
logstash_one_channel | "path" => "/usr/share/logstash/input/number1.log"
logstash_one_channel | }
Jo, et funktionnéiert!
Zur selwechter Zäit gesi mir datt mir automatesch de Weefeld bäigefüügt hunn. Dëst bedeit datt mir an Zukunft records dorop kënnen filteren.
Loosst eis nach eng Kéier probéieren:
echo '2' >> logs/number1.log
{
logstash_one_channel | "host" => "ac2d4e3ef70f",
logstash_one_channel | "habra_field" => "Hello Habr",
logstash_one_channel | "@timestamp" => 2019-04-29T14:28:59.906Z,
logstash_one_channel | "@version" => "1",
logstash_one_channel | "message" => "2",
logstash_one_channel | "path" => "/usr/share/logstash/input/number1.log"
logstash_one_channel | }
An elo zu engem anere Fichier:
echo '1' >> logs/number2.log
{
logstash_one_channel | "host" => "ac2d4e3ef70f",
logstash_one_channel | "habra_field" => "Hello Habr",
logstash_one_channel | "@timestamp" => 2019-04-29T14:29:26.061Z,
logstash_one_channel | "@version" => "1",
logstash_one_channel | "message" => "1",
logstash_one_channel | "path" => "/usr/share/logstash/input/number2.log"
logstash_one_channel | }
Super! D'Datei gouf opgeholl, de Wee gouf korrekt spezifizéiert, alles ass gutt.
Stop Logstash a fänkt erëm un. Loosst eis waarden. Rou. Déi. Mir kréien dës records net erëm.
An elo dat getraut Experiment.
Installéiert Logstash an ausféiert:
echo '3' >> logs/number2.log
echo '4' >> logs/number1.log
Run Logstash erëm a kuckt:
logstash_one_channel | {
logstash_one_channel | "host" => "ac2d4e3ef70f",
logstash_one_channel | "habra_field" => "Hello Habr",
logstash_one_channel | "message" => "3",
logstash_one_channel | "@version" => "1",
logstash_one_channel | "path" => "/usr/share/logstash/input/number2.log",
logstash_one_channel | "@timestamp" => 2019-04-29T14:48:50.589Z
logstash_one_channel | }
logstash_one_channel | {
logstash_one_channel | "host" => "ac2d4e3ef70f",
logstash_one_channel | "habra_field" => "Hello Habr",
logstash_one_channel | "message" => "4",
logstash_one_channel | "@version" => "1",
logstash_one_channel | "path" => "/usr/share/logstash/input/number1.log",
logstash_one_channel | "@timestamp" => 2019-04-29T14:48:50.856Z
logstash_one_channel | }
Hour! Alles gouf opgeholl.
Mä mir mussen Iech iwwer déi folgend warnen. Wann de Logstash Container geläscht gëtt (docker stop logstash_one_channel && docker rm logstash_one_channel), da gëtt näischt opgeholl. D'Positioun vun der Datei bis zu där se gelies gouf gouf am Container gespäichert. Wann Dir et vun Null leeft, akzeptéiert et nëmmen nei Linnen.
Liesen bestehend Fichieren
Loosst eis soen datt mir Logstash fir d'éischte Kéier lancéieren, awer mir hu scho Logbicher a mir wëllen se veraarbechten.
Wa mir Logstash mat der Input Sektioun lafen, déi mir uewe benotzt hunn, kréie mir näischt. Nëmmen nei Linnen ginn duerch Logstash veraarbecht.
Fir Linnen aus existente Dateien ze zéien, sollt Dir eng zousätzlech Zeil an d'Input Sektioun addéieren:
input {
file {
start_position => "beginning"
path => "/usr/share/logstash/input/*.log"
}
}
Ausserdeem gëtt et eng Nuance: dëst beaflosst nëmmen nei Dateien déi de Logstash nach net gesinn huet. Fir déiselwecht Dateien, déi schonn am Siichtfeld vu Logstash waren, huet et schonn hir Gréisst erënnert a wäert elo nëmmen nei Entréen an hinnen huelen.
Loosst eis hei ophalen an d'Input Sektioun studéieren. Et ginn nach vill Optiounen, awer dat ass genuch fir eis fir weider Experimenter fir de Moment.
Routing an Daten Transformatioun
Loosst eis probéieren de folgende Problem ze léisen, loosst eis soen datt mir Messagen vun engem Kanal hunn, e puer vun hinnen sinn informativ, an e puer sinn Fehlermeldungen. Si ënnerscheede sech duerch Tag. E puer sinn INFO, anerer sinn ERROR.
Mir mussen se bei der Sortie trennen. Déi. Mir schreiwen Informatiounsmeldungen an engem Kanal, a Fehlermeldungen an engem aneren.
Fir dëst ze maachen, réckelt vun der Input Sektioun op Filter an Output.
Mat der Filtersektioun wäerte mir déi erakommen Noriicht parséieren, en Hash (Schlëssel-Wäertpairen) kréien, mat deem mir scho kënne schaffen, d.h. no Konditiounen disassemble. An an der Ausgangssektioun wäerte mir Messagen auswielen an all eenzel op säin eegene Kanal schécken.
Parsing e Message mat Grok
Fir Text Strings ze analyséieren an e Set vu Felder vun hinnen ze kréien, gëtt et e spezielle Plugin an der Filtersektioun - grok.
Ouni mech d'Zil ze setzen fir eng detailléiert Beschreiwung dovun hei ze ginn (fir dëst bezéien ech op
Fir dëst ze maachen, musst Dir iwwer d'Format vun den Input Saiten entscheeden. Ech hunn se esou:
1 INFO Message1
2 Feelmeldung 2
Déi. Den Identifizéierer kënnt als éischt, dann INFO/Feeler, dann e puer Wuert ouni Raum.
Et ass net schwéier, awer et ass genuch fir de Prinzip vun der Operatioun ze verstoen.
Also, an der Filtersektioun vum Grok Plugin, musse mir e Muster definéieren fir eis Saiten ze analyséieren.
Et wäert esou ausgesinn:
filter {
grok {
match => { "message" => ["%{INT:message_id} %{LOGLEVEL:message_type} %{WORD:message_text}"] }
}
}
Wesentlech ass et e reguläre Ausdrock. Fäerdeg Mustere gi benotzt, wéi INT, LOGLEVEL, WORD. Hir Beschreiwung, wéi och aner Mustere kënnen hei fonnt ginn
Elo, duerch dëse Filter passéiert, wäert eis String an en Hash vun dräi Felder verwandelen: message_id, message_type, message_text.
Si ginn an der Ausgangssektioun ugewisen.
Routing Messagen op d'Output Sektioun mat dem Kommando if
An der Ausgangssektioun, wéi mir eis erënneren, wäerte mir d'Botschaften an zwee Streamen opdeelen. E puer - déi iNFO sinn, ginn op d'Konsole erausginn, a mat Feeler wäerte mir op eng Datei erausginn.
Wéi trenne mir dës Messagen? Den Zoustand vum Problem proposéiert schonn eng Léisung - schliisslech hu mir schonn en dedizéierten Message_type Feld, deen nëmmen zwee Wäerter ka huelen: INFO an ERROR. Et ass op dëser Basis datt mir e Choix maache mat der if Ausso.
if [message_type] == "ERROR" {
# Здесь выводим в файл
} else
{
# Здесь выводим в stdout
}
Eng Beschreiwung vun der Aarbecht mat Felder an Opérateuren kann an dëser Rubrik fonnt ginn
Elo iwwer déi eigentlech Conclusioun selwer.
Konsolausgang, hei ass alles kloer - stdout {}
Awer d'Ausgab op eng Datei - erënnert datt mir all dëst aus engem Container lafen a fir datt d'Datei, an där mir d'Resultat schreiwen, vu baussen zougänglech ass, musse mir dëse Verzeechnes an docker-compose.yml opmaachen.
Total:
D'Output Sektioun vun eiser Datei gesäit esou aus:
output {
if [message_type] == "ERROR" {
file {
path => "/usr/share/logstash/output/test.log"
codec => line { format => "custom format: %{message}"}
}
} else
{stdout {
}
}
}
An docker-compose.yml addéiere mer en anere Volume fir d'Ausgab:
version: '3'
networks:
elk:
volumes:
elasticsearch:
driver: local
services:
logstash:
container_name: logstash_one_channel
image: docker.elastic.co/logstash/logstash:6.3.2
networks:
- elk
environment:
XPACK_MONITORING_ENABLED: "false"
ports:
- 5046:5046
volumes:
- ./config/pipelines.yml:/usr/share/logstash/config/pipelines.yml:ro
- ./config/pipelines:/usr/share/logstash/config/pipelines:ro
- ./logs:/usr/share/logstash/input
- ./output:/usr/share/logstash/output
Mir starten et, probéieren et a gesinn eng Divisioun an zwee Streamen.
Source: will.com