ELKren aplikazio praktikoa. Logstash konfiguratzen

Sarrera

Beste sistema bat zabaltzen ari ginen bitartean, hainbat erregistro prozesatu beharrari aurre egin genion. ELK aukeratu zuten instrumentu gisa. Artikulu honek pila hau konfiguratzean dugun esperientziari buruz hitz egingo du.

Ez dugu helbururik ezartzen bere gaitasun guztiak deskribatzeko, baina arazo praktikoak konpontzen zentratu nahi dugu. Izan ere, dokumentazio kopuru nahiko handiarekin eta prest egindako irudiekin, tranpa asko daudelako, aurkitu ditugu behintzat.

Docker-compose bidez zabaldu dugu pila. Gainera, ondo idatzitako docker-compose.yml bat genuen, ia arazorik gabe pila igotzeko aukera eman ziguna. Eta garaipena jada gertu zegoela iruditu zitzaigun, orain pixka bat bihurrituko dugu gure beharretara egokitzeko eta kitto.

Zoritxarrez, gure aplikazioaren erregistroak jaso eta prozesatzeko sistema sintonizatzeko saiakerak ez zuen arrakastarik izan. Hori dela eta, osagai bakoitza bereizita aztertzea merezi duela erabaki dugu, eta gero haien loturetara itzultzea.

Beraz, has gaitezen logstash-ekin.

Ingurumena, hedapena, Logstash edukiontzi batean exekutatzen

Inplementatzeko, docker-compose erabiltzen dugu, hemen deskribatutako esperimentuak MacOS eta Ubuntu 18.0.4-n egin ziren.

Gure jatorrizko docker-compose.yml-n genuen logstash irudia docker.elastic.co/logstash/logstash:6.3.2 da

Esperimentuetarako erabiliko dugu.

Logstash exekutatzeko, docker-compose.yml bereizi bat idatzi dugu. Noski, irudia komando-lerrotik abiarazteko posible zen, baina azken finean, zeregin zehatz bat konpondu genuen, non docker-compose-tik dena abiarazten zaigun.

Konfigurazio fitxategiei buruz laburki

Deskribapenetik ondorioztatzen den moduan, logstash kanal baterako bezala exekutatu daiteke, kasu honetan, *.conf fitxategia edo hainbat kanaletarako transferitu behar du, eta kasu horretan pipelines.yml fitxategia transferitu behar du, eta, aldi berean , kanal bakoitzeko .conf fitxategiei erreferentzia egingo die.
Bigarren bidea hartu genuen. Polifazetikoagoa eta eskalagarriagoa iruditu zitzaigun. Hori dela eta, pipelines.yml sortu dugu, eta kanal bakoitzeko .conf fitxategiak jarriko ditugun pipelines direktorio bat egin dugu.

Edukiontziaren barruan beste konfigurazio fitxategi bat dago - logstash.yml. Ez dugu ukitzen, dagoen bezala erabiltzen dugu.

Beraz, gure direktorioaren egitura hau da:

ELKren aplikazio praktikoa. Logstash konfiguratzen

Momentuz, 5046 atakan tcp dela suposatzen dugu sarrerako datuak jasotzeko, eta irteerarako stdout erabiliko dugu.

Hona hemen lehen exekuziorako konfigurazio sinple bat. Hasierako zeregina martxan jartzea delako.

Beraz, docker-compose.yml hau dugu

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

Zer ikusten dugu hemen?

  1. Sareak eta bolumenak jatorrizko docker-compose.yml (pila osoa abiarazten den horretatik) hartu ziren eta uste dut ez dutela asko eragiten hemen irudi orokorrari.
  2. Logstash zerbitzu (zerbitzuak) bat sortzen dugu, docker.elastic.co/logstash/logstash:6.3.2 iruditik eta logstash_one_channel izena ematen diogu.
  3. 5046 ataka edukiontziaren barruan birbidaltzen ari gara, barne portu berera.
  4. Gure ./config/pipelines.yml kanalizazio-konfigurazio-fitxategia edukiontzi barruan dagoen /usr/share/logstash/config/pipelines.yml fitxategira mapatzen dugu, non logstash-ek jasoko duen eta irakurtzeko soilik izango da alde segurua.
  5. ./config/pipelines direktorioa, non kanalen konfigurazio-fitxategiak ditugun, /usr/share/logstash/config/pipelines direktorioa eta irakurtzeko soilik egiten dugu.

ELKren aplikazio praktikoa. Logstash konfiguratzen

piping.yml fitxategia

- pipeline.id: HABR
  pipeline.workers: 1
  pipeline.batch.size: 1
  path.config: "./config/pipelines/habr_pipeline.conf"

Kanal bat deskribatzen du HABR identifikatzailearekin eta bere konfigurazio fitxategirako bidea.

Eta azkenik "./config/pipelines/habr_pipeline.conf" fitxategia

input {
  tcp {
    port => "5046"
   }
  }
filter {
  mutate {
    add_field => [ "habra_field", "Hello Habr" ]
    }
  }
output {
  stdout {
      
    }
  }

Ez gara bere deskribapenean sartuko oraingoz, exekutatzen saiatzen gara:

docker-compose up

Zer ikusten dugu?

Edukiontzia hasi da. Bere lana egiaztatu dezakegu:

echo '13123123123123123123123213123213' | nc localhost 5046

Eta erantzuna edukiontzien kontsolan ikusten dugu:

ELKren aplikazio praktikoa. Logstash konfiguratzen

Baina, aldi berean, ikusten dugu:

logstash_one_channel | [2019-04-29T11:28:59,790][ERROREA][logstash.licensechecker.licensereader] Ezin da lizentzia-informazioa berreskuratu lizentzia-zerbitzaritik {:message=>"Elasticsearch Ezin da iritsi: [http://elasticsearch:9200/][Manticore ::ResolutionFailure]elasticsearch",...

logstash_one_channel | [2019-04-29T11:28:59,894][INFO ][logstash.pipeline ] Pipeline arrakastaz hasi da {:pipeline_id=>".monitoring-logstash", :thread=>"# Β»}

logstash_one_channel | [2019-04-29T11:28:59,988][INFO ][logstash.agent ] Pipelines exekutatzen ari diren {: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 Logstash-en instalatuta dago baina ez Elasticsearch-en. Mesedez, instalatu X-Pack Elasticsearch-en monitorizazio funtzioa erabiltzeko. Baliteke beste funtzio batzuk erabilgarri egotea.
logstash_one_channel | [2019-04-29T11:29:00,526][INFO ][logstash.agent ] Logstash API amaierako puntua behar bezala hasi zen {:port=>9600}
logstash_one_channel | [2019-04-29T11:29:04,478][INFO ][logstash.outputs.elasticsearch] Osasun-egiaztapena exekutatzen Elasticsearch konexio bat funtzionatzen ari den ikusteko {:healthcheck_url=>http://elasticsearch:9200/, :path=> "/"}
logstash_one_channel | [2019-04-29T11:29:04,487][WARN ][logstash.outputs.elasticsearch] Hildako ES instantziarako konexioa berpizten saiatu da, baina errore bat izan da. {:url =>"elastiko bilaketa:9200/", :error_type=>LogStash::Outputs::ElasticSearch::HttpClient::Pool::HostUnreachableError, :error=>"Elasticsearch atzeman ezina: [http://elasticsearch:9200/][Manticore::ResolutionFailure] bilaketa elastikoa"}
logstash_one_channel | [2019-04-29T11:29:04,704][INFO ][logstash.licensechecker.licensereader] Osasun-egiaztapena exekutatzen Elasticsearch konexio bat funtzionatzen ari den ikusteko {:healthcheck_url=>http://elasticsearch:9200/, :path=> "/"}
logstash_one_channel | [2019-04-29T11:29:04,710][WARN ][logstash.licensechecker.licensereader] Hildako ES instantziarako konexioa berpizten saiatu da, baina errore bat izan da. {:url =>"elastiko bilaketa:9200/", :error_type=>LogStash::Outputs::ElasticSearch::HttpClient::Pool::HostUnreachableError, :error=>"Elasticsearch atzeman ezina: [http://elasticsearch:9200/][Manticore::ResolutionFailure] bilaketa elastikoa"}

Eta gure erregistroa etengabe arakatzen da.

Hemen berdez nabarmendu dut kanalizazioa ongi hasi zelako mezua, gorriz errore mezua eta horiz harremanetan jartzen saiatzeari buruzko mezua. elastiko bilaketa: 9200.
Irudian sartutako logstash.conf-en elastiko bilaketaren erabilgarritasunaren egiaztapena dagoelako gertatzen da hori. Azken finean, logstash-ek Elk pilaren zati gisa funtzionatzen duela suposatzen du eta bereizi egin dugu.

Lan egin dezakezu, baina ez da komenigarria.

Irtenbidea egiaztapen hau XPACK_MONITORING_ENABLED ingurune-aldagaiaren bidez desgaitzea da.

Egin dezagun aldaketa docker-compose.yml-en eta exekutatu berriro:

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

Orain, dena ondo dago. Ontzia esperimentuak egiteko prest dago.

Berriro idatzi dezakegu ondoko kontsolan:

echo '13123123123123123123123213123213' | nc localhost 5046

Eta ikusi:

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 | }

Lan egin kanal bakarrean

Beraz, hasi ginen. Orain benetan denbora hartu dezakezu logstash zuzenean konfiguratzeko. Ez dezagun ukitu pipelines.yml fitxategia oraingoz, ikus dezagun zer lor dezakegun kanal batekin lan eginez.

Esan behar dut kanalaren konfigurazio fitxategiarekin lan egiteko printzipio orokorra eskuliburu ofizialean ondo deskribatuta dagoela, hemen Hemen
Errusieraz irakurri nahi baduzu, hau erabili dugu Artikulu(baina kontsultaren sintaxia zaharra da hor, hau kontuan hartu behar duzu).

Goazen sekuentzialki Sarrera ataletik. Dagoeneko ikusi dugu tcp-en lana. Zer gehiago izan daiteke interesgarria hemen?

Probatu mezuak taupadak erabiliz

Proba automatikoko mezuak sortzeko aukera interesgarria dago.
Horretarako, heartbean plugina sartu behar duzu sarrera atalean.

input {
  heartbeat {
    message => "HeartBeat!"
   }
  } 

Pizten dugu, minutuan behin jasotzen hasten gara

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 | }

Sarriago jaso nahi dugu, tarte parametroa gehitu behar dugu.
Horrela jasoko dugu 10 segundoro mezu bat.

input {
  heartbeat {
    message => "HeartBeat!"
    interval => 10
   }
  }

Fitxategi batetik datuak lortzea

Fitxategi modua ere aztertzea erabaki dugu. Fitxategiarekin ondo funtzionatzen badu, baliteke agenterik behar ez izatea, tira, tokiko erabilerarako behintzat.

Deskribapenaren arabera, funtzionamendu-moduak buztana -f antzekoa izan behar du, hau da. lerro berriak irakurtzen ditu edo, aukeran, fitxategi osoa irakurtzen du.

Beraz, lortu nahi duguna:

  1. Erregistro-fitxategi batean erantsitako lerroak jaso nahi ditugu.
  2. Hainbat log-fitxategitan idatzitako datuak jaso nahi ditugu, jasotakoa nondik bereizi ahal izateko.
  3. Logstash berrabiarazten denean datu hauek berriro jasoko ez dituela ziurtatu nahi dugu.
  4. Logstash desgaituta badago eta datuak fitxategietan idazten jarraitzen badute, exekutatzen dugunean datu hauek jasoko ditugula egiaztatu nahi dugu.

Esperimentua egiteko, gehi dezagun lerro bat gehiago docker-compose.yml-ra, fitxategiak jartzen ditugun direktorioa irekiz.

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

Eta aldatu sarrera atala habr_pipeline.conf-en

input {
  file {
    path => "/usr/share/logstash/input/*.log"
   }
  }

hasten gara:

docker-compose up

Erregistro fitxategiak sortzeko eta idazteko, komandoa erabiliko dugu:


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 | }

Bai, funtzionatzen du!

Aldi berean, bide-eremua automatikoki gehitu dugula ikusten dugu. Beraz, etorkizunean, haren arabera iragazi ahal izango ditugu erregistroak.

Saia gaitezen berriro:

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 | }

Eta orain beste fitxategi batera:

 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 | }

Bikaina! Fitxategia jaso da, bidea behar bezala zehaztu da, dena ondo dago.

Gelditu logstash eta berrabiarazi. Itxaron dezagun. Isiltasuna. Horiek. Ez ditugu berriro erregistro hauek jasotzen.

Eta orain esperimentu ausartena.

Logstash jarri eta exekutatzen dugu:

echo '3' >> logs/number2.log
echo '4' >> logs/number1.log

Exekutatu logstash berriro eta ikusi:

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 | }

Aupa! Dena jasota.

Baina, honako hauei buruz ohartarazi behar da. Logstash edukiontzia kentzen bada (docker stop logstash_one_channel && docker rm logstash_one_channel), ez da ezer jasoko. Irakurri zen fitxategiaren posizioa edukiontzi barruan gordetzen zen. Hutsetik hasten bazara, lerro berriak soilik onartuko ditu.

Lehendik dauden fitxategiak irakurtzea

Demagun logstash lehen aldiz exekutatzen ari garela, baina dagoeneko baditugula erregistroak eta prozesatu nahiko genituzke.
Logstash goian erabili dugun sarrera atalarekin exekutatzen badugu, ez dugu ezer lortuko. Lerro berriak soilik prozesatuko ditu logstash-ek.

Lehendik dauden fitxategietatik lerroak ateratzeko, gehitu lerro gehigarri bat sarrerako atalean:

input {
  file {
    start_position => "beginning"
    path => "/usr/share/logstash/input/*.log"
   }
  }

Gainera, Γ±abardura bat dago, honek logstash-ek oraindik ikusi ez dituen fitxategi berriei bakarrik eragiten die. Logstash-en ikus-eremuan zeuden fitxategi berberetarako, dagoeneko haien tamaina gogoratu du eta orain erregistro berriak bakarrik hartuko ditu.

Eten gaitezen honetan sarrera atala aztertuz. Askoz aukera gehiago daude, baina oraingoz nahikoa dugu esperimentu gehiago egiteko.

Bideraketa eta datuen eraldaketa

Saia gaitezen ondoko arazoa konpontzen, demagun kanal bateko mezuak ditugula, batzuk informatiboak direla eta beste batzuk errore mezuak. Etiketaz desberdinak dira. Batzuk INFO dira, beste batzuk ERROREA.

Irteeran bereizi behar ditugu. Horiek. Informazio-mezuak idazten ditugu kanal batean, eta errore-mezuak beste batean.

Horretarako, joan sarrerako ataletik iragazi eta irteerara.

Iragazkien atala erabiliz, sarrerako mezua analizatuko dugu, bertatik hash bat (gako-balio bikoteak) lortuz, eta horrekin dagoeneko lan egin dezakegu, hau da. baldintzen arabera analizatu. Eta irteera atalean, mezuak hautatu eta bakoitza bere kanalera bidaliko dugu.

Mezu bat grok-ekin analizatzen

Testu-kateak analizatzeko eta haietatik eremu multzo bat lortzeko, iragazkien atalean plugin berezi bat dago - grok.

Hemen horren deskribapen zehatza emateko helburua jarri gabe (horretarako aipatzen dut dokumentazio ofiziala), nire adibide sinplea emango dut.

Horretarako, sarrera-lerroen formatua erabaki behar duzu. Honela ditut:

1 INFO mezua1
2 ERRORE mezua2

Horiek. Identifikatzailea lehenik, gero INFO/ERROREA, gero zuriunerik gabeko hitz bat.
Ez da zaila, baina nahikoa funtzionamendu printzipioa ulertzeko.

Beraz, iragazkien atalean, grok pluginean, gure kateak analizatzeko eredu bat definitu behar dugu.

Honela izango da:

filter {
  grok {
    match => { "message" => ["%{INT:message_id} %{LOGLEVEL:message_type} %{WORD:message_text}"] }
   }
  } 

Funtsean, adierazpen erregularra da. Prestatutako ereduak erabiltzen dira, hala nola INT, LOGLEVEL, WORD. Haien deskribapena, baita beste eredu batzuk ere, hemen ikus daitezke. Hemen

Orain, iragazki honetatik pasatuz, gure katea hiru eremuko hash bihurtuko da: mezu_id, mezu_mota, mezu_testua.

Irteera atalean bistaratuko dira.

Irteera atalean mezuak bideratzea if komandoarekin

Irteera atalean, gogoratzen dugunez, mezuak bi korrontetan banatuko genituen. Batzuk - iNFO direnak, kontsolara aterako ditugu, eta akatsekin, fitxategi batera aterako dugu.

Nola parteka ditzakegu mezu hauek? Arazoaren egoerak dagoeneko irtenbide bat iradokitzen du; azken finean, dagoeneko badaukagu ​​mezu_mota eremu dedikatu bat, zeinak INFO eta ERRORE bi balio soilik har ditzakeena. Bertan egingo dugu aukera if adierazpena erabiliz.

if [message_type] == "ERROR" {
        # Π—Π΄Π΅ΡΡŒ Π²Ρ‹Π²ΠΎΠ΄ΠΈΠΌ Π² Ρ„Π°ΠΉΠ»
       } else
     {
      # Π—Π΄Π΅ΡΡŒ Π²Ρ‹Π²ΠΎΠ΄ΠΈΠΌ Π² stdout
    }

Eremu eta operadoreekin egindako lanaren deskribapena atal honetan aurki daiteke eskuliburu ofiziala.

Orain, ondorioari buruz.

Kontsolaren irteera, dena argi dago hemen - stdout {}

Baina fitxategirako irteera - gogoratu hori guztia edukiontzitik exekutatzen ari garela eta emaitza idazten dugun fitxategia kanpotik eskuragarri egon dadin, direktorio hau docker-compose.yml-en ireki behar dugu.

Guztira:

Gure fitxategiaren irteerako atalak honela dauka:


output {
  if [message_type] == "ERROR" {
    file {
          path => "/usr/share/logstash/output/test.log"
          codec => line { format => "custom format: %{message}"}
         }
    } else
     {stdout {
             }
     }
  }

Gehitu bolumen bat gehiago docker-compose.yml-ra irteerarako:

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

Hasi gara, saiatzen gara, bi korrontetan banatuta ikusten dugu.

Iturria: www.habr.com

Gehitu iruzkin berria