Grafana Data Source: เชื่อมต่อ Prometheus และ Data Sources อื่น

Grafana เป็นเครื่องมือ visualization ที่ไม่ได้เก็บข้อมูลเอง แต่จะอ่านข้อมูลจากแหล่งข้อมูลภายนอกที่เรียกว่า Data Source การตั้งค่า Data Source อย่างถูกต้องจึงเป็นขั้นตอนแรกที่สำคัญที่สุดก่อนที่จะสร้าง Dashboard หรือ Alert ใด ๆ เพราะหากเชื่อมต่อผิดหรือตั้ง authentication ไม่ถูก ทุก panel จะแสดง error ทันที

บทความนี้จะอธิบายวิธีเชื่อมต่อ Prometheus เข้ากับ Grafana อย่างละเอียด พร้อมครอบคลุม Data Source อื่นที่นิยมใช้ เช่น Loki, InfluxDB, MySQL, PostgreSQL และ Elasticsearch รวมถึงวิธีจัดการ authentication, TLS, query timeout, และ template variables ข้ามหลาย data source

Data Source คืออะไร

Data Source คือการเชื่อมต่อระหว่าง Grafana กับระบบที่เก็บข้อมูลจริง เช่น time-series database, log database หรือ SQL database เมื่อผู้ใช้เปิด dashboard panel จะส่ง query ไปที่ data source แล้วรอ response กลับมาเพื่อ render เป็นกราฟ ถ้าไม่มี data source ที่ config ไว้ panel จะไม่มีข้อมูลให้แสดง

Grafana รองรับ Data Source หลายประเภทตั้งแต่ built-in plugin มาพร้อมตั้งแต่ติดตั้ง ไปจนถึง plugin ที่ต้องติดตั้งเพิ่มจาก Grafana plugin catalog บทความนี้เน้น built-in data sources ที่พบบ่อยที่สุดในระบบ production

Data Source ยอดนิยม

Data SourceประเภทUse Case
PrometheusTime-series (metrics)System/application metrics, alerting
LokiLog aggregationรวม logs จาก containers/services
InfluxDBTime-seriesIoT, sensor data, high-cardinality metrics
ElasticsearchDocument storeFull-text search บน logs/events
MySQL/PostgreSQLRelational DBBusiness metrics, reporting data
TempoDistributed tracingติดตาม request ระหว่าง microservices
CloudWatchManaged (AWS)AWS resource metrics

เชื่อมต่อ Prometheus เข้ากับ Grafana

Prometheus เป็น data source ที่ใช้คู่กับ Grafana มากที่สุดในงาน monitoring ขั้นตอนการเชื่อมต่อผ่าน UI ทำได้ดังนี้:

  1. ล็อกอินเข้า Grafana ด้วยบัญชี admin
  2. ไปที่เมนู Connections → Data sources แล้วกดปุ่ม Add data source
  3. เลือก Prometheus จากรายการ
  4. กรอก URL ของ Prometheus server เช่น http://prometheus:9090 (ถ้าอยู่ใน Docker network เดียวกัน) หรือ http://10.0.0.5:9090 (ถ้าอยู่คนละเครื่อง)
  5. ตั้ง Access mode เป็น Server (default) — Grafana จะ proxy request ไป Prometheus ผ่าน backend
  6. กด Save & test เพื่อทดสอบการเชื่อมต่อ — ถ้าเห็น “Data source is working” แสดงว่าเสร็จแล้ว

Provisioning ผ่านไฟล์ YAML

สำหรับระบบ production ควรจัดการ data source ผ่าน Infrastructure as Code แทนการคลิกบน UI เพื่อให้ version controlled และ reproducible ได้ ไฟล์ provisioning ปกติจะอยู่ที่ /etc/grafana/provisioning/datasources/

apiVersion: 1

datasources:
  - name: Prometheus
    type: prometheus
    access: proxy
    url: http://prometheus:9090
    isDefault: true
    editable: false
    jsonData:
      timeInterval: 15s
      queryTimeout: 60s
      httpMethod: POST
      manageAlerts: true
      prometheusType: Prometheus
      prometheusVersion: 2.45.0

Option ที่ควรทราบ: timeInterval คือค่า default ของ $__interval ใน PromQL, httpMethod: POST แนะนำสำหรับ query ที่ยาวเกิน limit ของ URL, manageAlerts: true เปิดให้ Grafana Alerting อ่าน rule จาก Prometheus ได้

Authentication และความปลอดภัย

ในระบบ production endpoint ของ Prometheus หรือ data source อื่นไม่ควรเปิดให้ทุกคนเข้าถึงได้ การตั้ง authentication จะปกป้อง endpoint จากการ query ที่ไม่พึงประสงค์

Basic Auth

datasources:
  - name: Prometheus
    type: prometheus
    url: https://prometheus.example.com
    basicAuth: true
    basicAuthUser: grafana
    secureJsonData:
      basicAuthPassword: $PROM_BASIC_AUTH_PASSWORD

