0

Ghi chép về Logstash (P1): Logstash Pipeline

Chia sẻ
  • 517 0
 Xuất bản thg 9 17, 2019 2:42 SA 517 0 0 0
  • 517 0

1. Logstash là gì?

Logstash là một engine mã nguồn mở cho phép thu thập dữ liệu theo thời gian thực. Chúng ta có thể Logstash đóng vai trò "data shipper" - trạm trung chuyển của dữ liệu.

Trong ELK stack, Logstash được kết hợp với Elasticsearch và Kibana:

Để cài đặt Logstash chúng ta thực hiện như sau:

Bước 1: Download và giải nén thư mục cài đặt Logstash từ https://www.elastic.co/downloads/logstash.

Bước 2: Chuẩn bị một file logstash.conf đặt trong thư mục cài đặt Logtash.

Ví dụ:

input { stdin { } }
output {
  elasticsearch { hosts => ["localhost:9200"] }
  stdout { codec => rubydebug }
}

Các bạn có thể tham khảo thêm về file logstash.conf tại đây.

Bước 3: Chạy lệnh bin/logstash -f logstash.conf để khởi động Logstash.

Logstash API mặc định chạy ở cổng 9600.

Đây là output sau khỉ khởi động Logstash:

$ bin/logstash -f logstash.conf
Thread.exclusive is deprecated, use Thread::Mutex
Sending Logstash logs to /home/yuen/logstash/logs which is now configured via log4j2.properties
[2019-09-17T09:57:34,125][WARN ][logstash.config.source.multilocal] Ignoring the 'pipelines.yml' file because modules or command line options are specified
[2019-09-17T09:57:34,146][INFO ][logstash.runner          ] Starting Logstash {"logstash.version"=>"7.3.1"}
[2019-09-17T09:57:35,844][INFO ][org.reflections.Reflections] Reflections took 46 ms to scan 1 urls, producing 19 keys and 39 values 
[2019-09-17T09:57:36,843][WARN ][org.logstash.instrument.metrics.gauge.LazyDelegatingGauge] A gauge metric of an unknown type (org.jruby.RubyArray) has been create for key: cluster_uuids. This may result in invalid serialization.  It is recommended to log an issue to the responsible developer/development team.
[2019-09-17T09:57:36,846][INFO ][logstash.javapipeline    ] Starting pipeline {:pipeline_id=>"main", "pipeline.workers"=>4, "pipeline.batch.size"=>125, "pipeline.batch.delay"=>50, "pipeline.max_inflight"=>500, :thread=>"#<Thread:0x13a39f9a run>"}
[2019-09-17T09:57:36,928][INFO ][logstash.javapipeline    ] Pipeline started {"pipeline.id"=>"main"}
The stdin plugin is now waiting for input:
[2019-09-17T09:57:37,001][INFO ][logstash.agent           ] Pipelines running {:count=>1, :running_pipelines=>[:main], :non_running_pipelines=>[]}
[2019-09-17T09:57:37,209][INFO ][logstash.agent           ] Successfully started Logstash API endpoint {:port=>9600}

2. Tổng quan về Logstash pipeline

Luồng dữ liệu đi qua Logstash sẽ được xử lý theo cơ chế pipeline. Để tăng performance, pipeline sẽ được phân bổ trên nhiều worker. Mỗi worker sẽ chạy bên trong thread riêng của mình.

Pipeline gồm có 3 stage (giai đoạn): input → filter → output.

  1. Input: trong stage này, dữ liệu từ các source sẽ được Logstash chuyển thành các event. Mỗi một input stage sẽ chạy bên trong thread riêng của mình, và ghi các event vào trong một queue trung tâm nằm trong bộ nhớ (mặc định) hoặc ổ cứng. Trong queue này, các event sẽ được đóng gói thành các batch.
  2. Filter: trong stage này, các worker thread sẽ lấy các batch ra khỏi queue. Sau đó tùy theo filter mà chỉnh sửa nội dung của các event.
  3. Output: trong stage này, các worker thread sẽ chuyển các event tới các destination.

Input và output còn hỗ trợ codec cho phép encode và decode dữ liệu mà không cần phải thông qua filter. Trong một pipeline, chúng ta có thể sử dụng một hoặc kết hợp nhiều input/filter/output/codec.

Ví dụ: Trong một hệ thống Microservice, chúng ta sẽ sử dụng Logstash để thu thập log từ các service (input), sau đó thống nhất thành 1 chuẩn (filter) và chuyển cho Elasticsearch để tập trung và phân tích log (output).

Có một lưu ý là, nếu các event được lưu bên trong bộ nhớ thì khi Logstash bị dừng một cách đột ngột, các event sẽ biến mất. Để tránh gặp phải tình trạng này, chúng ta có thể chuyển sang lưu event trong ổ cứng. Các bạn có thể tham khảo thêm tại đây.


3. Plugin

Trong mỗi stage của pipeline, chúng ta sẽ tích hợp một hoặc nhiều plugin. Plugin có thể hiểu là các tiện ích mà Logstash cung cấp để chúng ta thu thập và xử lý dữ liệu dễ dàng và linh hoạt hơn.

Mỗi plugin lại có nhiều setting để cấu hình. Setting cũng có name và value.

