Event Log - MUIT-iDev/JWT GitHub Wiki

Quick Start

ชื่อกลาง correlationId ที่ระบบใช้งานร่วมกัน

  • ขึ้นอยู่กับ service ตกลงร่วมกัน
  • url route: /{correlationId}
  • url query: ?correlationId={correlationId}
  • url tag: #correlationId={correlationId}
  • header: {correlationId:{correlationId}}
  • body: {correlationId:{correlationId}}

Topic

Add Event Log

  • path: {domain}/evlog/v1/add/{systempKey}/{correlationId}
    • systempKey: String
    • correlationId: UUID
  • method: post
  • body (Minimal):
{
  "level": "INFO",
  "type": "AUTHENTICATION",
  "traceId": "5aec0e4c-79f3-487b-8b4a-0f049207623b",
  "domain": "example.com",
  "version": "1.0.0",
  "mode": "PROD",
  "serviceName": "AuthService",
  "responseMessage": "Authentication failed",
  "processStart": "2025-02-05T12:34:56.123Z",
  "processTimeMs": 177.0
}
  • body (FULL):
{
  "level": "INFO",
  "type": "AUTHENTICATION",
  "traceId": "5aec0e4c-79f3-487b-8b4a-0f049207623b",
  "domain": "example.com",
  "host": "server1.example.com",
  "version": "1.0.0",
  "mode": "PROD",
  "serviceName": "AuthService",
  "path": "/api/user/add",
  "method": "POST",
  "requestIdentity": "user123",
  "requestIp": "203.0.113.45",
  "requestAuthen": false,
  "requestUser": "john.doe",
  "requestContext": {
    "header": {
      "User-Agent": "Mozilla/5.0",
      "Authorization": "Bearer abcdef123456"
    },
    "query": {
      "ref": "google"
    },
    "body": {
      "username": "john.doe",
      "action": "create",
      "data": ["asdf","zxcv"]
    }
  },
  "responseStatus": true,
  "responseStatusCode": 200,
  "responseContext": {
    "processId": "45aa514d-aaff-40be-9677-9d21a51a9de5",
    "agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36",
    "hostAddress": "10.43.4.248",
    "hostName": "10.43.4.248",
    "browserName": "Chrome",
    "browserVersion": "132.0",
    "browserType": "Chrome132"
  },
  "responseMessage": "Authentication failed",
  "responseException": {
    "errorCode": "AUTH_001",
    "errorMessage": "Invalid username or password",
    "stackTrace": "at JWT.Model.AuthService.Login(...)"
  },
  "processDetail": [
    "2025-02-05T12:34:56.123Z: Init process started",
    "2025-02-05T12:34:56.200Z: Received login request",
    "2025-02-05T12:34:56.300Z: User authentication failed"
  ],
  "processStart": "2025-02-05T12:34:56.123Z",
  "processSuccess": "2025-02-05T12:34:56.300Z",
  "processTimeMs": 177.0
}

คำอธิบายแต่ละฟิลด์และข้อมูลที่สามารถกรอกได้