ใช้ environment variable แทนการ hard-code password ในไฟล์ — Grafana จะอ่าน $PROM_BASIC_AUTH_PASSWORD จาก environment ตอน start

TLS และ mTLS

datasources:
  - name: Prometheus
    type: prometheus
    url: https://prometheus.example.com
    jsonData:
      tlsAuth: true
      tlsAuthWithCACert: true
    secureJsonData:
      tlsCACert: |
        -----BEGIN CERTIFICATE-----
        ...
        -----END CERTIFICATE-----
      tlsClientCert: |
        -----BEGIN CERTIFICATE-----
        ...
        -----END CERTIFICATE-----
      tlsClientKey: |
        -----BEGIN PRIVATE KEY-----
        ...
        -----END PRIVATE KEY-----

เมื่อใช้ mTLS ทั้ง client (Grafana) และ server (Prometheus) ต้องมี certificate ที่เซ็นจาก CA เดียวกัน เหมาะกับสภาพแวดล้อม zero-trust ที่ต้องการยืนยันตัวตนทั้งสองฝั่ง

Bearer Token / OAuth

datasources:
  - name: Prometheus
    type: prometheus
    url: https://prometheus.example.com
    jsonData:
      httpHeaderName1: 'Authorization'
    secureJsonData:
      httpHeaderValue1: 'Bearer $PROM_TOKEN'

รูปแบบ header นี้ใช้กับ managed Prometheus หลายเจ้า เช่น Grafana Cloud, AWS Managed Prometheus หรือระบบที่ใช้ JWT/OAuth ในการยืนยันตัวตน

Loki (Logs)

datasources:
  - name: Loki
    type: loki
    access: proxy
    url: http://loki:3100
    jsonData:
      maxLines: 1000
      derivedFields:
        - datasourceUid: tempo-uid
          matcherRegex: 'trace_id=(\w+)'
          name: TraceID
          url: '$${__value.raw}'

Loki ใช้ LogQL ซึ่งคล้าย PromQL สำหรับ query logs — derivedFields ช่วยให้ Grafana ตรวจหา trace ID ใน log แล้วทำ link ไป Tempo ได้อัตโนมัติ ช่วยให้ correlate ระหว่าง log กับ trace ได้ในคลิกเดียว

MySQL / PostgreSQL

datasources:
  - name: PostgreSQL
    type: postgres
    url: postgres:5432
    user: grafana_reader
    jsonData:
      database: analytics
      sslmode: require
      postgresVersion: 1500
      timescaledb: false
    secureJsonData:
      password: $POSTGRES_PASSWORD

สำหรับ SQL data source ควรสร้าง user แยกที่มีสิทธิ์ SELECT เท่านั้น — ห้ามใช้ user ที่มีสิทธิ์ INSERT/UPDATE/DELETE เพราะ Grafana อาจเผลอ execute query ที่มาจาก template variable แล้วแก้ไขข้อมูลได้

InfluxDB

datasources:
  - name: InfluxDB
    type: influxdb
    url: http://influxdb:8086
    jsonData:
      version: Flux
      organization: myorg
      defaultBucket: metrics
      tlsSkipVerify: false
    secureJsonData:
      token: $INFLUX_TOKEN

InfluxDB 2.x ใช้ Flux query language ต่างจาก 1.x ที่ใช้ InfluxQL — ตั้งค่า version: Flux เพื่อบอก Grafana ให้ใช้ syntax ใหม่

Query Options และ Timeout

Data source แต่ละตัวมี option เพิ่มเติมที่ส่งผลกับประสิทธิภาพและความเสถียรของ dashboard:

  • Scrape interval / timeInterval: ระยะห่างระหว่างจุดข้อมูล — ถ้าตั้งต่ำกว่า scrape interval จริงของ Prometheus จะเห็น gap บนกราฟ
  • Query timeout: ระยะเวลาสูงสุดที่รอ response — query ที่ใช้ข้อมูลย้อนหลัง 30 วันอาจต้องขยาย timeout ถึง 120s
  • HTTP method: POST ดีกว่า GET เมื่อ query ยาว เพราะ URL มี limit ~8KB
  • Custom HTTP headers: เพิ่ม header สำหรับ routing/multi-tenancy เช่น X-Scope-OrgID ที่ Mimir/Cortex ใช้
  • Exemplars: เปิดให้ Grafana ดึง sample trace จาก Prometheus แสดงบนกราฟเป็นจุด (ใช้คู่กับ Tempo)

การใช้ Data Source ใน Dashboard

เมื่อเพิ่ม data source เรียบร้อยแล้ว ทุก panel ใน dashboard จะมี dropdown ให้เลือก data source ที่ต้องการใช้ — panel เดียวกันสามารถใช้ data source ต่างชนิดได้ใน dashboard เดียว เช่น graph ซ้ายใช้ Prometheus อีกกราฟใช้ PostgreSQL

