Hagnýt notkun ELK. Að setja upp logstash

Inngangur

Við uppsetningu á öðru kerfi stóðum við frammi fyrir þörfinni á að vinna úr miklum fjölda mismunandi annála. ELK varð fyrir valinu sem tækið. Þessi grein mun fjalla um reynslu okkar af því að setja upp þennan stafla.

Við setjum okkur ekki markmið um að lýsa öllum getu þess, heldur viljum við einbeita okkur sérstaklega að því að leysa hagnýt vandamál. Þetta stafar af því að þó að það sé frekar mikið magn af skjölum og tilbúnum myndum þá eru ansi margar gildrur, við fundum þær allavega.

Við sendum staflann í gegnum docker-compose. Þar að auki vorum við með vel skrifaða docker-compose.yml, sem gerði okkur kleift að hækka staflan nánast án vandræða. Og okkur virtist sem sigur væri þegar nærri lagi, nú munum við fínstilla hann aðeins til að henta þörfum okkar og það er allt.

Því miður tókst ekki strax tilraun til að stilla kerfið til að taka á móti og vinna úr annálum úr forritinu okkar. Þess vegna ákváðum við að það væri þess virði að rannsaka hvern þátt fyrir sig og snúa síðan aftur að tengingum þeirra.

Svo, við byrjuðum með logstash.

Umhverfi, dreifing, keyrir Logstash í gámi

Fyrir uppsetningu notum við docker-compose; tilraunirnar sem lýst er hér voru gerðar á MacOS og Ubuntu 18.0.4.

Logstash myndin sem var skráð í upprunalegu docker-compose.yml okkar er docker.elastic.co/logstash/logstash:6.3.2

Við munum nota það til tilrauna.

Við skrifuðum sérstakan docker-compose.yml til að keyra logstash. Auðvitað var hægt að ræsa myndina frá skipanalínunni, en við vorum að leysa ákveðið vandamál, þar sem við keyrum allt frá docker-compose.

Stuttlega um stillingarskrár

Eins og kemur fram í lýsingunni er hægt að keyra logstash annað hvort fyrir eina rás, í því tilviki þarf það að fara framhjá *.conf skránni, eða fyrir nokkrar rásir, en þá þarf það að fara framhjá pipelines.yml skránni, sem aftur á móti , mun tengja við skrárnar .conf fyrir hverja rás.
Við fórum seinni leiðina. Það virtist okkur alhliða og skalanlegra. Þess vegna bjuggum við til pipelines.yml og gerðum pipelines möppu þar sem við munum setja .conf skrár fyrir hverja rás.

Inni í ílátinu er önnur stillingarskrá - logstash.yml. Við snertum það ekki, við notum það eins og það er.

Svo, möppuuppbygging okkar:

Hagnýt notkun ELK. Að setja upp logstash

Til að fá inntaksgögn gerum við ráð fyrir að þetta sé tcp á höfn 5046 og fyrir úttak munum við nota stdout.

Hér er einföld uppsetning fyrir fyrstu kynningu. Vegna þess að upphafsverkefnið er að ræsa.

Svo, við höfum þetta 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

Hvað sjáum við hér?

  1. Netkerfi og bindi voru tekin úr upprunalegu docker-compose.yml (þeim þar sem allur staflinn er ræstur) og ég held að þau hafi ekki mikil áhrif á heildarmyndina hér.
  2. Við búum til eina logstash þjónustu(r) úr docker.elastic.co/logstash/logstash:6.3.2 myndinni og nefnum hana logstash_one_channel.
  3. Við sendum höfn 5046 inni í gámnum, í sömu innri höfn.
  4. Við kortleggjum pípustillingarskrána okkar ./config/pipelines.yml í skrána /usr/share/logstash/config/pipelines.yml inni í gámnum, þar sem logstash mun taka það upp og gera það skrifvarið, bara ef til öryggis.
  5. Við kortleggjum ./config/pipelines möppuna, þar sem við höfum skrár með rásarstillingum, inn í /usr/share/logstash/config/pipelines möppuna og gerum hana einnig skrifvarða.

Hagnýt notkun ELK. Að setja upp logstash

Pipelines.yml skrá

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

