Utumiaji wa vitendo wa ELK. Kuweka logstash

Utangulizi

Wakati wa kupeleka mfumo mwingine, tulikabiliwa na hitaji la kuchakata idadi kubwa ya kumbukumbu mbalimbali. ELK ilichaguliwa kama chombo. Nakala hii itazungumza juu ya uzoefu wetu katika kuanzisha stack hii.

Hatuweki lengo la kuelezea uwezo wake wote, lakini tunataka kuzingatia kutatua matatizo ya vitendo. Hii ni kutokana na ukweli kwamba kwa kiasi kikubwa cha kutosha cha nyaraka na picha zilizopangwa tayari, kuna vikwazo vingi, angalau tulizipata.

Tulisambaza stack kupitia docker-compose. Zaidi ya hayo, tulikuwa na docker-compose.yml iliyoandikwa vizuri ambayo ilituruhusu kuinua rafu bila matatizo yoyote. Na ilionekana kwetu kuwa ushindi tayari ulikuwa karibu, sasa tutaipotosha kidogo ili kukidhi mahitaji yetu na ndivyo hivyo.

Kwa bahati mbaya, jaribio la kurekebisha mfumo ili kupokea na kuchakata kumbukumbu kutoka kwa ombi letu halikufaulu mara moja. Kwa hivyo, tuliamua kuwa inafaa kusoma kila sehemu kando, na kisha kurudi kwenye viunganisho vyao.

Kwa hivyo wacha tuanze na logstash.

Mazingira, uwekaji, kuendesha Logstash kwenye kontena

Kwa kupelekwa, tunatumia docker-compose, majaribio yaliyoelezwa hapa yalifanywa kwenye MacOS na Ubuntu 18.0.4.

Picha ya logstash ambayo tulikuwa nayo kwenye docker-compose.yml yetu ya asili ni docker.elastic.co/logstash/logstash:6.3.2

Tutatumia kwa majaribio.

Ili kuendesha logstash, tuliandika docker-compose.yml tofauti. Bila shaka, iliwezekana kuzindua picha kutoka kwa mstari wa amri, lakini baada ya yote, tulitatua kazi maalum, ambapo kila kitu kutoka kwa docker-compose kinazinduliwa kwa ajili yetu.

Kwa kifupi kuhusu faili za usanidi

Kama ifuatavyo kutoka kwa maelezo, logstash inaweza kuendeshwa kama chaneli moja, katika kesi hii, inahitaji kuhamisha faili ya *.conf au chaneli kadhaa, katika hali ambayo inahitaji kuhamisha faili ya pipelines.yml, ambayo, kwa upande wake. , itarejelea faili .conf kwa kila kituo.
Tulichukua njia ya pili. Ilionekana kwetu kuwa ya kubadilika zaidi na ya hatari. Kwa hivyo, tuliunda pipelines.yml, na kutengeneza saraka ya mabomba ambayo tutaweka faili za .conf kwa kila kituo.

Ndani ya chombo kuna faili nyingine ya usanidi - logstash.yml. Hatuigusi, tunaitumia kama ilivyo.

Kwa hivyo muundo wetu wa saraka ni:

Utumiaji wa vitendo wa ELK. Kuweka logstash

Kwa sasa, tunadhania kuwa hii ni tcp kwenye port 5046 ili kupokea data ya ingizo, na tutatumia stdout kwa kutoa.

Hapa kuna usanidi rahisi kama huu wa kukimbia kwanza. Kwa sababu kazi ya awali ni kuzindua.

Kwa hivyo tunayo docker-compose.yml hii

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

Tunaona nini hapa?

  1. Mitandao na juzuu zilichukuliwa kutoka kwa docker-compose.yml asili (ile ambapo mkusanyiko mzima umezinduliwa) na nadhani haziathiri sana picha ya jumla hapa.
  2. Tunaunda huduma moja (huduma) logstash, kutoka kwa docker.elastic.co/logstash/logstash:6.3.2 picha na kuipa jina logstash_one_channel.
  3. Tunasambaza mlango 5046 ndani ya kontena, hadi kwenye mlango sawa wa ndani.
  4. Tunapanga faili yetu ya ./config/pipelines.yml ya usanidi wa bomba kwa /usr/share/logstash/config/pipelines.yml faili ndani ya kontena, ambapo logstash itachukua na kuifanya isomeke tu, endapo itawezekana.
  5. Tunapanga saraka ya ./config/pipelines, ambapo tuna faili za usanidi wa bomba, kwa saraka ya /usr/share/logstash/config/pipelines na pia kuifanya isomeke tu.