Default Data Source

กำหนด isDefault: true ใน provisioning YAML หรือเลือกใน UI เพื่อให้ panel ใหม่ทั้งหมดเริ่มด้วย data source นี้โดยอัตโนมัติ ลดขั้นตอนการสร้าง panel ใหม่ได้มาก

Mixed Data Source

Grafana มี built-in data source ชื่อ — Mixed — ที่ให้ใช้หลาย data source ใน panel เดียว เหมาะกับกราฟที่ต้อง overlay metric จาก Prometheus กับ event จาก PostgreSQL เช่น deploy marker หรือ business event

การจัดการ Data Source หลายตัว

ระบบ production มักมี data source หลายตัวแยกตาม environment หรือ region:

datasources:
  - name: Prometheus-Production
    type: prometheus
    url: http://prom-prod:9090
    uid: prom-prod
    isDefault: true
  - name: Prometheus-Staging
    type: prometheus
    url: http://prom-staging:9090
    uid: prom-staging
  - name: Prometheus-EU
    type: prometheus
    url: http://prom-eu:9090
    uid: prom-eu

ตั้ง uid ที่คงที่ (แทนการให้ Grafana generate UID แบบ random) เพื่อให้ dashboard export แล้ว import ไปที่อื่นยังหา data source ตัวเดิมเจอ — สำคัญมากเมื่อใช้ dashboard-as-code

Template Variable สำหรับเลือก Data Source

สามารถสร้าง variable ชนิด Data source เพื่อให้ผู้ใช้สลับ environment ได้จาก dropdown ที่ด้านบน dashboard โดยไม่ต้องแก้ panel:

  • สร้าง variable ชื่อ DS_PROM ประเภท Datasource
  • ตั้ง type filter เป็น prometheus
  • ใน panel ให้เลือก data source เป็น ${DS_PROM}

วิธีนี้ทำให้ dashboard เดียวใช้ได้กับทุก environment — เลือก Prometheus-Production หรือ Prometheus-Staging จาก dropdown แล้วกราฟจะเปลี่ยนตามทันที

Troubleshooting ปัญหาที่พบบ่อย

ปัญหาสาเหตุวิธีแก้
Data source is not workingURL ผิด / network ไม่ถึงทดสอบจากภายใน container: curl http://prometheus:9090/-/ready
401 UnauthorizedBasic auth credential ผิดตรวจ env var และ reload Grafana
TLS handshake failedCA cert ไม่ตรงหรือหมดอายุตรวจ expiry, ใช้ openssl s_client -connect host:port
Query timeoutข้อมูลเยอะเกิน / query ช้าเพิ่ม queryTimeout, ใช้ recording rule
High cardinality errorLabel มี value เยอะเกินลด label dimension หรือ filter ก่อน aggregate
Dashboard import แล้ว panel ว่างUID ไม่ตรงตั้ง uid คงที่ใน provisioning

Best Practices

  • ใช้ provisioning YAML แทน UI ในทุก environment ตั้งแต่ dev ถึง production — tracked ใน Git เปลี่ยนแปลงได้ทุกเมื่อ
  • ตั้ง editable: false ในไฟล์ provisioning เพื่อป้องกันผู้ใช้เผลอแก้ผ่าน UI
  • ใช้ environment variable สำหรับ password/token เสมอ — ห้ามเก็บ secret ลงไฟล์ YAML ตรง ๆ
  • ตั้ง uid ที่คงที่ทุก data source เพื่อให้ dashboard portable
  • แยก user database สำหรับ Grafana ที่มีสิทธิ์ read-only เท่านั้น
  • ตั้ง query timeout ที่สมเหตุสมผล — ไม่ยาวเกินไปจนทำ Grafana ค้าง ไม่สั้นเกินไปจน panel error
  • เปิด HTTPS บนทุก data source ที่อยู่คนละเครือข่าย
  • ตรวจสอบ Data source Health เป็นระยะ เช่น ผ่าน Grafana API endpoint /api/datasources/uid/{uid}/health

สรุป

Data Source เป็นจุดเชื่อมต่อระหว่าง Grafana กับระบบเก็บข้อมูลจริง การตั้งค่าที่ถูกต้องจะช่วยให้ dashboard แสดงผลได้เสถียร ปลอดภัย และยืดหยุ่นพอจะรองรับการเปลี่ยน environment ได้โดยไม่ต้องแก้ panel ทีละอัน การใช้ provisioning YAML ร่วมกับ environment variable เป็นแนวทางที่ผู้ดูแลระบบควรยึดเป็นมาตรฐานตั้งแต่เริ่มวางระบบ monitoring

เมื่อ data source เชื่อมต่อเรียบร้อยแล้ว ขั้นตอนถัดไปคือการสร้าง panel และ alert rule ที่ query ข้อมูลจาก data source เหล่านี้ ซึ่งเป็นพื้นฐานของระบบ observability ที่สมบูรณ์