Ví dụ: Chúng ta thường sử dụng plugin file trong input stage để thu thập dữ liệu từ file log.

input {
    file {
        path => "/path/to/20190914.log"
        start_position => beginning
        ignore_older => 0
    }
}

Trong plugin file, chúng ta đã cấu hình 3 setting là path, start_positionignore_order.


4. Event

Trong phần trước chúng ta đã nhắc đến event. Vậy thực chất event là gì?

Event là một đối tượng chính trong Logstash, được dùng để đóng gói dữ liệu. Event bao gồm dữ liệu gốc được gửi tới Logstash + các dữ liệu khác do Logstash tạo ra trong filter stage.

Ví dụ: Khi Logstash đọc một file log, mỗi dòng trong file log sẽ được đóng gói thành một event.

{
      "@version" => "1",
       "message" => "2019-09-17 10:54:43.019  INFO 15705 --- [main] com.example.demo.DemoApplication         : Started DemoApplication in 2.363 seconds (JVM running for 3.205)",
    "@timestamp" => 2019-09-17T01:54:52.160Z,
          "path" => "/tmp/test.log",
          "host" => "example"
}

Event cung cấp một API để các đối tượng bên ngoài (plugin và developer) tương tác với nội dung của event.


5. Event field

Mỗi một event bao gồm nhiều field. Field có name và value. Như ở ví dụ phần trước, chúng ta có các field là: path, message, @version, @timestamphost.

5.1. Field reference

Cú pháp cơ bản để truy cập một field là [field name].

Để tham chiếu tới một nested field, chúng ta chỉ định full path trỏ tới field đó: [top-level field name][nested field name].

Ví dụ:

Với event:

{
    "agent": "Mozilla/5.0 (compatible; MSIE 9.0)",
    "ip": "192.168.24.44",
    "request": "/index.html"
    "response": {
        "status": 200,
        "bytes": 52353
    },
    "ua": {
        "os": "Windows 7"
    }
}

Để truy cập field os, chúng ta sử dụng [ua][os].

5.2. Sprintf format

Sprintf format là tính năng cho phép truyền field reference vào trong string.

Cú pháp 1: %{field name}

Cú pháp 2: dành cho nested field: %{[top-level field name][nested field name]}

5.3. Conditional

if EXPRESSION {
    ...
} else if EXPRESSION {
    ...
} else {
    ...
}

EXPRESSION ở đây có thể là một phép so sánh hoặc logic, ...

Các toán tử có thể sử dụng là:

  • equality: ==, !=, <, >, <=, >=
  • regexp: =~, !~
  • inclusion: in, not in
  • boolean: and, or, nand, xor
  • unary: !

Ví dụ:

output {
    # Send production errors to pagerduty
    if [loglevel] == "ERROR" and [deployment] == "production" {
        pagerduty {
            ...
        }
    }
}

Chú ý: field reference, sprintf format và conditional dưới đây không thể sử dụng trong input.

5.4. @metadata field

Kể từ phiên bản Logstash 1.5 trở về sau, trong mỗi event có một field đặc biệt có tên là @metadata. Khi output, @metadata mặc định sẽ không nằm trong event (chúng ta cũng có thể cấu hình để @metadata xuất hiện trong event).

Ví dụ:

input { stdin { } }

filter {
    mutate { add_field => { "show" => "This data will be in the output" } }
    mutate { add_field => { "[@metadata][no_show]" => "This data will not be in the output" } }
}

output {
    if [@metadata][no_show] {
        stdout { codec => rubydebug }
    }
}

Nhập dòng text test log, chúng ta sẽ thấy console output như sau:

test log
{
      "@version" => "1",
          "show" => "This data will be in the output",
    "@timestamp" => 2019-09-17T00:58:55.160Z,
          "host" => "example",
       "message" => "test log"
}

Để show @metadata, chúng ta sửa lại khối output như sau:

output {
    if [@metadata][no_show] {
        stdout { codec => rubydebug { metadata => true } }
    }
}

Console output lúc này:

test log
{
    "@timestamp" => 2019-09-17T01:05:23.168Z,
     "@metadata" => {
        "no_show" => "This data will not be in the output"
    },
          "show" => "This data will be in the output",
          "host" => "example",
      "@version" => "1",
       "message" => "test log"
}

6. Các kiểu dữ liệu của field/setting value

Dưới đây mình sẽ liệt kê một số kiểu dữ liệu thường gặp của field/setting value:

6.1. String

start_position => "beginning"

6.2. Number

Bao gồm cả số integer và floating point.

port => 33

6.3. Boolean

ssl_enable => true

6.4. Codec

Danh sách codec: https://www.elastic.co/guide/en/logstash/current/codec-plugins.html

codec => "json"

6.5. Array

ids => [1, 2]
names => ["bob", "jane"]
users => [{id => 1, name => bob}, {id => 2, name => jane}]

6.6. Hash

Hash là một tập các cặp key-value có định dạng là "field" => "value". Cần chú ý, các cặp key-value này không ngăn cách nhau bởi dấu phẩy.

match => {
  "field1" => "value1"
  "field2" => "value2"
  ...
}

6.7. URI

my_uri => "http://foo:bar@example.net"

6.8. Path

my_path => "/tmp/logstash"
Chia sẻ

NỘI DUNG


Series này không có bất kỳ bài đăng nào
Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí