Aplikasi praktis ELK. Nyetél logstash

perkenalan

Nalika nyebarkeun sistem anu sanés, kami kedah ngolah sajumlah ageung log anu béda. ELK dipilih salaku alat. Artikel ieu bakal ngabahas pangalaman urang dina nyetel tumpukan ieu.

Kami henteu netepkeun tujuan pikeun ngajelaskeun sadaya kamampuanna, tapi kami hoyong konsentrasi khusus pikeun ngarengsekeun masalah praktis. Ieu alatan kanyataan yén sanajan aya jumlah cukup badag dokuméntasi jeung gambar siap-dijieun, aya cukup loba pitfalls, sahenteuna urang kapanggih aranjeunna.

Urang nyebarkeun tumpukan via docker-compose. Leuwih ti éta, urang kungsi well-ditulis docker-compose.yml, nu diwenangkeun urang pikeun ngangkat tumpukan ampir tanpa masalah. Sareng sigana ka urang yén kameunangan parantos caket, ayeuna urang bakal ngarobih sakedik pikeun nyocogkeun ka kabutuhan urang sareng éta.

Hanjakalna, usaha pikeun ngonpigurasikeun sistem pikeun nampi sareng ngolah log tina aplikasi kami henteu langsung suksés. Kituna, urang mutuskeun yén éta patut diajar unggal komponén nyalira, lajeng balik deui ka sambungan maranéhanana.

Janten, urang mimitian ku logstash.

Lingkungan, deployment, ngajalankeun Logstash dina hiji wadah

Pikeun panyebaran kami nganggo docker-compose; percobaan anu dijelaskeun di dieu dilaksanakeun dina MacOS sareng Ubuntu 18.0.4.

Gambar logstash anu didaptarkeun dina docker-compose.yml asli kami nyaéta docker.elastic.co/logstash/logstash:6.3.2

Urang bakal ngagunakeun éta pikeun ékspérimén.

Urang nulis docker-compose.yml misah pikeun ngajalankeun logstash. Tangtosna, éta mungkin pikeun ngaluncurkeun gambar tina garis paréntah, tapi kami ngarengsekeun masalah khusus, dimana urang ngajalankeun sadayana tina docker-compose.

Sakeudeung ngeunaan file konfigurasi

Sapertos ieu tina pedaran, logstash tiasa dijalankeun boh pikeun hiji saluran, dina hal éta kedah ngaliwat file *.conf, atanapi pikeun sababaraha saluran, dina hal éta kedah ngalangkungan file pipelines.yml, anu, giliran. , bakal numbu ka file .conf pikeun tiap channel.
Urang nyandak jalur kadua. Ieu seemed kami leuwih universal tur scalable. Kituna, urang dijieun pipelines.yml, sarta dijieun diréktori pipelines nu urang bakal nempatkeun file .conf pikeun tiap channel.

Di jero wadahna aya file konfigurasi anu sanés - logstash.yml. Kami henteu nyabak, kami nganggo sakumaha anu aya.

Janten, struktur diréktori kami:

Aplikasi praktis ELK. Nyetél logstash

Pikeun nampi data input, ayeuna urang nganggap yén ieu tcp dina port 5046, sareng pikeun kaluaran kami bakal nganggo stdout.

Ieu konfigurasi basajan pikeun peluncuran munggaran. Kusabab tugas awal nyaéta ngaluncurkeun.

Janten, urang gaduh docker-compose.yml ieu

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

Naon anu urang tingali di dieu?

  1. Jaringan sareng jilid dicandak tina docker-compose.yml aslina (hiji dimana sadayana tumpukan diluncurkeun) sareng kuring nyangka yén aranjeunna henteu mangaruhan pisan kana gambar sadayana di dieu.
  2. Urang nyieun hiji jasa logstash (s) tina docker.elastic.co/logstash/logstash:6.3.2 gambar jeung ngaran eta logstash_one_channel.
  3. Urang teruskeun port 5046 jero wadahna, ka port internal sarua.
  4. Urang petakeun file konfigurasi pipa kami ./config/pipelines.yml kana file /usr/share/logstash/config/pipelines.yml di jero wadahna, dimana logstash bakal ngajemput sareng ngajantenkeun ngan ukur dibaca, bisi waé.
  5. Urang petakeun diréktori ./config/pipelines, dimana urang gaduh file sareng setélan saluran, kana diréktori /usr/share/logstash/config/pipelines sareng ogé ngajantenkeun éta ngan ukur dibaca.