Field ประเภทข้อมูล คำอธิบาย ค่าที่สามารถกรอกได้
level string Required🔴 ระดับของ Log "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"
type string Required🔴 ประเภทของเหตุการณ์ที่เกิดขึ้น "USER_ACTION", "API_CALL", "AUTHENTICATION", "DATABASE_QUERY", "PERFORMANCE_METRIC", "SECURITY_EVENT", "SYSTEM_EVENT", "ERROR_LOG", "INTEGRATION_EVENT", "AUDIT_LOG"
traceId string Required🔴 UUID ProcessId ของระบบ "5aec0e4c-79f3-487b-8b4a-0f049207623b"
domain string Required🔴 ชื่อโดเมนของระบบที่เรียกใช้งาน "example.com", "api.example.com"
host string ชื่อโฮสต์หรือ IP ของเครื่องที่เรียกใช้งาน "192.168.1.100", "server1.example.com"
version string Required🔴 เวอร์ชันของระบบ "1.0.0", "v2.3-beta"
mode string Required🔴 โหมดการทำงานของระบบ "DEV", "TEST", "STAGING", "PROD", "QAS", "PRD"
serviceName string Required🔴 ชื่อของบริการหรือ API ที่ถูกเรียกใช้ "UserService", "PaymentService"
path string (nullable) เส้นทาง API ที่ถูกเรียกใช้ "/api/users/login", "/v1/payments"
method string (nullable) HTTP Method ที่ใช้เรียก API "GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"
requestIdentity string (nullable) รหัสของคำขอที่ใช้ระบุเอกลักษณ์ "deviceId","user123", "txn-7890"
requestIp string (nullable) IP Address ของผู้ใช้ที่ทำคำขอ "192.168.1.100", "203.0.113.45"
requestAuthen boolean สถานะการยืนยันตัวตนของผู้ใช้ true, false
requestUser string (nullable) ชื่อหรือ ID ของผู้ใช้ที่ทำคำขอ "john.doe", "user_5678"
requestContext object ข้อมูลเพิ่มเติมเกี่ยวกับคำขอ Optional important📌📌📌 ดูรายละเอียดด้านล่าง
responseStatus boolean สถานะของการตอบกลับ true (สำเร็จ), false (ล้มเหลว)
responseStatusCode integer HTTP Status Code ของการตอบกลับ 200, 400, 401, 500
responseContext object (nullable) เนื้อหาการตอบกลับเพิ่มเติม { "token": "abcdef123456" }
responseMessage string Required🔴 ข้อความอธิบายผลลัพธ์ "Login successful", "User not found"
responseException object (nullable) ข้อมูลข้อผิดพลาดกรณีมี Exception ดูรายละเอียดด้านล่าง
processDetail list (string) รายละเอียดของการประมวลผลแต่ละขั้นตอน ["2025-02-05T12:34:56.123Z: Init process started", "2025-02-05T12:34:56.300Z: Authenticated user successfully"]
processStart string (ISO 8601) Required🔴 เวลาที่เริ่มกระบวนการ "2025-02-05T12:34:56.123Z"
processSuccess string (ISO 8601) (nullable) เวลาที่กระบวนการสำเร็จ "2025-02-05T12:34:56.456Z"
processTimeMs double Required🔴 เวลาที่ใช้ในการประมวลผล (ms) 333.0, 1500.5

โครงสร้าง requestContext 📌📌📌

  • header: Header ของคำขอ HTTP เช่น "User-Agent", "Authorization"
  • query: พารามิเตอร์ที่ส่งมากับ URL เช่น ?ref=google
  • body: ข้อมูลที่ถูกส่งมาใน POST, PUT หรือ PATCH

Get Event Log by ProcessId

  • path: {domain}/evlog/v1/processId/{systempKey}/{processId}
    • systempKey: String
    • processId: UUID
  • method: get
{
  "__message": "content same Get Event Log by ProcessId, CorrelationId and systemKey",
  "content": [
    {
      "level": "INFO",
      "type": "API_CALL",
      "mode": "PRD",
      "method": "GET",
      "requestContext": {
        "header": [
          {
            "Key": "Accept",
            "Value": [
              "application/json;q=1"
            ]
          },
          {
            "Key": "Accept-Encoding",
            "Value": [
              "gzip, deflate"
            ]
          },
        ],
        "query": null,
        "body": null
      },
      "responseContext": "xxyyzz",
      "responseException": null,
      "processDetail": [
        "2025-02-27 17:37:13.964: version1Control.xxyyzz init [version1Control.xxyyzz]",
        "2025-02-27 17:37:13.964: version1Control process [version1Control]",
        "2025-02-27 17:37:13.964: checkInitSystemKey init",
        "2025-02-27 17:37:13.964: checkInitSystemKey process",
        "2025-02-27 17:37:13.980: checkInitSystemKey success",
        "2025-02-27 17:37:14.011: version1Control.xxyyzz success [version1Control.xxyyzz]"
      ],
      "id": "4587096f-0472-490a-ba79-2946fcxxyyzz",
      "createDate": "2025-02-27T17:37:14.043",
      "correlation": "e72b0135-a0d2-480d-bbd3-4d268cxxyyzz",
      "traceId": "e72b0135-a0d2-480d-bbd3-4d268cxxyyzz",
      "domain": "jwt.mahidol.ac.th",
      "host": "JWT: ::1,10.41.118.11",
      "version": "202502261634-2025.3.1",
      "serviceName": "JWT",
      "path": "/v1/xxyyzz",
      "requestIdentity": "0e888a1c34ccb2e3dec3e2967aa69735754c82865e226be2ab0f0bce7fxxyyzz",
      "requestIp": "10.41.xx.xx",
      "requestAuthen": true,
      "requestUser": "flextime",
      "responseStatus": true,
      "responseStatusCode": 200,
      "responseMessage": "v1 xxyyzz success",
      "processStart": "2025-02-27T17:37:13.967",
      "processSuccess": "2025-02-27T17:37:14.013",
      "processTimeMs": 48
    }
  ]
}

Get Event Log by CorrelationId

  • path: {domain}/evlog/v1/correlationId/{systempKey}/{correlationId}
    • systempKey: String
    • correlationId: UUID
  • method: get
{
  "__message": "content same Get Event Log by ProcessId, CorrelationId and systemKey",
  "content": [
    {
      "level": "INFO",
      "type": "API_CALL",
      "mode": "PRD",
      "method": "GET",
      "id": "4587096f-0472-490a-ba79-2946fcxxyyzz",
      "createDate": "2025-02-27T17:37:14.043",
      "correlation": "e72b0135-a0d2-480d-bbd3-4d268cxxyyzz",
      "traceId": "e72b0135-a0d2-480d-bbd3-4d268cxxyyzz",
      "domain": "jwt.mahidol.ac.th",
      "host": "JWT: ::1,10.41.118.11",
      "version": "202502261634-2025.3.1",
      "serviceName": "JWT",
      "path": "/v1/xxyyzz",
      "requestIdentity": "0e888a1c34ccb2e3dec3e2967aa69735754c82865e226be2ab0f0bce7fxxyyzz",
      "requestIp": "10.41.xx.xx",
      "requestAuthen": true,
      "requestUser": "flextime",
      "responseStatus": true,
      "responseStatusCode": 200,
      "responseMessage": "v1 xxyyzz success",
      "processStart": "2025-02-27T17:37:13.967",
      "processSuccess": "2025-02-27T17:37:14.013",
      "processTimeMs": 48
    }
  ]
}

Get Event Log by systemKey

  • path: {domain}/evlog/v1/system/{systempKey}?day={day}&date={date}&perpage={perpage}&page={page}
    • systempKey: String
    • day: int default 7 day before (optional)
    • date: date default date now (yyyy-mm-dd) (optional)
    • perpage: int default 1000 (optional)
    • page: int default 1 (optional)
  • method: get

Get Event Log by systemKey in date time

  • path: {domain}/evlog/v1/system/{systempKey}/min?min={min}&date={date}&perpage={perpage}&page={page}
    • systempKey: String
    • min: int default 60 min before (max: 720 min) (optional)
    • date: date default date time now (yyyy-mm-dd hh:mm) (optional)
    • perpage: int default 1000 (optional)
    • page: int default 1 (optional)
  • method: get

Get Analytic by systemKey (Hour)

  • path: {domain}/evlog/v1/system/{systempKey}/analytic?day={day}&date={date}
    • systempKey: String
    • day: int default 7 day before (optional)
    • date: date default date now (yyyy-mm-dd) (optional)
  • method: get
{
  "content": [
    {
      "date": "2025-02-26T22:00:00",
      "level": "INFO",
      "mode": "PRD",
      "serviceName": "JWT",
      "responseStatusCode": 200,
      "TransactionAll": 100,
      "TimeMsTotal": 6416,
      "TimeMsMin": 5,
      "TimeMsMax": 211,
      "TimeMsAvg": 64.16
    },
    {
      "date": "2025-02-26T21:00:00",
      "level": "INFO",
      "mode": "PRD",
      "serviceName": "JWT",
      "responseStatusCode": 200,
      "TransactionAll": 242,
      "TimeMsTotal": 16865,
      "TimeMsMin": 4,
      "TimeMsMax": 373,
      "TimeMsAvg": 69.69
    }
  ],
}

Get Analytic by systemKey (Minutes)

  • path: {domain}/evlog/v1/system/{systempKey}/analyticmin?min={min}&date={date}
    • systempKey: String
    • min: int default 30 minutes before (optional)
    • date: date default date now (yyyy-mm-dd hh:mm) (optional)
  • method: get

Description

Log Level

Log Level เป็นระดับความสำคัญของ Log ซึ่งช่วยให้เราสามารถกรองและจัดลำดับความสำคัญของ Log ได้อย่างมีประสิทธิภาพ โดยทั่วไปมี 6 ระดับหลัก ๆ ดังนี้:

Log Level ความสำคัญ คำอธิบาย
TRACE 🟢 ต่ำสุด ใช้สำหรับ Debugging เชิงลึก (เช่น การติดตามการไหลของโค้ดแบบละเอียดมาก)
DEBUG 🟢 ต่ำ ใช้สำหรับบันทึกข้อมูลที่ใช้ในการพัฒนาและแก้ไขปัญหา (ไม่ควรเปิดใช้ใน Production)
INFO 🟡 ปานกลาง ใช้สำหรับบันทึกเหตุการณ์ทั่วไปที่เกิดขึ้นในระบบ เช่น User logged in, Payment processed
WARN 🟠 สูง ใช้สำหรับเหตุการณ์ที่อาจทำให้เกิดปัญหา แต่ระบบยังสามารถทำงานต่อได้ เช่น High CPU Usage, Slow API Response
ERROR 🔴 สูงมาก ใช้สำหรับข้อผิดพลาดที่ทำให้ระบบบางส่วนทำงานล้มเหลว เช่น Database Connection Failed, API Request Timeout
FATAL 🔴🔴 สูงสุด ใช้สำหรับข้อผิดพลาดที่ทำให้ระบบล่มโดยสิ้นเชิง เช่น Out of Memory, Service Unavailable

หลักการเลือกใช้ Log Level

  1. ใช้ DEBUG และ TRACE สำหรับการพัฒนา (Development Mode เท่านั้น)
  2. ใช้ INFO สำหรับเหตุการณ์ปกติของระบบที่ควรรู้ (แต่ไม่ใช่ข้อผิดพลาด)
  3. ใช้ WARN สำหรับเหตุการณ์ที่อาจนำไปสู่ข้อผิดพลาดในอนาคต
  4. ใช้ ERROR สำหรับข้อผิดพลาดที่ต้องการแก้ไขด่วน (เช่น ระบบล้มเหลวเฉพาะส่วน)
  5. ใช้ FATAL เมื่อต้องแจ้งเตือนว่าระบบมีปัญหาหนักและต้องหยุดทำงานทันที

Event Type

Event Type คือประเภทของเหตุการณ์ที่เกิดขึ้นในระบบ ซึ่งช่วยให้สามารถจัดหมวดหมู่ของ Log ได้ง่ายขึ้น

Event Type คำอธิบาย ตัวอย่าง``
USER_ACTION กิจกรรมที่เกิดจากผู้ใช้ User clicked checkout, User updated profile
API_CALL การเรียกใช้งาน API (Request & Response) POST /api/v1/orders, GET /api/v1/products
AUTHENTICATION การเข้าสู่ระบบหรือออกจากระบบ User logged in, User failed login attempt
DATABASE_QUERY การเรียกใช้งานฐานข้อมูล SELECT * FROM users WHERE id=1
PERFORMANCE_METRIC ข้อมูลการวัดผลการทำงานของระบบ API response time: 200ms, Memory usage: 80%
SECURITY_EVENT เหตุการณ์ที่เกี่ยวข้องกับความปลอดภัย Failed login attempt, XSS attack detected
SYSTEM_EVENT เหตุการณ์ทั่วไปของระบบ Server started, Cron job executed
ERROR_LOG ข้อผิดพลาดที่เกิดขึ้นในระบบ Payment processing failed, Database connection timeout
INTEGRATION_EVENT การทำงานร่วมกันระหว่างระบบ Webhook received from Stripe, Third-party API response error
AUDIT_LOG บันทึกกิจกรรมที่เกี่ยวข้องกับการเปลี่ยนแปลงข้อมูลสำคัญ Admin updated user role, User deleted record

หลักการใช้ Event Type

  • ใช้ USER_ACTION สำหรับการกระทำที่ผู้ใช้เป็นผู้ทำ
  • ใช้ API_CALL สำหรับการส่งและรับข้อมูลระหว่างระบบ
  • ใช้ AUTHENTICATION สำหรับเหตุการณ์เกี่ยวกับการล็อกอิน
  • ใช้ DATABASE_QUERY เพื่อตรวจสอบคำสั่งที่ใช้กับฐานข้อมูล
  • ใช้ PERFORMANCE_METRIC สำหรับการวัดประสิทธิภาพของระบบ
  • ใช้ SECURITY_EVENT สำหรับการแจ้งเตือนที่เกี่ยวกับความปลอดภัย
  • ใช้ ERROR_LOG เมื่อต้องการบันทึกข้อผิดพลาด
  • ใช้ INTEGRATION_EVENT สำหรับการเชื่อมต่อระหว่างระบบ
  • ใช้ AUDIT_LOG สำหรับเหตุการณ์ที่เกี่ยวกับข้อมูลสำคัญ เช่น การแก้ไขสิทธิ์ของผู้ใช้

หลักการของ Log Level

  • TRACE – ติดตามโค้ดละเอียดสุด
  • DEBUG – ใช้ระหว่างพัฒนา
  • INFO – ใช้กับเหตุการณ์ปกติ
  • WARN – แจ้งเตือนปัญหาที่อาจเกิดขึ้น
  • ERROR – แจ้งข้อผิดพลาดที่ต้องแก้ไข
  • FATAL – แจ้งข้อผิดพลาดที่รุนแรงมาก

หลักการของ Event Type

  • USER_ACTION – การกระทำของผู้ใช้
  • API_CALL – API Request & Response
  • AUTHENTICATION – การล็อกอิน / ล็อกเอาต์
  • DATABASE_QUERY – การใช้ฐานข้อมูล
  • SECURITY_EVENT – ปัญหาด้านความปลอดภัย
  • ERROR_LOG – ข้อผิดพลาดที่เกิดขึ้นในระบบ

Correlation ID vs Trace ID ต่างกันอย่างไร?

ในระบบ Distributed Logging หรือ Microservices, เรามักจะใช้ Correlation ID และ Trace ID เพื่อติดตาม Request ข้ามระบบ และ วิเคราะห์ปัญหาได้ง่ายขึ้น แต่ทั้งสองค่ามีบทบาทที่แตกต่างกัน:

Correlation ID คืออะไร?

  • ใช้เพื่อติดตาม Request ทั้งหมดที่เกี่ยวข้องกัน ผ่านหลายระบบ
  • ใช้เมื่อ Request หนึ่งมีหลาย Sub-Requests หรือทำงานข้ามหลายบริการ
  • ทุก Log ที่เกี่ยวข้องกับ Request เดียวกัน จะใช้ Correlation ID เดียวกัน

ตัวอย่างการใช้ Correlation ID

  1. User กด Checkout (Frontend สร้าง Correlation ID)
  2. Frontend เรียก API Payment → Correlation ID ถูกส่งไปยัง Backend
  3. Backend สร้าง Transaction และเรียก External Payment Gateway
  4. Payment Gateway ดำเนินการสำเร็จ → ส่ง Response กลับมา
  5. Backend ตอบกลับไปยัง Frontend
  6. ทุก Log ที่เกิดขึ้นระหว่าง Request นี้จะมี Correlation ID เดียวกัน

Trace ID คืออะไร?

  • ใช้เพื่อติดตามการทำงานภายในแต่ละระบบ (Microservices, Database, Queue, etc.)
  • มักใช้ร่วมกับ Distributed Tracing Tools เช่น Jaeger, Zipkin, AWS X-Ray
  • Trace ID ถูกสร้างขึ้นเมื่อมี Request เข้ามา และแต่ละ Service จะมี Span ID แยกกัน

ตัวอย่างการใช้ Trace ID

  1. Frontend เรียก API Payment (สร้าง Trace ID)
  2. Backend สร้าง Transaction และเรียก Payment Gateway
  3. Database บันทึกข้อมูล → สร้าง Span ID แยกกัน
  4. ทุกระบบสามารถใช้ Trace ID เพื่อติดตามได้ว่า Request ใช้เวลาส่วนไหนมากที่สุด

สรุปความแตกต่างระหว่าง Correlation ID และ Trace ID

คุณสมบัติ Correlation ID Trace ID
หน้าที่หลัก ติดตาม Request ทั้งหมด ที่เกี่ยวข้องกัน ติดตาม Request ภายในระบบเดียวกัน
ใครเป็นคนสร้าง Frontend หรือ API Gateway แต่ละ Service สร้างของตัวเอง
ใช้ทำอะไร? Debug และ Tracking Request ข้ามระบบ วิเคราะห์ Performance และ Distributed Tracing
อยู่ใน Log อะไร? API Calls, Business Logic Database, Internal Service, Queue Processing
สามารถใช้ร่วมกันได้ไหม? ✅ ใช่ ✅ ใช่

ตัวอย่างใช้งานร่วมกัน

Service Correlation ID Trace ID
Frontend (User Clicks Checkout) corr-123456 trace-abc123
API Gateway (Pass Request to Backend) corr-123456 trace-def456
Order Service (Create Order) corr-123456 trace-ghi789
Payment Service (Process Payment) corr-123456 trace-jkl012
Database (Insert Transaction Record) corr-123456 trace-mno345
  • ทุกระบบมี Correlation ID เดียวกัน (corr-123456)
  • แต่ละระบบสร้าง Trace ID ของตัวเอง เพื่อใช้ในการ Tracing ภายใน

Ref

  1. BetterStack - Log Levels Explained https://betterstack.com/community/guides/logging/log-levels-explained
  2. BetterStack - Logging for Microservices https://betterstack.com/community/guides/logging/logging-microservices
  3. CrowdStrike - Centralized Logging Best Practices https://www.crowdstrike.com/en-us/cybersecurity-101/next-gen-siem/centralized-logging
  4. Splunk - Centralized Logging https://www.splunk.com/en_us/blog/learn/centralized-logging.html
  5. Elastic Common Schema (ECS) - Standard Logging Fields https://www.elastic.co/guide/en/ecs/current/ecs-field-reference.html
  6. Google Cloud - Logging Overview https://cloud.google.com/logging/docs/overview