Hér er einni rás með HABR auðkenninu og slóðinni að stillingarskrá hennar lýst.

Og að lokum skráin „./config/pipelines/habr_pipeline.conf“

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

Við skulum ekki fara í lýsingu þess í bili, við skulum reyna að keyra hana:

docker-compose up

Hvað sjáum við?

Gámurinn er byrjaður. Við getum athugað virkni þess:

echo '13123123123123123123123213123213' | nc localhost 5046

Og við sjáum svarið í gámaborðinu:

Hagnýt notkun ELK. Að setja upp logstash

En á sama tíma sjáum við líka:

logstash_one_channel | [2019-04-29T11:28:59,790][ERROR][logstash.licensechecker.licensereader] Ekki tókst að sækja leyfisupplýsingar frá leyfisþjóni {:message=>“Elasticsearch Unreachable: [http://elasticsearch:9200/][Manticore ::ResolutionFailure] elasticsearch", ...

logstash_one_channel | [2019-04-29T11:28:59,894][INFO ][logstash.pipeline ] Leiðsla byrjaði {:pipeline_id=>".monitoring-logstash", :thread=>"# "}

logstash_one_channel | [2019-04-29T11:28:59,988][INFO ][logstash.agent ] Leiðslur í gangi {: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 er sett upp á Logstash en ekki á Elasticsearch. Vinsamlegast settu upp X-Pack á Elasticsearch til að nota vöktunareiginleikann. Aðrir eiginleikar gætu verið í boði.
logstash_one_channel | [2019-04-29T11:29:00,526][INFO ][logstash.agent ] Tókst að ræsa Logstash API endapunkt {:port=>9600}
logstash_one_channel | [2019-04-29T11:29:04,478][INFO ][logstash.outputs.elasticsearch] Keyrir heilsufarsskoðun til að sjá hvort Elasticsearch tenging virkar {:healthcheck_url=>http://elasticsearch:9200/, :path=> "/"}
logstash_one_channel | [2019-04-29T11:29:04,487][WARN ][logstash.outputs.elasticsearch] Reyndi að endurvekja tengingu við dautt ES tilvik, en fékk villu. {:url=>“teygjanám:9200/", :error_type=>LogStash::Outputs::ElasticSearch::HttpClient::Pool::HostUnreachableError, :error=>"Elasticsearch Unreachable: [http://elasticsearch:9200/][Manticore::ResolutionFailure] elasticsearch"}
logstash_one_channel | [2019-04-29T11:29:04,704][INFO ][logstash.licensechecker.licensereader] Keyrir heilsuathugun til að sjá hvort Elasticsearch tenging virkar {:healthcheck_url=>http://elasticsearch:9200/, :path=> "/"}
logstash_one_channel | [2019-04-29T11:29:04,710][WARN ][logstash.licensechecker.licensereader] Reyndi að endurvekja tengingu við dautt ES tilvik en fékk villu. {:url=>“teygjanám:9200/", :error_type=>LogStash::Outputs::ElasticSearch::HttpClient::Pool::HostUnreachableError, :error=>"Elasticsearch Unreachable: [http://elasticsearch:9200/][Manticore::ResolutionFailure] elasticsearch"}

Og loggurinn okkar er að læðast upp allan tímann.

Hér hef ég auðkennt með grænu skilaboðin um að leiðslan hafi ræst með góðum árangri, í rauðu villuboðin og í gulu skilaboðin um tilraun til að hafa samband teygjanám: 9200.
Þetta gerist vegna þess að logstash.conf, innifalið í myndinni, inniheldur ávísun á framboð á elasticsearch. Þegar öllu er á botninn hvolft gerir logstash ráð fyrir að það virki sem hluti af Elk-staflanum, en við skildum hann að.

Það er hægt að vinna, en það er ekki þægilegt.

Lausnin er að slökkva á þessari athugun í gegnum XPACK_MONITORING_ENABLED umhverfisbreytuna.

Við skulum gera breytingu á docker-compose.yml og keyra það aftur:

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

Nú er allt í lagi. Ílátið er tilbúið fyrir tilraunir.

Við getum skrifað aftur í næstu stjórnborði:

echo '13123123123123123123123213123213' | nc localhost 5046

Og sjáðu:

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

Að vinna innan einnar rásar

Svo við lögðum af stað. Nú geturðu í raun tekið þér tíma til að stilla logstash sjálft. Við skulum ekki snerta pipelines.yml skrána í bili, við skulum sjá hvað við getum fengið með því að vinna með eina rás.

Ég verð að segja að almenna meginreglan um að vinna með rásarstillingarskránni er vel lýst í opinberu handbókinni hér hér
Ef þú vilt lesa á rússnesku notuðum við þetta grein(en setningafræði fyrirspurnarinnar þar er gömul, við þurfum að taka tillit til þess).

Við skulum fara í röð frá inntakshlutanum. Við höfum þegar séð vinnu á TCP. Hvað annað gæti verið áhugavert hér?

Prófaðu skilaboð með hjartslætti

Það er svo áhugavert tækifæri til að búa til sjálfvirk prófskilaboð.
Til að gera þetta þarftu að virkja heartbean viðbótina í inntakshlutanum.

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

Kveiktu á því, byrjaðu að fá einu sinni á mínútu

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

Ef við viljum taka á móti oftar þurfum við að bæta við bilbreytu.
Svona munum við fá skilaboð á 10 sekúndna fresti.

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

Að sækja gögn úr skrá

Við ákváðum líka að skoða skráarhaminn. Ef það virkar vel með skránni, þá er kannski ekki þörf á neinum umboðsmanni, að minnsta kosti fyrir staðbundna notkun.

Samkvæmt lýsingunni á rekstrarhamurinn að vera svipaður hali -f, þ.e. les nýjar línur eða, sem valkostur, les alla skrána.

Svo það sem við viljum fá:

  1. Við viljum fá línur sem eru bætt við eina annálaskrá.
  2. Við viljum fá gögn sem eru skrifuð í nokkrar annálaskrár, á sama tíma og við getum aðskilið það sem er móttekið frá hvaðan.
  3. Við viljum ganga úr skugga um að þegar logstash er endurræst fái það ekki þessi gögn aftur.
  4. Við viljum athuga að ef slökkt er á logstash og gögn halda áfram að vera skrifuð í skrár, þá munum við fá þessi gögn þegar við keyrum það.

Til að framkvæma tilraunina skulum við bæta annarri línu við docker-compose.yml og opna möppuna sem við setjum skrárnar í.

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

Og breyttu inntakshlutanum í habr_pipeline.conf

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

Byrjum:

docker-compose up

Til að búa til og skrifa annálaskrár munum við nota skipunina:


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

Jájá, það virkar!

Á sama tíma sjáum við að við höfum sjálfkrafa bætt við slóðareitnum. Þetta þýðir að í framtíðinni munum við geta síað færslur eftir því.

Reynum aftur:

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

Og nú að annarri skrá:

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

Frábært! Skráin var tekin upp, slóðin var rétt tilgreind, allt er í lagi.

Hættu logstash og byrjaðu aftur. Við skulum bíða. Þögn. Þeir. Við fáum ekki þessar skrár aftur.

Og nú djarflegasta tilraunin.

Settu upp logstash og keyrðu:

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

Keyrðu logstash aftur og sjáðu:

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

Húrra! Allt var tekið upp.

En við verðum að vara þig við eftirfarandi. Ef logstash gámnum er eytt (docker stop logstash_one_channel && docker rm logstash_one_channel), þá verður ekkert tekið upp. Staðsetning skráarinnar þar sem hún var lesin var geymd inni í ílátinu. Ef þú keyrir það frá grunni tekur það aðeins við nýjum línum.

Að lesa núverandi skrár

Segjum að við séum að setja af stað logstash í fyrsta skipti, en við höfum nú þegar logstash og viljum gjarnan vinna úr þeim.
Ef við keyrum logstash með inntakshlutanum sem við notuðum hér að ofan, fáum við ekkert. Aðeins nýjar línur verða unnar af logstash.

Til þess að hægt sé að draga línur úr núverandi skrám upp ættir þú að bæta við viðbótarlínu við innsláttarhlutann:

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

Þar að auki er blæbrigði: þetta hefur aðeins áhrif á nýjar skrár sem logstash hefur ekki enn séð. Fyrir sömu skrár sem þegar voru á sjónsviði logstash, hefur það þegar munað stærð þeirra og mun nú aðeins taka nýjar færslur í þær.

Stoppum hér og lærum inntakshlutann. Það eru enn margir möguleikar, en það er nóg fyrir okkur fyrir frekari tilraunir í bili.

Leiðbeiningar og gagnabreyting

Við skulum reyna að leysa eftirfarandi vandamál, segjum að við höfum skilaboð frá einni rás, sum þeirra eru til upplýsinga og önnur eru villuboð. Þeir eru mismunandi eftir merki. Sum eru INFO, önnur eru VILLA.

Við þurfum að aðskilja þá við útganginn. Þeir. Við skrifum upplýsingaskilaboð í eina rás og villuboð í aðra.

Til að gera þetta skaltu fara úr inntakshlutanum yfir í síun og úttak.

Með því að nota síuhlutann munum við flokka skilaboðin sem berast, fá kjötkássa (key-value pör) úr því, sem við getum nú þegar unnið með, þ.e. taka í sundur eftir aðstæðum. Og í framleiðsluhlutanum munum við velja skilaboð og senda hvert og eitt á sína eigin rás.

Að flokka skilaboð með grok

Til þess að flokka textastrengi og fá sett af reitum úr þeim er sérstakt tappi í síuhlutanum - grok.

Án þess að setja mér það markmið að gefa nákvæma lýsingu á því hér (fyrir þetta vísa ég til opinber skjöl), Ég skal gefa einfalda dæmið mitt.

Til að gera þetta þarftu að ákveða snið inntaksstrenganna. Ég á þær svona:

1 UPPLÝSINGARskilaboð1
2 VILLUskilaboð2

Þeir. Auðkennið kemur fyrst, svo INFO/VILLA, svo eitthvað orð án bils.
Það er ekki erfitt, en það er nóg til að skilja meginregluna um rekstur.

Svo, í síuhluta grok viðbótarinnar, verðum við að skilgreina mynstur til að flokka strengina okkar.

Það mun líta svona út:

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

Í meginatriðum er það venjuleg tjáning. Notuð eru tilbúin mynstur eins og INT, LOGLEVEL, WORD. Lýsingu þeirra, sem og önnur mynstur, má finna hér hér

Nú, þegar farið er í gegnum þessa síu, mun strengurinn okkar breytast í kjötkássa af þremur reitum: message_id, message_type, message_text.

Þeir munu birtast í framleiðsluhlutanum.

Senda skilaboð til úttakshluta með if skipuninni

Í framleiðsluhlutanum, eins og við munum, ætluðum við að skipta skilaboðunum í tvo strauma. Sumir - sem eru iNFO, verða sendar út á stjórnborðið og með villum munum við gefa út í skrá.

Hvernig aðskiljum við þessi skilaboð? Ástand vandamálsins bendir nú þegar til lausnar - þegar allt kemur til alls erum við nú þegar með sérstakan message_type reit, sem getur aðeins tekið tvö gildi: INFO og ERROR. Það er á þessum grundvelli sem við munum velja með því að nota ef yfirlýsinguna.

if [message_type] == "ERROR" {
        # Здесь выводим в файл
       } else
     {
      # Здесь выводим в stdout
    }

Lýsingu á vinnu með sviðum og rekstraraðilum er að finna í þessum hluta opinber handbók.

Nú, um raunverulega niðurstöðuna sjálfa.

Console framleiðsla, allt er á hreinu hér - stdout {}

En úttakið í skrá - mundu að við erum að keyra þetta allt úr gámi og til þess að skráin sem við skrifum niðurstöðuna í sé aðgengileg utan frá þurfum við að opna þessa möppu í docker-compose.yml.

Samtals:

Úttakshlutinn í skránni okkar lítur svona út:


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

Í docker-compose.yml bætum við við öðru bindi fyrir úttak:

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

Við ræsum það, prófum það og sjáum skiptingu í tvo strauma.

Heimild: www.habr.com

Bæta við athugasemd