การแนะนำ
ในขณะที่ปรับใช้ระบบอื่น เราต้องเผชิญกับความจำเป็นในการประมวลผลบันทึกต่างๆ จำนวนมาก ELK ได้รับเลือกให้เป็นเครื่องดนตรี บทความนี้จะพูดถึงประสบการณ์ของเราในการตั้งค่ากองนี้
เราไม่ได้กำหนดเป้าหมายเพื่ออธิบายความสามารถทั้งหมด แต่เราต้องการเน้นที่การแก้ปัญหาในทางปฏิบัติ นี่เป็นเพราะเอกสารจำนวนมากเพียงพอและรูปภาพสำเร็จรูปมีข้อผิดพลาดมากมายอย่างน้อยเราก็พบพวกเขา
เราปรับใช้สแต็คผ่านนักเทียบท่า-เขียน ยิ่งไปกว่านั้น เรามี docker-compose.yml ที่เขียนอย่างดีซึ่งทำให้เราสามารถเพิ่มสแต็คได้โดยแทบไม่มีปัญหา และดูเหมือนว่าชัยชนะใกล้เข้ามาแล้วสำหรับเรา ตอนนี้เราจะบิดเล็กน้อยเพื่อให้เหมาะกับความต้องการของเรา แค่นั้น
น่าเสียดายที่ความพยายามปรับแต่งระบบเพื่อรับและประมวลผลบันทึกจากแอปพลิเคชันของเราไม่สำเร็จในทันที ดังนั้นเราจึงตัดสินใจว่าควรศึกษาแต่ละองค์ประกอบแยกกันแล้วกลับไปที่การเชื่อมต่อ
เรามาเริ่มกันที่ logstash
สภาพแวดล้อม การปรับใช้ การเรียกใช้ Logstash ในคอนเทนเนอร์
สำหรับการปรับใช้ เราใช้ docker-compose การทดลองที่อธิบายไว้ที่นี่ดำเนินการบน MacOS และ Ubuntu 18.0.4
อิมเมจ logstash ที่เรามีใน docker-compose.yml ดั้งเดิมคือ docker.elastic.co/logstash/logstash:6.3.2
เราจะใช้สำหรับการทดลอง
ในการเรียกใช้ logstash เราได้เขียน docker-compose.yml แยกต่างหาก แน่นอน มันเป็นไปได้ที่จะเปิดอิมเมจจากบรรทัดคำสั่ง แต่หลังจากนั้น เราได้แก้ไขงานเฉพาะซึ่งทุกอย่างตั้งแต่นักเทียบท่า-คอมโพสิทถูกเปิดใช้งานสำหรับเรา
สั้น ๆ เกี่ยวกับไฟล์คอนฟิกูเรชัน
จากคำอธิบายต่อไปนี้ สามารถเรียกใช้ logstash เป็นหนึ่งแชนเนล ซึ่งในกรณีนี้จำเป็นต้องถ่ายโอนไฟล์ *.conf หรือสำหรับหลายแชนเนล ซึ่งในกรณีนี้จำเป็นต้องถ่ายโอนไฟล์ไปป์ไลน์.yml ซึ่งในทางกลับกัน จะอ้างถึงไฟล์ .conf สำหรับแต่ละช่อง
เราใช้เส้นทางที่สอง ดูเหมือนว่าเราจะมีความหลากหลายและปรับขนาดได้มากขึ้น ดังนั้นเราจึงสร้างไปป์ไลน์ .yml และสร้างไดเร็กทอรีไปป์ไลน์ที่เราจะใส่ไฟล์ .conf สำหรับแต่ละแชนเนล
ภายในคอนเทนเนอร์มีไฟล์กำหนดค่าอื่น - logstash.yml เราไม่ได้สัมผัสมัน เราใช้มันตามที่เป็นอยู่
โครงสร้างไดเร็กทอรีของเราคือ:
ในขณะนี้ เราถือว่านี่คือ tcp บนพอร์ต 5046 เพื่อรับข้อมูลอินพุต และเราจะใช้ stdout สำหรับเอาต์พุต
นี่คือการกำหนดค่าอย่างง่ายสำหรับการรันครั้งแรก เพราะงานเริ่มต้นคือการเปิดตัว
ดังนั้นเราจึงมี 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
เราเห็นอะไรที่นี่?
- เครือข่ายและไดรฟ์ข้อมูลนำมาจาก docker-compose.yml ดั้งเดิม (อันที่เปิดตัวสแต็กทั้งหมด) และฉันคิดว่าสิ่งเหล่านี้ไม่ส่งผลกระทบต่อภาพรวมที่นี่มากนัก
- เราสร้าง logstash หนึ่งบริการ (บริการ) จากอิมเมจ docker.elastic.co/logstash/logstash:6.3.2 และตั้งชื่อว่า logstash_one_channel
- เรากำลังส่งต่อพอร์ต 5046 ภายในคอนเทนเนอร์ไปยังพอร์ตภายในเดียวกัน
- เราแมปไฟล์คอนฟิกูเรชันไปป์ ./config/pipelines.yml กับไฟล์ /usr/share/logstash/config/pipelines.yml ภายในคอนเทนเนอร์ ซึ่ง logstash จะรับไฟล์และทำให้เป็นแบบอ่านอย่างเดียว ในกรณีนี้
- เราแมปไดเร็กทอรี ./config/pipelines ซึ่งเรามีไฟล์คอนฟิกูเรชันไปป์ กับไดเร็กทอรี /usr/share/logstash/config/pipelines และทำให้เป็นแบบอ่านอย่างเดียว
ไฟล์ piping.yml
- pipeline.id: HABR
pipeline.workers: 1
pipeline.batch.size: 1
path.config: "./config/pipelines/habr_pipeline.conf"
ซึ่งอธิบายช่องทางหนึ่งที่มีตัวระบุ HABR และพาธไปยังไฟล์คอนฟิกูเรชัน
และสุดท้ายไฟล์ "./config/pipelines/habr_pipeline.conf"
input {
tcp {
port => "5046"
}
}
filter {
mutate {
add_field => [ "habra_field", "Hello Habr" ]
}
}
output {
stdout {
}
}
เราจะไม่อธิบายในตอนนี้ เราพยายามเรียกใช้:
docker-compose up
เราเห็นอะไร
คอนเทนเนอร์เริ่มทำงานแล้ว เราสามารถตรวจสอบการทำงานของมันได้:
echo '13123123123123123123123213123213' | nc localhost 5046
และเราเห็นการตอบสนองในคอนเทนเนอร์คอนโซล:
แต่ในขณะเดียวกัน เรายังเห็น:
logstash_one_channel | [2019-04-29T11:28:59,790][ERROR][logstash.licensechecker.licensereader] ไม่สามารถดึงข้อมูลใบอนุญาตจากเซิร์ฟเวอร์ใบอนุญาต {:message=>"Elasticsearch ไม่สามารถเข้าถึง: [http://elasticsearch:9200/][Manticore ::ResolutionFailure]elasticsearch", ...
logstash_one_channel | [2019-04-29T11:28:59,894][INFO ][logstash.pipeline ] ไปป์ไลน์เริ่มต้นเรียบร้อยแล้ว {:pipeline_id=>".monitoring-logstash", :thread=>"# »}
logstash_one_channel | [2019-04-29T11:28:59,988][INFO ][logstash.agent ] ไปป์ไลน์ที่ทำงาน {: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 แต่ไม่ได้อยู่ใน Elasticsearch โปรดติดตั้ง X-Pack บน Elasticsearch เพื่อใช้คุณลักษณะการตรวจสอบ อาจมีคุณสมบัติอื่นๆ
logstash_one_channel | [2019-04-29T11:29:00,526][INFO ][logstash.agent ] เริ่มต้นจุดสิ้นสุด Logstash API สำเร็จแล้ว {:port=>9600}
logstash_one_channel | [2019-04-29T11:29:04,478][INFO ][logstash.outputs.elasticsearch] กำลังตรวจสอบความสมบูรณ์เพื่อดูว่าการเชื่อมต่อของ Elasticsearch ทำงานอยู่หรือไม่ {:healthcheck_url=>http://elasticsearch:9200/, :path=> "/"}
logstash_one_channel | [2019-04-29T11:29:04,487][WARN ][logstash.outputs.elasticsearch] พยายามคืนชีพการเชื่อมต่อกับอินสแตนซ์ ES ที่ไม่ทำงาน แต่พบข้อผิดพลาด {:url=>"
logstash_one_channel | [2019-04-29T11:29:04,704][INFO ][logstash.licensechecker.licensereader] กำลังตรวจสอบความสมบูรณ์เพื่อดูว่าการเชื่อมต่อของ Elasticsearch ทำงานอยู่หรือไม่ {:healthcheck_url=>http://elasticsearch:9200/, :path=> "/"}
logstash_one_channel | [2019-04-29T11:29:04,710][WARN ][logstash.licensechecker.licensereader] พยายามคืนชีพการเชื่อมต่อกับอินสแตนซ์ ES ที่ไม่ทำงาน แต่ได้รับข้อผิดพลาด {:url=>"
และบันทึกของเราก็รวบรวมข้อมูลตลอดเวลา
ที่นี่ฉันเน้นข้อความสีเขียวว่าไปป์ไลน์เริ่มต้นสำเร็จ สีแดงคือข้อความแสดงข้อผิดพลาด และสีเหลืองคือข้อความเกี่ยวกับการพยายามติดต่อ
สิ่งนี้เกิดขึ้นเนื่องจากใน logstash.conf ที่รวมอยู่ในรูปภาพมีการตรวจสอบความพร้อมใช้งานของการค้นหาแบบยืดหยุ่น ท้ายที่สุดแล้ว logstash ถือว่ามันทำงานเป็นส่วนหนึ่งของ Elk stack และเราแยกมันออกจากกัน
ทำงานได้แต่ไม่สะดวก
วิธีแก้ไขคือปิดใช้งานการตรวจสอบนี้ผ่านตัวแปรสภาพแวดล้อม XPACK_MONITORING_ENABLED
มาทำการเปลี่ยนแปลง 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
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
ตอนนี้ทุกอย่างเรียบร้อยดี ภาชนะพร้อมสำหรับการทดลอง
เราสามารถพิมพ์อีกครั้งในคอนโซลที่อยู่ติดกัน:
echo '13123123123123123123123213123213' | nc localhost 5046
และดู:
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 | }
ทำงานภายในช่องทางเดียว
ดังนั้นเราจึงเริ่มต้น ตอนนี้คุณสามารถใช้เวลาในการกำหนดค่า logstash ได้โดยตรง ตอนนี้อย่าเพิ่งแตะต้องไฟล์pipelines.yml มาดูกันว่าเราจะได้อะไรจากการทำงานกับหนึ่งช่องสัญญาณ
ฉันต้องบอกว่าหลักการทั่วไปของการทำงานกับไฟล์การกำหนดค่าช่องนั้นอธิบายไว้อย่างดีในคู่มืออย่างเป็นทางการที่นี่
หากคุณต้องการอ่านเป็นภาษารัสเซีย เราใช้สิ่งนี้
ไปตามลำดับจากส่วนอินพุต เราได้เห็นการทำงานบน tcp แล้ว มีอะไรน่าสนใจอีกบ้างที่นี่?
ทดสอบข้อความโดยใช้การเต้นของหัวใจ
มีความเป็นไปได้ที่น่าสนใจในการสร้างข้อความทดสอบอัตโนมัติ
ในการทำเช่นนี้ คุณต้องรวมปลั๊กอิน heartbean ไว้ในส่วนอินพุต
input {
heartbeat {
message => "HeartBeat!"
}
}
เราเปิดใช้งานเราเริ่มได้รับนาทีละครั้ง
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 | }
เราต้องการรับบ่อยขึ้นเราต้องเพิ่มพารามิเตอร์ช่วงเวลา
นี่คือวิธีที่เราจะได้รับข้อความทุกๆ 10 วินาที
input {
heartbeat {
message => "HeartBeat!"
interval => 10
}
}
รับข้อมูลจากไฟล์
เราตัดสินใจดูโหมดไฟล์ด้วย หากทำงานได้ดีกับไฟล์ ก็เป็นไปได้ว่าไม่จำเป็นต้องใช้เอเจนต์ อย่างน้อยก็สำหรับการใช้งานในเครื่อง
ตามคำอธิบาย โหมดการทำงานควรคล้ายกับ tail -f นั่นคือ อ่านบรรทัดใหม่หรืออ่านไฟล์ทั้งหมด
ดังนั้นสิ่งที่เราต้องการได้รับ:
- เราต้องการรับบรรทัดที่ต่อท้ายไฟล์บันทึกหนึ่งไฟล์
- เราต้องการรับข้อมูลที่เขียนลงในล็อกไฟล์หลายๆ ไฟล์ ในขณะที่สามารถแยกข้อมูลที่ได้รับจากที่ใดได้
- เราต้องการให้แน่ใจว่าเมื่อรีสตาร์ท logstash จะไม่ได้รับข้อมูลนี้อีก
- เราต้องการตรวจสอบว่าหากปิดใช้งาน logstash และข้อมูลยังคงถูกเขียนลงในไฟล์ เมื่อเราเรียกใช้ เราจะได้รับข้อมูลนี้
ในการดำเนินการทดสอบ ให้เพิ่มอีกหนึ่งบรรทัดใน 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
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
และเปลี่ยนส่วนอินพุตใน habr_pipeline.conf
input {
file {
path => "/usr/share/logstash/input/*.log"
}
}
เราเริ่ม:
docker-compose up
ในการสร้างและเขียนไฟล์บันทึก เราจะใช้คำสั่ง:
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 | }
ใช่มันใช้งานได้!
ในเวลาเดียวกัน เราเห็นว่าเราได้เพิ่มช่องเส้นทางโดยอัตโนมัติ ดังนั้นในอนาคต เราจะสามารถกรองบันทึกตามนั้น
ลองอีกครั้ง:
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 | }
และตอนนี้ไปที่ไฟล์อื่น:
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 | }
ยอดเยี่ยม! ไฟล์ถูกหยิบขึ้นมา, เส้นทางถูกระบุอย่างถูกต้อง, ทุกอย่างเรียบร้อยดี.
หยุด logstash และเริ่มต้นใหม่ มารอกัน ความเงียบ. เหล่านั้น. เราไม่ได้รับบันทึกเหล่านี้อีก
และตอนนี้เป็นการทดลองที่กล้าหาญที่สุด
เราใส่ logstash และดำเนินการ:
echo '3' >> logs/number2.log
echo '4' >> logs/number1.log
เรียกใช้ logstash อีกครั้งและดู:
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 | }
ไชโย! ทุกอย่างหยิบขึ้นมา
แต่จำเป็นต้องเตือนเกี่ยวกับสิ่งต่อไปนี้ หากนำคอนเทนเนอร์ logstash ออก (นักเทียบท่าหยุด logstash_one_channel && นักเทียบท่า rm logstash_one_channel) จะไม่มีการดึงข้อมูลใดๆ ตำแหน่งของไฟล์ที่อ่านถูกเก็บไว้ภายในคอนเทนเนอร์ หากคุณเริ่มต้นจากศูนย์ ระบบจะยอมรับเฉพาะการขึ้นบรรทัดใหม่เท่านั้น
อ่านไฟล์ที่มีอยู่
สมมติว่าเรากำลังเรียกใช้ logstash เป็นครั้งแรก แต่เรามีบันทึกอยู่แล้วและต้องการประมวลผล
ถ้าเราเรียกใช้ logstash ด้วยส่วนอินพุตที่เราใช้ด้านบน เราจะไม่ได้อะไรเลย เฉพาะการขึ้นบรรทัดใหม่เท่านั้นที่จะถูกประมวลผลโดย logstash
ในการดึงบรรทัดจากไฟล์ที่มีอยู่ ให้เพิ่มบรรทัดเพิ่มเติมในส่วนอินพุต:
input {
file {
start_position => "beginning"
path => "/usr/share/logstash/input/*.log"
}
}
ยิ่งไปกว่านั้น มีความแตกต่างกันเล็กน้อย ซึ่งมีผลเฉพาะกับไฟล์ใหม่ที่ logstash ยังไม่เห็นเท่านั้น สำหรับไฟล์เดิมที่อยู่ในมุมมองของ logstash ไฟล์ได้จำขนาดไว้แล้วและตอนนี้จะรับเฉพาะบันทึกใหม่เท่านั้น
เรามาหยุดกันโดยศึกษาส่วนอินพุต มีตัวเลือกเพิ่มเติมมากมาย แต่สำหรับตอนนี้ เรามีเพียงพอสำหรับการทดลองเพิ่มเติม
การกำหนดเส้นทางและการแปลงข้อมูล
ลองแก้ปัญหาต่อไปนี้ สมมติว่าเรามีข้อความจากช่องทางหนึ่ง บางข้อความเป็นข้อมูล และบางข้อความเป็นข้อความแสดงข้อผิดพลาด พวกเขาแตกต่างกันในแท็ก บางตัวเป็น INFO บางตัวเป็น ERROR
เราต้องแยกกันที่ทางออก เหล่านั้น. เราเขียนข้อความแสดงข้อมูลในช่องหนึ่ง และข้อความแสดงข้อผิดพลาดในอีกช่องหนึ่ง
ในการดำเนินการนี้ ให้เปลี่ยนจากส่วนอินพุตเป็นตัวกรองและเอาต์พุต
เมื่อใช้ส่วนตัวกรอง เราจะแยกวิเคราะห์ข้อความขาเข้า รับแฮช (คู่คีย์-ค่า) จากมัน ซึ่งเราสามารถทำงานได้แล้ว เช่น แยกวิเคราะห์ตามเงื่อนไข และในส่วนเอาต์พุต เราจะเลือกข้อความและส่งแต่ละรายการไปยังช่องของตัวเอง
แยกวิเคราะห์ข้อความด้วย grok
ในการแยกวิเคราะห์สตริงข้อความและรับชุดฟิลด์จากสตริงเหล่านั้น มีปลั๊กอินพิเศษอยู่ในส่วนตัวกรอง - grok
โดยไม่ตั้งเป้าหมายที่จะให้คำอธิบายโดยละเอียดที่นี่ (สำหรับสิ่งนี้ฉันหมายถึง
ในการทำเช่นนี้คุณต้องตัดสินใจเลือกรูปแบบของบรรทัดอินพุต ฉันมีพวกเขาเช่นนี้:
1 ข้อความ INFO1
2 ข้อความผิดพลาด2
เหล่านั้น. ตัวระบุก่อน ตามด้วย INFO/ERROR จากนั้นบางคำที่ไม่มีช่องว่าง
ไม่ยากแต่พอเข้าใจหลักการทำงาน
ดังนั้น ในส่วนตัวกรอง ในปลั๊กอิน grok เราจำเป็นต้องกำหนดรูปแบบสำหรับแยกวิเคราะห์สตริงของเรา
มันจะมีลักษณะดังนี้:
filter {
grok {
match => { "message" => ["%{INT:message_id} %{LOGLEVEL:message_type} %{WORD:message_text}"] }
}
}
โดยพื้นฐานแล้ว มันเป็นนิพจน์ทั่วไป ใช้รูปแบบสำเร็จรูป เช่น INT, LOGLEVEL, WORD สามารถดูคำอธิบายและรูปแบบอื่นๆ ได้ที่นี่
เมื่อผ่านตัวกรองนี้ สตริงของเราจะกลายเป็นแฮชของสามฟิลด์: message_id, message_type, message_text
พวกเขาจะแสดงในส่วนผลลัพธ์
กำหนดเส้นทางข้อความในส่วนเอาต์พุตด้วยคำสั่ง if
ในส่วนเอาต์พุต อย่างที่เราจำได้ เราจะแบ่งข้อความออกเป็นสองสตรีม บางอย่าง - ซึ่งเป็น iNFO เราจะส่งออกไปยังคอนโซล และเมื่อมีข้อผิดพลาด เราจะส่งออกไปยังไฟล์
เราจะแบ่งปันข้อความเหล่านี้ได้อย่างไร? เงื่อนไขของปัญหาแนะนำวิธีแก้ไขแล้ว - เรามีฟิลด์ message_type เฉพาะอยู่แล้วซึ่งสามารถรับเพียงสองค่า INFO และ ERROR อยู่ที่ว่าเราจะเลือกใช้คำสั่ง if
if [message_type] == "ERROR" {
# Здесь выводим в файл
} else
{
# Здесь выводим в stdout
}
คำอธิบายของงานกับฟิลด์และตัวดำเนินการสามารถพบได้ในส่วนนี้
ตอนนี้เกี่ยวกับข้อสรุปของตัวเอง
เอาต์พุตคอนโซล ทุกอย่างชัดเจนที่นี่ - stdout {}
แต่ผลลัพธ์ไปยังไฟล์ - จำไว้ว่าเรากำลังเรียกใช้ทั้งหมดนี้จากคอนเทนเนอร์ และเพื่อให้ไฟล์ที่เราเขียนผลลัพธ์สามารถเข้าถึงได้จากภายนอก เราจำเป็นต้องเปิดไดเร็กทอรีนี้ใน docker-compose.yml
รวม:
ส่วนผลลัพธ์ของไฟล์ของเรามีลักษณะดังนี้:
output {
if [message_type] == "ERROR" {
file {
path => "/usr/share/logstash/output/test.log"
codec => line { format => "custom format: %{message}"}
}
} else
{stdout {
}
}
}
เพิ่มโวลุ่มอีกหนึ่งรายการใน 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
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
เราเริ่มต้น เราพยายาม เราเห็นการแบ่งออกเป็นสองกระแส
ที่มา: will.com