Filebeat: Log Shipper ส่ง Logs ไป Elasticsearch

ในระบบที่ต้องส่ง logs จำนวนมากจากหลายเซิร์ฟเวอร์ไปเก็บที่ Elasticsearch ส่วนกลาง การเขียนสคริปต์ส่งเองหรือใช้ tool หนัก ๆ อย่าง Logstash บนทุกเครื่องไม่ใช่ทางเลือกที่ดี เพราะกิน resource และจัดการยาก — Filebeat จึงถูกออกแบบมาให้เป็น lightweight log shipper ที่รันบนเครื่อง source ได้อย่างเบาและเสถียร

Filebeat เป็นส่วนหนึ่งของ Elastic Beats family ที่เขียนด้วย Go มีขนาดเล็ก ใช้ RAM น้อย (มักไม่เกิน 50MB) และรองรับการส่ง logs ไป Elasticsearch, Logstash, หรือ Kafka ได้โดยตรง บทความนี้จะพาไปรู้จักการทำงาน, การตั้งค่า, module พร้อมใช้, และแนวทางการ deploy Filebeat ในระบบจริง

Filebeat ทำงานอย่างไร

Filebeat ทำงานด้วยสถาปัตยกรรมภายในประกอบด้วย 3 ส่วนหลัก — Input (อ่าน logs จาก source เช่น file, container, syslog), Processor (แปลงและ enrich event), และ Output (ส่งไปปลายทาง) โดยทุก event จะถูก track ด้วย registry file เพื่อให้ restart ได้โดยไม่ซ้ำหรือขาด

จุดเด่นคือ back-pressure mechanism — หาก output รับ event ไม่ทัน Filebeat จะชะลอการอ่านแทนการทิ้ง event ทำให้ไม่สูญเสียข้อมูลแม้ระบบปลายทางจะช้าลงชั่วคราว และยังรองรับ at-least-once delivery โดยยืนยัน acknowledgment จาก output ก่อนอัพเดต registry

การติดตั้งและโครงสร้าง Config

Filebeat ติดตั้งได้ง่ายผ่าน APT/YUM repository หรือ Docker image ไฟล์ config หลักอยู่ที่ /etc/filebeat/filebeat.yml ใช้ YAML format ซึ่งเขียนอ่านง่าย ตัวอย่าง config เบื้องต้นสำหรับส่ง Nginx access log ไปยัง Elasticsearch:

filebeat.inputs:
  - type: filestream
    id: nginx-access
    enabled: true
    paths:
      - /var/log/nginx/access.log
    fields:
      service: nginx
      env: production
    fields_under_root: true

processors:
  - add_host_metadata: ~
  - add_cloud_metadata: ~

output.elasticsearch:
  hosts: ["http://es-01:9200", "http://es-02:9200"]
  index: "nginx-access-%{+yyyy.MM.dd}"
  username: "filebeat_writer"
  password: "${ES_PASSWORD}"

Input type filestream เป็นรุ่นใหม่กว่า log ที่ถูก deprecate ไป รองรับ state tracking ที่ดีกว่าและเร็วกว่า สำหรับ environment variable ใน config สามารถใช้รูปแบบ ${VAR_NAME} ได้ทั้ง password, URL, หรือ path

Processors — Enrich และ Transform Event

Processor ทำงานหลังจาก input อ่าน event แต่ก่อนส่งไป output เพื่อ enrich หรือ transform ข้อมูล Processor ยอดนิยมที่ใช้บ่อย:

  • add_host_metadata — เพิ่มข้อมูล hostname, OS, architecture ของเครื่องที่ส่ง
  • add_cloud_metadata — เพิ่ม metadata ของ cloud provider (AWS, GCP, Azure) อัตโนมัติ
  • add_kubernetes_metadata — enrich ด้วย pod name, namespace, labels เมื่อรันบน K8s
  • drop_event — ทิ้ง event ที่ตรงเงื่อนไข เช่น health check, debug log
  • drop_fields / rename / copy_fields — จัดรูป field ก่อนส่ง
  • script — ใช้ JavaScript สำหรับ logic ซับซ้อน