Utumiaji wa vitendo wa ELK. Kuweka logstash

piping.yml faili

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

Inaelezea chaneli moja iliyo na kitambulisho cha HABR na njia ya faili yake ya usanidi.

Na hatimaye faili "./config/pipelines/habr_pipeline.conf"

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

Hatutaingia katika maelezo yake kwa sasa, tunajaribu kukimbia:

docker-compose up

Tunaona nini?

Chombo kimeanza. Tunaweza kuangalia kazi yake:

echo '13123123123123123123123213123213' | nc localhost 5046

Na tunaona majibu kwenye koni ya chombo:

Utumiaji wa vitendo wa ELK. Kuweka logstash

Lakini wakati huo huo, tunaona pia:

logstash_chaneli_moja | [2019-04-29T11:28:59,790][ERROR][logstash.licensechecker.licensereader] Haijaweza kuepua maelezo ya leseni kutoka kwa seva ya leseni {:message=>"Elasticsearch Unreachable: [http://elasticsearch:9200/][Manticore ::ResolutionFailure]elasticsearch", ...

logstash_chaneli_moja | [2019-04-29T11:28:59,894][INFO ][logstash.pipeline ] Bomba lilianza kwa mafanikio {:pipeline_id=>".monitoring-logstash", :thread=>"# Β»}

logstash_channel_one | [2019-04-29T11:28:59,988][INFO ][logstash.agent ] Mabomba yanayoendesha {:count=>2, :running_pipelines=>[:HABR, :".monitoring-logstash"], :non_running_pipelines=>[ ]}
logstash_channel_one | [2019-04-29T11:29:00,015][ERROR][logstash.inputs.metrics ] X-Pack imesakinishwa kwenye Logstash lakini si kwenye Elasticsearch. Tafadhali sakinisha X-Pack kwenye Elasticsearch ili kutumia kipengele cha ufuatiliaji. Vipengele vingine vinaweza kupatikana.
logstash_chaneli_moja | [2019-04-29T11:29:00,526][INFO ][logstash.agent ] Imefaulu kuanzisha mwisho wa API ya Logstash {:port=>9600}
logstash_channel_one | [2019-04-29T11:29:04,478][INFO ][logstash.outputs.elasticsearch] Inaendesha ukaguzi wa afya ili kuona kama muunganisho wa Elasticsearch unafanya kazi {:healthcheck_url=>http://elasticsearch:9200/, :path=> "/"}
logstash_channel_one | [2019-04-29T11:29:04,487][WARN ][logstash.outputs.elasticsearch] Ilijaribu kufufua muunganisho wa mfano wa ES uliokufa, lakini ilipata hitilafu. {:url=>"utaftaji wa elastic... elasticsearch"}
logstash_chaneli_moja | [2019-04-29T11:29:04,704][INFO ][logstash.licensechecker.licensereader] Inaendesha ukaguzi wa afya ili kuona kama muunganisho wa Elasticsearch unafanya kazi {:healthcheck_url=>http://elasticsearch:9200/, :path=> "/"}
logstash_channel_one | [2019-04-29T11:29:04,710][WARN ][logstash.licensechecker.licensereader] Ilijaribu kufufua muunganisho wa mfano wa ES uliokufa, lakini ilipata hitilafu. {:url=>"utaftaji wa elastic... elasticsearch"}

Na logi yetu hutambaa kila wakati.

Hapa niliangazia kwa kijani ujumbe ambao bomba lilianza kwa mafanikio, kwa nyekundu ujumbe wa makosa na kwa manjano ujumbe kuhusu kujaribu kuwasiliana. utaftaji wa elastic: 9200.
Hii hutokea kutokana na ukweli kwamba katika logstash.conf iliyojumuishwa kwenye picha, kuna hundi ya upatikanaji wa elasticsearch. Baada ya yote, logstash inadhani kuwa inafanya kazi kama sehemu ya safu ya Elk, na tukaitenganisha.

Unaweza kufanya kazi, lakini sio rahisi.

Suluhisho ni kuzima ukaguzi huu kupitia XPACK_MONITORING_ENABLED utofauti wa mazingira.

Wacha tufanye mabadiliko kwa docker-compose.yml na tuiendeshe tena:

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

Sasa, kila kitu kiko sawa. Chombo kiko tayari kwa majaribio.

Tunaweza kuandika tena kwenye koni iliyo karibu:

echo '13123123123123123123123213123213' | nc localhost 5046

Na tazama:

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

Fanya kazi ndani ya kituo kimoja

Kwa hiyo, tulianza. Sasa unaweza kuchukua muda kusanidi logstash moja kwa moja. Wacha tusiguse faili ya pipelines.yml kwa sasa, wacha tuone tunachoweza kupata kwa kufanya kazi na chaneli moja.

Lazima niseme kwamba kanuni ya jumla ya kufanya kazi na faili ya usanidi wa kituo imeelezewa vizuri katika mwongozo rasmi, hapa hapa
Ikiwa unataka kusoma kwa Kirusi, basi tulitumia hii makala(lakini syntax ya hoja ni ya zamani hapo, unahitaji kuzingatia hii).

Hebu twende kwa kufuatana kutoka sehemu ya Ingizo. Tayari tumeona kazi kwenye tcp. Ni nini kingine kinachoweza kuvutia hapa?

Jaribu jumbe kwa kutumia mapigo ya moyo

Kuna uwezekano huo wa kuvutia wa kutoa ujumbe wa majaribio otomatiki.
Ili kufanya hivyo, unahitaji kujumuisha programu-jalizi ya moyo katika sehemu ya uingizaji.

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

Tunawasha, tunaanza kupokea mara moja kwa dakika

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

Tunataka kupokea mara nyingi zaidi, tunahitaji kuongeza parameter ya muda.
Hivi ndivyo tutakavyopokea ujumbe kila baada ya sekunde 10.

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

Kupata data kutoka kwa faili

Tuliamua pia kuangalia hali ya faili. Ikiwa inafanya kazi vizuri na faili, basi inawezekana kwamba hakuna wakala anayehitajika, vizuri, angalau kwa matumizi ya ndani.

Kwa mujibu wa maelezo, hali ya uendeshaji inapaswa kuwa sawa na mkia -f, i.e. inasoma mistari mipya au, kwa hiari, inasoma faili nzima.

Kwa hivyo kile tunachotaka kupata:

  1. Tunataka kupokea laini ambazo zimeambatishwa kwa faili moja ya kumbukumbu.
  2. Tunataka kupokea data ambayo imeandikwa kwa faili kadhaa za kumbukumbu, huku tukiwa na uwezo wa kutenganisha kile kilichopokelewa kutoka wapi.
  3. Tunataka kuhakikisha kuwa logstash inapowashwa upya, haitapokea data hii tena.
  4. Tunataka kuangalia kwamba ikiwa logstash imezimwa, na data inaendelea kuandikwa kwa faili, basi tunapoiendesha, tutapokea data hii.

Ili kufanya jaribio, hebu tuongeze mstari mmoja zaidi kwa docker-compose.yml, tukifungua saraka ambapo tunaweka faili.

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

Na ubadilishe sehemu ya ingizo katika habr_pipeline.conf

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

Tunaanza:

docker-compose up

Ili kuunda na kuandika faili za kumbukumbu, tutatumia amri:


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

Ndio, inafanya kazi!

Wakati huo huo, tunaona kwamba tumeongeza moja kwa moja uwanja wa njia. Kwa hivyo katika siku zijazo, tutaweza kuchuja rekodi kwa hilo.

Hebu tujaribu tena:

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

Na sasa kwa faili nyingine:

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

Kubwa! Faili ilichukuliwa, njia ilielezwa kwa usahihi, kila kitu ni sawa.

Acha kuweka kumbukumbu na uanze upya. Tusubiri. Kimya. Wale. Hatupokei rekodi hizi tena.

Na sasa jaribio la kuthubutu zaidi.

Tunaweka logstash na kutekeleza:

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

Endesha logstash tena na uone:

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

Hooray! Kila kitu kilichukua.

Lakini, ni muhimu kuonya kuhusu zifuatazo. Chombo cha logstash kikiondolewa (docker stop logstash_one_channel && docker rm logstash_one_channel), hakuna kitakachochukuliwa. Nafasi ya faili ambayo ilisomwa ilihifadhiwa ndani ya kontena. Ikiwa utaanza kutoka mwanzo, basi itakubali tu mistari mpya.

Kusoma faili zilizopo

Wacha tuseme tunaendesha logstash kwa mara ya kwanza, lakini tayari tunayo kumbukumbu na tungependa kuzichakata.
Ikiwa tutaendesha logstash na sehemu ya kuingiza tuliyotumia hapo juu, hatutapata chochote. Ni laini mpya pekee ndizo zitachakatwa na logstash.

Ili kuvuta mistari kutoka kwa faili zilizopo, ongeza laini ya ziada kwenye sehemu ya ingizo:

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

Kwa kuongeza, kuna nuance, hii inathiri tu faili mpya ambazo logstash bado haijaona. Kwa faili sawa ambazo tayari zilikuwa kwenye uwanja wa mtazamo wa logstash, tayari imekumbuka ukubwa wao na sasa itachukua rekodi mpya tu ndani yao.

Wacha tusimame kwa hili kwa kusoma sehemu ya kuingiza. Kuna chaguzi nyingi zaidi, lakini kwa sasa, tunayo ya kutosha kwa majaribio zaidi.

Ubadilishaji wa njia na data

Wacha tujaribu kusuluhisha shida ifuatayo, tuseme tuna ujumbe kutoka kwa chaneli moja, zingine ni za habari, na zingine ni ujumbe wa makosa. Wanatofautiana katika tag. Baadhi ni INFO, nyingine ni HITILAFU.

Tunahitaji kuwatenganisha wakati wa kutoka. Wale. Tunaandika ujumbe wa habari katika kituo kimoja, na ujumbe wa makosa katika mwingine.

Ili kufanya hivyo, nenda kutoka sehemu ya ingizo ili kuchuja na kutoa.

Kutumia sehemu ya chujio, tutachanganua ujumbe unaoingia, kupata hashi (jozi za thamani-muhimu) kutoka kwake, ambayo tunaweza kufanya kazi tayari, i.e. kuchanganua kulingana na masharti. Na katika sehemu ya pato, tutachagua ujumbe na kutuma kila moja kwa kituo chake.

Kuchanganua ujumbe na grok

Ili kuchanganua masharti ya maandishi na kupata seti ya mashamba kutoka kwao, kuna programu-jalizi maalum katika sehemu ya chujio - grok.

Bila kujiwekea lengo la kutoa maelezo ya kina hapa (kwa hili ninarejelea nyaraka rasmi), nitatoa mfano wangu rahisi.

Ili kufanya hivyo, unahitaji kuamua juu ya muundo wa mistari ya pembejeo. Nina yao kama hii:

Ujumbe 1 wa MAELEZO1
2 UJUMBE MAKOSA2

Wale. Kitambulisho kwanza, kisha INFO/ERROR, kisha neno bila nafasi.
Si vigumu, lakini kutosha kuelewa kanuni ya uendeshaji.

Kwa hivyo, katika sehemu ya kichungi, kwenye programu-jalizi ya grok, tunahitaji kufafanua muundo wa kuchanganua nyuzi zetu.

Itakuwa kama hii:

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

Kimsingi, ni usemi wa kawaida. Miundo iliyotengenezwa tayari hutumiwa, kama vile INT, LOGLEVEL, WORD. Maelezo yao, pamoja na mifumo mingine, inaweza kutazamwa hapa. hapa

Sasa, tukipitia kichujio hiki, mfuatano wetu utageuka kuwa heshi ya sehemu tatu: message_id, message_type, message_text.

Wataonyeshwa katika sehemu ya towe.

Kuelekeza ujumbe katika sehemu ya pato kwa amri if

Katika sehemu ya pato, kama tunavyokumbuka, tungeenda kugawanya ujumbe katika mitiririko miwili. Baadhi - ambayo ni iNFO, tutatoa kwa console, na kwa makosa, tutatoa faili.

Je, tunawezaje kushiriki ujumbe huu? Hali ya tatizo tayari inapendekeza suluhisho - baada ya yote, tayari tunayo sehemu maalum ya ujumbe_aina, ambayo inaweza kuchukua maadili mawili tu INFO na ERROR. Ni juu yake kwamba tutafanya chaguo kwa kutumia taarifa ya if.

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

Maelezo ya kazi na mashamba na waendeshaji yanaweza kupatikana katika sehemu hii mwongozo rasmi.

Sasa, kuhusu hitimisho yenyewe.

Pato la Console, kila kitu kiko wazi hapa - stdout {}

Lakini pato kwa faili - kumbuka kwamba tunaendesha haya yote kutoka kwenye chombo na ili faili ambayo tunaandika matokeo iweze kupatikana kutoka nje, tunahitaji kufungua saraka hii katika docker-compose.yml.

Jumla:

Sehemu ya pato la faili yetu inaonekana kama hii:


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

Ongeza sauti moja zaidi kwa docker-compose.yml kwa pato:

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

Tunaanza, tunajaribu, tunaona mgawanyiko katika mito miwili.

Chanzo: mapenzi.com

Kuongeza maoni