Aplikasi praktis ELK. Nyetél logstash

Pipelines.yml file

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

Hiji saluran sareng identifier HABR sareng jalur ka file konfigurasina dijelaskeun di dieu.

Sareng tungtungna file "./config/pipelines/habr_pipeline.conf"

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

Hayu urang henteu lebet kana pedaranana pikeun ayeuna, cobian ngajalankeunana:

docker-compose up

Naon anu urang tingali?

Wadahna parantos ngamimitian. Urang tiasa pariksa operasi na:

echo '13123123123123123123123213123213' | nc localhost 5046

Sareng urang ningali réspon dina konsol wadahna:

Aplikasi praktis ELK. Nyetél logstash

Tapi dina waktos anu sami, urang ogé ningali:

logstash_one_channel | [2019-04-29T11:28:59,790][ERROR][logstash.licensechecker.licensereader] Teu bisa meunangkeun informasi lisénsi ti server lisénsi {: message => "Elasticsearch Unreachable: [http://elasticsearch:9200/][Manticore ::ResolutionFailure] elasticsearch", ...

logstash_one_channel | [2019-04-29T11:28:59,894][INFO ][logstash.pipeline] Pipa dimimitian suksés {:pipeline_id =>".monitoring-logstash", :thread=>"# "}

logstash_one_channel | [2019-04-29T11:28:59,988][INFO ][logstash.agent ] Pipelines ngajalankeun {: count=>2, :running_pipelines =>[:HABR, :".monitoring-logstash"], :non_running_pipelines=>[ ]}
logstash_one_channel | [2019-04-29T11: 29: 00,015, XNUMX] [ERROR] [logstash.inputs.metrics] X-Pack dipasang dina Logstash tapi henteu dina Elasticsearch. Punten pasang X-Pack dina Elasticsearch pikeun ngagunakeun fitur ngawaskeun. fitur sejenna bisa jadi sadia.
logstash_one_channel | [2019-04-29T11:29:00,526][INFO ][logstash.agent ] Geus hasil ngamimitian Logstash API endpoint {:port=>9600}
logstash_one_channel | [2019-04-29T11:29:04,478] [INFO] [logstash.outputs.elasticsearch] Ngajalankeun pamariksaan kaséhatan pikeun ningali naha sambungan Elasticsearch berpungsi {:healthcheck_url=>http: //elasticsearch:9200/,:path=> "/"}
logstash_one_channel | [2019-04-29T11: 29: 04,487, XNUMX] [PERINGATAN] [logstash.outputs.elasticsearch] Diusahakeun pikeun ngahirupkeun deui sambungan kana conto ES anu maot, tapi ngagaduhan kasalahan. {:url =>"élastis: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] Ngajalankeun pamariksaan kaséhatan pikeun ningali naha sambungan Elasticsearch berpungsi {:healthcheck_url=>http://elasticsearch:9200/,:path=> "/"}
logstash_one_channel | [2019-04-29T11: 29: 04,710, XNUMX] [PERINGATAN] [logstash.licensechecker.licensereader] Diusahakeun pikeun ngahirupkeun deui sambungan kana conto ES maot, tapi ngagaduhan kasalahan. {:url =>"élastis:9200/", :error_type=>LogStash::Outputs::ElasticSearch::HttpClient::Pool::HostUnreachableError,:error=>"Elasticsearch Unreachable: [http://elasticsearch:9200/][Manticore::ResolutionFailure] elasticsearch"}

Jeung log kami creeping up sadaya waktu.

Di dieu kuring parantos nyorot dina héjo pesen yén pipa parantos suksés diluncurkeun, beureum pesen kasalahan sareng konéng pesen ngeunaan usaha ngahubungi élastis: 9200.
Ieu kajadian sabab logstash.conf, kaasup dina gambar, ngandung cek pikeun kasadiaan elasticsearch. Barina ogé, logstash nganggap yén gawéna salaku bagian tina tumpukan Elk, tapi urang dipisahkeun.

Ieu mungkin pikeun digawé, tapi teu merenah.

Solusina nyaéta nganonaktipkeun cék ieu via variabel lingkungan XPACK_MONITORING_ENABLED.

Hayu urang parobihan kana docker-compose.yml sareng jalankeun deui:

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

Ayeuna, sagalana geus rupa. Wadahna siap pikeun ékspérimén.

Urang tiasa ngetik deui dina konsol salajengna:

echo '13123123123123123123123213123213' | nc localhost 5046

Sareng tingali:

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

Gawé dina hiji saluran

Ku kituna urang dibuka. Ayeuna anjeun leres-leres tiasa nyandak waktos pikeun ngonpigurasikeun logstash sorangan. Hayu urang henteu noél file pipelines.yml pikeun ayeuna, hayu urang tingali naon anu urang tiasa kéngingkeun ku damel sareng hiji saluran.

Kuring kudu nyebutkeun yén prinsip umum gawé bareng file konfigurasi channel ogé digambarkeun dina manual resmi, Ieuh di dieu
Upami anjeun hoyong maca dina basa Rusia, kami nganggo ieu artikel(tapi sintaksis query aya heubeul, urang kudu tumut kana akun).

Hayu urang balik sequentially tina bagian Input. Kami parantos ningali padamelan dina TCP. Naon sejenna bisa jadi metot di dieu?

Uji pesen nganggo ketak jantung

Aya kasempetan anu pikaresepeun pikeun ngahasilkeun pesen uji otomatis.
Jang ngalampahkeun ieu, anjeun kedah ngaktipkeun plugin heartbean dina bagian input.

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

Hurungkeun, mimitian nampa sakali menit

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

Upami urang hoyong nampi langkung sering, urang kedah nambihan parameter interval.
Ieu kumaha urang bakal nampi pesen unggal 10 detik.

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

Retrieving data tina file

Urang ogé mutuskeun pikeun nempo mode file. Lamun gawéna rupa kalawan file, lajeng sugan euweuh agén diperlukeun, sahenteuna pikeun pamakéan lokal.

Numutkeun katerangan, mode operasi kedah sami sareng buntut -f, i.e. maca garis anyar atawa, salaku pilihan, maca sakabéh file.

Janten naon anu urang hoyong kéngingkeun:

  1. Simkuring hoyong nampi garis nu appended kana hiji file log.
  2. Kami hoyong nampi data anu diserat kana sababaraha file log, bari tiasa misahkeun naon anu ditampi ti mana.
  3. Kami hoyong mastikeun yén nalika logstash di-restart, éta henteu nampi data ieu deui.
  4. Kami hoyong pariksa yén upami logstash dipareuman, sareng data terus diserat kana file, teras nalika kami ngajalankeun éta, kami bakal nampi data ieu.

Pikeun ngalaksanakeun ékspérimén, hayu urang tambahkeun garis sanés ka docker-compose.yml, muka diréktori dimana urang nempatkeun file.

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

Jeung ngarobah bagian input dina habr_pipeline.conf

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

Hayu urang mimitian:

docker-compose up

Pikeun nyieun sareng nyerat file log kami bakal nganggo paréntah:


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

Yep, éta jalan!

Dina waktu nu sarua, urang nempo yén urang geus otomatis ditambahkeun widang jalur. Ieu ngandung harti yén dina mangsa nu bakal datang, urang bakal bisa nyaring rékaman ku eta.

Hayu urang cobian deui:

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

Sareng ayeuna kana file anu sanés:

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

Hebat! Filena dijemput, jalurna parantos leres, sadayana saé.

Ngeureunkeun logstash tur mimitian deui. Hayu urang antosan. tiiseun. Jelema. Kami henteu nampi rékaman ieu deui.

Tur ayeuna percobaan paling wani.

Pasang logstash sareng laksanakeun:

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

Jalankeun logstash deui sareng tingali:

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

Horeeee! Sagalana dipulut.

Tapi urang kudu ngingetkeun anjeun ngeunaan handap. Upami wadahna nganggo logstash dihapus (docker stop logstash_one_channel && docker rm logstash_one_channel), teras teu aya anu bakal diangkat. Posisi file anu dibacana disimpen di jero wadahna. Lamun ngajalankeun eta ti scratch, éta ngan bakal nampa garis anyar.

Maca file anu aya

Anggap urang ngaluncurkeun logstash pikeun kahiji kalina, tapi urang parantos ngagaduhan log sareng urang hoyong ngolahna.
Lamun urang ngajalankeun logstash kalawan bagian input kami dipaké di luhur, urang moal meunang nanaon. Ngan baris anyar bakal diolah ku logstash.

Supaya garis tina file anu tos aya ditarik ka luhur, anjeun kedah nambihan garis tambahan kana bagian input:

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

Leuwih ti éta, aya nuansa: ieu ngan mangaruhan file anyar nu logstash teu acan katempo. Pikeun file anu sami anu parantos aya dina widang panempoan logstash, éta parantos émut ukuranana sareng ayeuna ngan ukur nyandak éntri énggal di jerona.

Hayu urang eureun di dieu sarta diajar bagian input. Masih aya seueur pilihan, tapi éta cekap pikeun urang pikeun ékspérimén salajengna ayeuna.

Routing sarta Transformasi Data

Hayu urang cobaan pikeun ngajawab masalah di handap ieu, hayu urang nyebutkeun aya pesen ti hiji saluran, sababaraha di antarana mangrupa informasi, sarta sababaraha pesen kasalahan. Aranjeunna béda ku tag. Sababaraha INFO, batur ERROR.

Urang kedah misahkeun aranjeunna di jalan kaluar. Jelema. Kami nyerat pesen inpormasi dina hiji saluran, sareng pesen kasalahan dina saluran anu sanés.

Jang ngalampahkeun ieu, pindah ti bagian input pikeun nyaring jeung kaluaran.

Ngagunakeun bagian filter, urang bakal parse pesen asup, meunangkeun hash (pasangan konci-nilai) ti dinya, nu urang geus bisa dianggo kalayan, i.e. ngabongkar nurutkeun kaayaan. Sareng dina bagian kaluaran, urang bakal milih pesen sareng ngirim masing-masing ka saluran sorangan.

Parsing pesen ku grok

Dina raraga parse string téks tur meunangkeun sakumpulan widang ti aranjeunna, aya hiji plugin husus dina bagian filter - grok.

Tanpa netepkeun tujuan kuring pikeun masihan katerangan lengkep ngeunaan éta di dieu (kanggo ieu kuring ngarujuk kana dokuméntasi resmi), Kuring gé masihan conto basajan kuring.

Jang ngalampahkeun ieu, anjeun kudu mutuskeun dina format string input. Abdi gaduh aranjeunna sapertos kieu:

1 talatah INFO1
2 talatah ERROR2

Jelema. Identifier asalna heula, teras INFO / ERROR, teras sababaraha kecap tanpa spasi.
Teu hese, tapi cukup ngartos prinsip operasi.

Ku kituna, dina bagian filter tina plugin grok, urang kudu nangtukeun pola pikeun parsing string urang.

Ieu bakal kasampak kawas kieu:

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

Intina éta éksprési biasa. Pola anu siap dianggo dianggo, sapertos INT, LOGLEVEL, WORD. Katerangan maranéhanana, kitu ogé pola séjén, bisa kapanggih di dieu di dieu

Ayeuna, ngaliwatan saringan ieu, string urang bakal robah jadi hash tina tilu widang: message_id, message_type, message_text.

Aranjeunna bakal dipintonkeun dina bagian kaluaran.

Routing pesen ka bagian kaluaran ngagunakeun paréntah if

Dina bagian kaluaran, sakumaha urang émut, urang badé ngabagi pesen kana dua aliran. Sababaraha - anu iNFO, bakal kaluaran kana konsol, sareng kalayan kasalahan, urang bakal kaluaran kana file.

Kumaha urang misahkeun pesen ieu? Kaayaan masalah geus nunjukkeun solusi - sanggeus kabeh, urang geus boga husus message_type widang, nu ngan bisa nyandak dua nilai: INFO na ERROR. Dina dasar ieu urang bakal nyieun pilihan ngagunakeun pernyataan if.

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

Katerangan ngeunaan gawé bareng widang sareng operator tiasa dipendakan dina bagian ieu manual resmi.

Ayeuna, ngeunaan kacindekan sabenerna sorangan.

Kaluaran konsol, sadayana jelas di dieu - stdout {}

Tapi kaluaran kana file - inget yen urang ngajalankeun sagala ieu tina wadahna sarta dina urutan pikeun file nu urang nulis hasilna bisa diasupan ti luar, urang kudu muka diréktori ieu docker-compose.yml.

total:

Bagian kaluaran file kami katingalina kieu:


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

Dina docker-compose.yml kami nambihan volume anu sanés pikeun kaluaran:

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

Urang ngajalankeun eta, coba eta, tur tingal division kana dua aliran.

sumber: www.habr.com

Tambahkeun komentar