การใช้ processor ที่ดีช่วยลดภาระของ Elasticsearch เช่นการ drop health check logs ทำให้ index เล็กลง และการ add_kubernetes_metadata ช่วยให้ query log ตาม pod/namespace ได้ทันทีใน Kibana โดยไม่ต้อง correlate เอง

Modules — Config พร้อมใช้สำหรับบริการยอดนิยม

Filebeat มี modules สำเร็จรูปสำหรับบริการยอดนิยม เช่น Nginx, Apache, MySQL, MongoDB, Kafka, PostgreSQL แต่ละ module มี config, ingest pipeline, Kibana dashboard และ index template พร้อมใช้ — ลดเวลา setup จากหลายชั่วโมงเหลือไม่กี่นาที

# เปิดใช้งาน module
filebeat modules enable nginx mysql system

# ตรวจสอบ module ที่เปิดอยู่
filebeat modules list

# Setup index template + dashboard ใน Kibana
filebeat setup

# Run
systemctl restart filebeat

หลังเปิด module และรัน setup จะได้ dashboard สำเร็จรูปใน Kibana ที่แสดง access log, error rate, top URL, response time breakdown แบบ out-of-the-box เหมาะสำหรับทีมที่ต้องการเริ่มใช้งานเร็วโดยไม่ต้องสร้าง visualization เอง

Deploy Filebeat บน Kubernetes

วิธีที่นิยมที่สุดคือ deploy เป็น DaemonSet ให้ Filebeat ทำงานบนทุก node อ่าน container logs จาก /var/log/containers/ และ enrich ด้วย Kubernetes metadata อัตโนมัติ — ทำให้ทุก log จาก pod ใดก็ตาม มี pod name, namespace, labels ติดไปด้วย ไม่ต้อง config แยกต่อ service

filebeat.autodiscover:
  providers:
    - type: kubernetes
      node: ${NODE_NAME}
      hints.enabled: true
      hints.default_config:
        type: container
        paths:
          - /var/log/containers/*${data.kubernetes.container.id}.log

processors:
  - add_kubernetes_metadata:
      host: ${NODE_NAME}
      matchers:
        - logs_path:
            logs_path: "/var/log/containers/"

output.elasticsearch:
  hosts: ["elasticsearch.logging:9200"]

Feature hints.enabled ช่วยให้ pod ระบุ config ได้จาก annotation ใน manifest เอง เช่น co.elastic.logs/enabled: "true" หรือ co.elastic.logs/module: "nginx" ทำให้ config ส่วนกลางไม่ต้องรู้รายละเอียดของแต่ละ pod

Best Practices สำหรับงาน Production

  • ใช้ filestream input แทน log ที่ deprecated แล้ว
  • เปิด queue.disk สำหรับ buffer บน disk ป้องกัน event loss เมื่อ output ล่ม
  • ใช้ dedicated user ของ Elasticsearch ที่มีสิทธิ์เฉพาะ index ที่จำเป็น ไม่ใช้ superuser
  • Monitor Filebeat ด้วย xpack.monitoring หรือ Prometheus exporter เพื่อติดตาม lag และ dropped events
  • ตั้ง harvester_limit หาก host มี log file จำนวนมาก ป้องกัน file descriptor exhaustion
  • กำหนด scan_frequency ให้สั้นสำหรับ log ที่เขียนเร็ว ยาวสำหรับ log ที่เขียนช้า เพื่อลด CPU overhead

สรุป

Filebeat เป็น log shipper ที่เบา เร็ว และเสถียร เหมาะกับการ deploy บน host จำนวนมากโดยไม่กิน resource ของ application server จุดเด่นอยู่ที่ module สำเร็จรูป การ integrate กับ Elastic Stack ได้ smooth และรองรับ environment ตั้งแต่ VM เดี่ยวไปจนถึง Kubernetes cluster ขนาดใหญ่

สำหรับองค์กรที่ใช้ ELK/Elastic Stack เป็น centralized logging การเริ่มต้นจาก Filebeat บน host เป็นแนวทางที่ปลอดภัยและมีประสิทธิภาพที่สุด ขยายไปใช้ module และ autodiscover เมื่อ infrastructure ซับซ้อนขึ้น จะช่วยให้ทีม ops ดูแล log pipeline ได้โดยไม่ต้องเขียน integration เอง