จัดการกับ log ด้วยเทคโนโลยี ELK stack

Tangmo Saengsala

Overview
โดยทั่วไปแล้วเวลาเกิดเหตุการณ์ผิดปกติที่โปรแกรมหรือต้องการตรวจสอบอะไรบางอย่าง สิ่งแรกที่นักพัฒนาจำเป็นต้องดูและตรวจสอบนั้นคือ log message ของโปรแกรม แล้วถ้า log message นั้นอยู่ที่ server production ล่ะ ซึ่งหลายทีมก็อาจจะไม่มีสิทธิ์เข้าถึง server production ก็ต้องไปทำเรื่องของดูไฟล์ log อีกต่าง ๆ นา ๆ หรือถ้า server มีเป็นร้อยๆเครื่องล่ะมันดูเหมือนต้องไปงมเข็มในมหสมุทเลยเนอะ งั้นถ้าเรามีเว็บดู log message ได้เลยจะสะดวกขึ้นไหม แน่นอนว่าต้องสะดวกขึ้นสิ… และด้วยเทคโนโลยี ELK stack นี่ล่ะจะมาช่วยให้งานงมเข็มในมหสมุทนั้นเป็นเรื่องง่ายขึ้น

Kibana

Tools Preparation
-
Docker
- Git client
- IDE
( eclipse หรือ IntelliJ ) ขึ้นอยู่กับเราว่าชอบใช้ตัวไหน
- *optional สำหรับนักพัฒนาที่ไม่ถนัดการใช้งาน command prompt ของ windows
แนะนำให้ลองใช้โปรแกรม Cygwin ดูนะครับ เป็นซอฟต์แวร์สำหรับจำลอง Environment ของ Linux บนเครื่อง Windows และยังสามารถลง package เพิ่มได้*

Let’s get started.

สร้าง log ไฟล์เตรียมไว้พ่นขึ้น ELK stack
เริ่มต้นด้วยการสร้าง Project ที่เขียน log ลงไฟล์ ในบทความนี้ขอให้ภาษา java ครับ
เพื่อความสะดวกและรวดเร็วสามารถ clone project มาลองเล่นดูตามนี้

$ git clone https://github.com/saengsala/logback-demo-log.git
Project Structure
  • configure logback
    การที่ application จะสามารถเขียน log ลงไฟล์นั้นเราจะใช้ slf4j library โดยต้องสร้าง logback configuration file ไว้ที่ folder resources ชื่อไฟล์ logback.xml ซึ่งในการ config นี้เราสามารถกำหนดได้ว่าจะให้ไฟล์ log ของเรานั้นมีการ rolling ไฟล์ไหม เช่น ไฟล์ log ของเราถ้ามีขนาดกี่ MB ถึงจะต้อง zip ไฟล์ หรือ ต้องการ zip ไฟล์ log ในแต่ละวัน แล้วแต่เราจะ config ให้เป็นแบไหน
ตัวอย่าง config logback ให้มีการrollingไฟล์ทุกๆนาที โดยเก็บไฟล์ไว้มากที่สุด 5 ไฟล์

...
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>
log/backup/logback-demo-log-%d{yyyyMMddHHmm}.log.zip
</fileNamePattern>
<maxHistory>5</maxHistory>
</rollingPolicy>
...

logback.xml

  • สร้าง main class
    จากที่ configure logback เราจะได้ไฟล์ log ของ application ชื่อว่า logback-demo-log.log ซึ่งจะถูกเขียนไว่ที่ folder log
log level ที่ใช้กันบ่อยๆlogger.debug("User id {} has successfully logged in.", i);
logger.info("User id {} entered the password incorrectly.", i);
logger.error("feature login error may be due to network problems");

main class

ไฟล์ log ของ application

ติดตั้ง ELK stack
EKL stack นี้จะประกอบด้วย Elasticsearch, Logstash และ Kibana และยังเป็น Open Source อีกด้วยในบทความนี้ขอติดตั้งโดยใช้ Docker เข้ามาช่วยเพื่อจะได้ไม่ต้อง Install หลาย srevice ซึ่งจะเริ่มต้นด้วยการสร้าง folder elk ใน project log ของเราเลยดังนี้

Docker ELK Structure
  • หลักการทำงานของ ELK stack
    เริ่มจาก fileBeat จะเก็บรวบรวม log file ของเราแล้วก็ส่งไปให้กับ logstash หลังจากนั้น Logstash จะทำการ filters และวิเคราห์ข้อมูลเพื่อทำการเปลี่ยนแปลงแล้วสร้าง output ส่งต่อไปให้กับ elasticsearch ซึ่งเป็น storage แสดงว่า kibana ของเรานั้นก็จะเปรียบเสมือน User Interface ค่อยดึงข้อมูลจาก elasticsearch ไปแสดงบนหน้าเว็บให้ดูเข้าใจง่ายนั้นเอง
