Tracking và Analyzing ứng dụng bằng ELK Stack

Chuyện kể về vào một ngày đẹp trời đâu đó ở những ngày cuối năm 2018, tôi vẫn đang vui đùa, dong chơi (thật ra là đang fix bugs thấy ..) với các đồng nghiệp fucking awesome developer thân thiết trong công ty rồi bất chợt tôi nhận được một email báo cáo về lỗi xảy ra và yêu cầu giải quyết gấp trong ngày. Sau khi phân tích report được nhận tôi tự nhận mình là Thám tử lừng danh Sherlock Home tiến hành điều tra lỗi xảy ra ở đâu để tiến HÀNH ăn hành sấp mặt tiếp :(.

Tôi đã lục tung mọi ngóc ngách của log, từ log network tới log server, từ accesslog tới mainlog từ app khách hàng tới app mình, từ server khách hàng đến server mình. Dùng tài năng phân tích tài ba của mình để dựng lên một cách sinh động các tình huống có thể xảy ra lỗi quái quỷ này.
Và sau tất cả dữ kiện tôi thu thập được bằng cách rút trích, suy đoán, mail qua, mail lại giữa các bên liên quan thì tôi đã rút kết luận cần phải có sự phối hợp của các cấp chính quyền để
giải quyết triệt để vấn đề này là phải làm công cụ để theo dõi các flow (luồng đi) của user để biết user bị drop ở bước nào ở trên ứng dụng của mình, từ đó để có số liệu thông kê và cải tiến sản phẩm

Hành trình tới với ELK

Hiện tại khi có vấn đề trên ứng dụng của chúng tôi hiện đang phụ thuộc chủ yếu bằng log file và database mặc dù log ở phía server rất đầy đủ nhưng ở phía client: sdk mobile, app, web thì lại không. Nó được đẩy sang ở Google và Facebook Analytics.

Hai phần server và client đôi lúc sẽ không liên kết được với nhau và có khó là không liên quan gì cả.
Tôi thì thường tin log server hơn là vì do chính tôi code nên tôi hoàn toàn tin tưởng :p
(Đến đây em xin lỗi mấy anh xung quanh)

Hơn nữa có những thông tin quan trọng và nhảy cảm không được để cho những công cụ ngoại bang khác biết được như thông tin user, giao dịch.
Công cụ ngoại bang ở đây có thể là Google, Fb, các tool tracking ngoài công ty mình.

Trong lúc rối ren ấy tôi đã nhận sự giúp đỡ rất nhiệt tình từ hội những người già neo đơn SENIOR DEV đề xuất dùng thử ELK Stack

Và công cuộc R&D lại bắt đầu

1. ELK Stack là gì?

ELK Stack là bộ công cụ của Elastic, dùng để thu thập, lưu trữ và phân tích logging. Gồm 3 phần:

  • Logstash: Thu thập dữ liệu và xử lý log từ nhiều nguồn khác nhau: http, file log, kafka, rabbitMQ, v,v...
    Output của nó là là đẩy dữ liệu đã được xử lý vào thằng bên dưới (Elasticsearch).
  • Elasticsearch: Nơi để lưu trữ dữ liệu, truy vấn, tìm kiếm log.
  • Kibana: Phân tích, quản lý, hiển thị log lên giao diện.Dữ liệu được lấy từ thằng ở trên (Elasticsearch).

Bản chất ELK Stack là làm hệ thống logging nhưng chính vì khả năng visualize data như biểu đồ, đồ thị của Kibana (giống một phần như Facebook Analytics) và kèm theo là trace log cụ thể 1 request đang đi như thế nào nên mình đã biến tấu thành hệ thống tracking riêng cho hệ sinh thái gồm nhiều loại ứng dụng mình, mở rộng ra những hệ thống khác: insight :D

2. Cài đặt ELK

Link xXx phút ở đây:

Mình nghĩ chỉ cần theo dõi những bước hướng dẫn ở trang chính thức của cái thằng làm ra nó là có thể cài đặt được chúng rồi, vì chúng cực kỳ dễ hiểu, còn lại là do cơ địa của mỗi người, do ăn ở ra sao mà ra bugs như vậy.
Cơ mà cũng là cái duyên, chúng ta lại có cơ hội để ghé thăm người bạn già StackOverFlow để nói chuyện

Dành cho ai đó là tín đồ của Docker hoặc ít nhiều biết về nó: Chỉ cần pull một cái image về và run nó là được :xD

Link 22 phút: https://elk-docker.readthedocs.io/ hoặc link 8 phút : https://medium.com/tech-tajawal/elk-stack-docker-playground-for-devops-221179ca00dd

Mình đã thử và sấp mặt vì không config được http cho logstash
vì phải config cho cả docker nữa. Một ngày chủ nhật buồn

3. Cấu hình Logstash

Vì mình dùng brew mac để cài đặt cho cả bộ nên cấu trúc chứa source sẽ như thế này

cd /usr/local/etc/logstash`
vim logstash.conf

Ở đây mình sử dụng http để gửi event tới logstash
Nên cấu hình đơn giản như thế này:

input { 
  http {
    port => "8081" // Port của Logstash để nhận http request
    type => "analytics" // Kiểu data: Đại loại là để phân loại dữ liệu
  }
}

filter {
  // Đơn giản nên không cần phải làm filter làm gì cả :xD
}
output { // Sau khi có output thì làm gì?
  elasticsearch {
    hosts => ["127.0.0.1:9200"]  // Gửi dữ liệu lên elasticsearch
  }
  stdout { codec => rubydebug } // Bật chế độ debug trên console
}

Khởi động logstash

logstash -f logstash.conf

Gửi thử 1 event tới logstash

Screen-Shot-2018-12-26-at-10.42.20-PM

4. Gửi event từ client lên logstash

Client ở đây có thể là mobile app, browers, service khác
Ở đây mình không để mobile app và browser giao tiếp trực tiếp với logstash mà thông qua service khác, rồi để service đó giao tiếp với logstash thông qua giao thức http.
Còn service khác thì sẽ gửi event bằng Kafka, RabbitMQ, hoặc đọc file log tùy theo những thứ hiện có để tránh gây ra nhiều rắc rối sau này


Những thứ bất chạy ổn thì đừng đụng vào

Điều quan trọng là định nghĩa được các tham số của event cần được track lại

Ví dụ: Đây là event của mình

{
    "client": "mobileApp", //server, browser
    "eventId": "open_login_screen",
    "deviceInfo": {},
    "requestId": "1234567"
}

5. Phân tích và thông kê dữ liệu bằng Kibana

Cuối cùng là đây là phân mong đợi nhất, sau khi có data thì việc còn lại nó hiện thị nó như thế nào để dễ hiểu nhất.

Screen-Shot-2018-12-26-at-10.56.36-PM

Phần Discover cho phép xem event theo thời gian, hiện thị theo từng tham số trong event gửi lên

Screen-Shot-2018-12-26-at-11.01.39-PM

Phần Visualize cho phép tạo các biểu đồ theo dữ liệu được lưu trong Elasticsearch. Ở đây mình vẽ thử 1 cái biểu đồ đường thể hiện sự xuất hiện của các event theo requestId (unique)

Kibana said: "Xin lỗi anh chỉ là thằng hiển thị dữ liệu"

Tổng kết

Có 3 thứ phải làm để build hệ thống này:

  • Setup môi trường ELK Stack
  • Định nghĩa rõ các event
  • Dựng được biểu đồ mong muốn :xD

Everything will be 200 okey