การทำงาน ELK stack

configure ELK

  • filebeat.yml
    ไฟล์ที่มีนาสกุล .log ทั้งหมดที่ path /usr/share/filebeat/logs/ (เป็น path ของ containerใน docker) และมีการอ่านค่าในไฟล์เรื่อยๆ เมื่อมีการเขียน log ลงไฟล์ใหม่ แล้วจะส่งข้อมูลที่ได้ไปให้กับ logstash
filebeat.prospectors:
- type: log
enabled: true
paths:
- "/usr/share/filebeat/logs/*.log"
tail_files: true

output.logstash:
hosts:
"logstash:5000"
  • logstash.conf
    ในการนำเข้าข้อมูลจะรับค่ามาจาก filebeat แล้วนำไปทำการ filter ข้อมูลด้วย plugins ที่ชื่อว่า grok ซึ่ง grok ตัวนี้แหละ จะทำการเปลี่ยนแปลงข้อมูล log message ของเราให้อยู่ในรูปแบบ json จากนั้นก็ส่งไปเก็บไว้ที่ storage elasticsearch
input {
beats {
port => 5000
type => syslog
codec => plain { charset => "UTF-8" }
}
}

## Add your filters / logstash plugins configuration here
filter {
grok {
match => {"message" => "%{DATA:activityTimeStamp} \| \[%{DATA:thread}\] \| %{DATA:level} \| %{DATA:class} \| %{DATA:function} \| - %{GREEDYDATA:activityMessage}"}
}
}

output {
elasticsearch {
hosts => "elasticsearch:9200"
}
}
  • grok patterns
    เราสามารถศึกษาและทดลอง mapping log message ได้จากเว็บ grokdebug และจาก project log ของเรานั้นเราจะได้ log message ดังนี้
- log message
2019-02-24 08:00:05 | [main] | ERROR | com.logback.LogbackRollingExample | demoLogError | - feature login error may be due to network problems
- grok patterns
%{DATA:activityTimeStamp} \| \[%{DATA:thread}\] \| %{DATA:level} \| %{DATA:class} \| %{DATA:function} \| - %{GREEDYDATA:activityMessage}
grok debugger
  • elasticsearch.yml
    ตัว elasticsearch นี้เราจะไม่ได้ config อะไรมาก ซึ่งจะกำหนดค่าตาม default
---
## Default Elasticsearch configuration from elasticsearch-docker.
cluster.name: "docker-cluster"
network.host: 0.0.0.0
discovery.zen.minimum_master_nodes: 1
discovery.type: single-node
  • kibana.yml
    Kibana ที่ทำหน้าที่เป็น User Interface ก็จะเป็นการเอาข้อมูลจาก elasticsearch ขึ้นมาโชว์ที่หน้าเว็บ
---
## Default Kibana configuration from kibana-docker.
server.name: kibana
server.host: "0"
elasticsearch.url: http://elasticsearch:9200
  • docker-compose.yml
    เป็นการกำหนดว่าให้อ่านไฟล์ config service ต่างๆ จาก path ไหน และเป็นตัว download images เพื่อสร้าง container กำหนด port ทำให้ container สามารถคุยกันได้พร้อมกับตั้งชื่อ container ให้อัตโนมัติ

มาทดลองจัดการกับ log ด้วยเทคโนโลยี ELK stack กันเลย

เปิด Terminal หรือ Cygwin แล้วไปที่ path elk แล้วทำการรัน docker compose

$ cd elk
$ docker-compose up

เมื่อ docker ทำการ download images และสร้าง container ให้เราเรียบร้อยแล้วให้เราทำการ run main class เพื่อทำการเขียน log ลงไฟล์

Open browser: http://localhost:5601

จะเห็นหน้าเว็บ Kibana ให้เราทำการเลือก Set up index patterns

kibana web

create index pattern ตรง index name ให้ใส่คำว่า logstash* แล้วกด next step

create index pattern

step 2 ให้เลือกเป็น timestamp แล้วกด create index pattern ได้เลย

เสร็จแล้วให้เลือกไปที่เมนู Discover ก็จะเห็นหน้าเว็บที่แสดง log message ตามเวลาและสามารถค้นหาได้ตามต้องการ

Reference
https://www.elastic.co/products/kiban
https://www.elastic.co/products/elasticsearch
https://www.elastic.co/products/logstash
https://www.elastic.co/products/beats
https://grokdebug.herokuapp.com/

Tangmo Saengsala

Written by

I'm Mo. Please feel free to your comments or suggestions.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade