ID tương quan từ đầu đến cuối: theo dõi hành động người dùng trong nhật ký
Hướng dẫn end-to-end về ID tương quan: tạo ID ở frontend, truyền qua API và đính vào logs để hỗ trợ truy nguyên sự cố nhanh.

Tại sao ID tương quan quan trọng với bộ phận hỗ trợ
Bộ phận hỗ trợ hiếm khi nhận được một báo cáo lỗi rõ ràng. Người dùng có thể nói, "Tôi nhấn Pay và bị lỗi," nhưng một lần nhấn đó có thể chạm tới trình duyệt, một API gateway, dịch vụ thanh toán, cơ sở dữ liệu và một job nền. Mỗi phần ghi lại một lát cắt của câu chuyện vào những thời điểm khác nhau trên những máy khác nhau. Nếu không có một nhãn chung, bạn sẽ phải đoán những dòng log nào thuộc về cùng một luồng.
ID tương quan là nhãn chung đó. Là một ID gắn với một hành động người dùng (hoặc một workflow logic) và được mang qua mọi yêu cầu, retry và service hop. Với độ phủ end-to-end thực sự, bạn có thể bắt đầu từ một phàn nàn của người dùng và kéo ra toàn bộ chuỗi thời gian giữa các hệ thống.
Mọi người thường nhầm lẫn vài loại ID tương tự. Đây là cách phân biệt rõ ràng:
- Correlation ID: gom mọi thứ liên quan đến một hành động (ví dụ, "Lưu cài đặt").
- Request ID: định danh một yêu cầu HTTP; retry sẽ tạo request ID mới.
- Trace ID: dùng trong công cụ tracing phân tán; mục tiêu tương tự, thường do thư viện tracing tạo.
- Session ID: định danh một phiên người dùng qua nhiều hành động; quá rộng để gỡ lỗi một sự cố cụ thể.
Ví dụ tốt trông đơn giản: người dùng báo lỗi, bạn yêu cầu họ cung cấp correlation ID hiển thị trên UI (hoặc ở màn hình hỗ trợ), và bất kỳ ai trong đội có thể tìm toàn bộ câu chuyện trong vài phút. Bạn thấy request frontend, phản hồi API, các bước backend và kết quả database, tất cả được liên kết với nhau.
Quy ước cho correlation ID
Trước khi sinh ID, hãy thống nhất vài quy tắc. Nếu mỗi đội chọn một tên header hoặc trường log khác nhau, hỗ trợ vẫn sẽ bị mắc kẹt đoán.
Bắt đầu với một tên chuẩn và dùng nó ở mọi nơi. Một lựa chọn phổ biến là header HTTP như X-Correlation-Id, kèm một trường log có cấu trúc như correlation_id. Chọn một cách viết và một quy tắc chữ hoa/chữ thường, document lại, và đảm bảo reverse proxy hoặc gateway của bạn không đổi tên hoặc loại header.
Chọn định dạng dễ sinh và an toàn khi chia sẻ trong ticket hoặc chat. UUID phù hợp vì nó độc nhất và không gây chú ý. Giữ ID đủ ngắn để dễ copy nhưng không quá ngắn gây trùng. Nhất quán quan trọng hơn thông minh.
Cũng quyết định nơi ID phải xuất hiện để con người thực sự có thể dùng nó. Trong thực tế, điều đó có nghĩa là ID xuất hiện trong requests, logs và lỗi hiển thị, và có thể tìm kiếm trong công cụ mà đội dùng.
Xác định thời gian sống (lifetime) cho một ID. Mặc định hợp lý là một hành động người dùng, ví dụ "nhấn Pay" hoặc "lưu hồ sơ." Với workflow dài hơn qua nhiều dịch vụ và queue, giữ cùng một ID cho đến khi workflow kết thúc, rồi bắt ID mới cho hành động tiếp theo. Tránh "một ID cho toàn bộ phiên" vì tìm kiếm sẽ quá ồn nhanh chóng.
Một quy tắc quan trọng: không bao giờ đặt dữ liệu cá nhân vào ID. Không dùng email, số điện thoại, user ID hay số đơn hàng. Nếu cần ngữ cảnh đó, log nó vào trường riêng với kiểm soát quyền riêng tư phù hợp.
Sinh ID ở frontend (cách tiếp cận thực tế)
Nơi dễ nhất để bắt đầu một correlation ID là ngay lúc người dùng bắt đầu một hành động quan trọng: nhấn "Save", submit form, hoặc khởi trigger một flow gây ra nhiều request. Nếu đợi backend tạo, bạn thường mất phần đầu của câu chuyện (lỗi UI, retry, request bị hủy).
Dùng định dạng ngẫu nhiên, duy nhất. UUID v4 là lựa chọn phổ biến vì dễ sinh và ít khả năng trùng. Giữ nó opaque (không chứa username, email hay timestamps) để không vô tình lộ dữ liệu cá nhân vào header và log.
Tạo và giữ ID cho một workflow
Xem "workflow" như một hành động người dùng có thể gây nhiều request: validate, upload, tạo record, rồi refresh danh sách. Tạo một ID khi workflow bắt đầu, rồi giữ nó đến khi workflow kết thúc (thành công, thất bại, hoặc người dùng hủy). Mẫu đơn giản là lưu nó trong state của component hoặc một đối tượng context nhẹ cho request.
Nếu người dùng bắt đầu cùng hành động hai lần, sinh ID mới cho lần thử thứ hai. Điều này giúp hỗ trợ phân biệt giữa "cùng một click retry" và "hai lần gửi riêng biệt."
Đính kèm vào mọi request của workflow
Thêm ID vào mọi API call do workflow kích hoạt, thường qua header như X-Correlation-ID. Nếu bạn dùng API client chung (wrapper fetch, Axios instance, v.v.), truyền ID một lần và để client chèn nó vào mọi cuộc gọi.
// 1) when the user action starts
const correlationId = crypto.randomUUID(); // UUID v4 in modern browsers
// 2) pass it to every request in this workflow
await api.post('/orders', payload, {
headers: { 'X-Correlation-ID': correlationId }
});
await api.get('/orders/summary', {
headers: { 'X-Correlation-ID': correlationId }
});
Nếu UI của bạn thực hiện các request nền không liên quan đến hành động (polling, analytics, auto-refresh), đừng tái sử dụng workflow ID cho chúng. Giữ correlation ID tập trung để một ID kể một câu chuyện duy nhất.
Truyền ID qua API một cách tin cậy
Khi đã sinh ID ở trình duyệt, nhiệm vụ đơn giản: ID phải rời khỏi frontend trong mọi request và đến nơi không đổi tại mọi ranh giới API. Đây là điểm thường hay sập khi các đội thêm endpoint, client mới, hoặc middleware mới.
Mặc định an toàn nhất là dùng header HTTP trên mọi cuộc gọi (ví dụ X-Correlation-Id). Header dễ thêm ở một chỗ (fetch wrapper, interceptor Axios, layer mạng trên mobile) và không cần thay đổi payload.
Nếu có request cross-origin, đảm bảo API cho phép header đó. Nếu không, trình duyệt có thể âm thầm chặn và bạn sẽ nghĩ rằng mình đã gửi mà thực tế không phải.
Nếu bắt buộc phải đặt ID trong query string hoặc body (một số công cụ bên thứ ba hoặc upload file yêu cầu), giữ cho nhất quán và document rõ. Chọn một tên field và dùng nó ở mọi nơi. Đừng trộn correlationId, requestId và cid tùy endpoint.
Retries là một bẫy phổ biến khác. Một retry nên giữ cùng correlation ID nếu vẫn là cùng một hành động người dùng. Ví dụ: người dùng nhấn "Save", mạng rớt, client retry POST. Hỗ trợ nên thấy một chuỗi liên kết, không phải ba chuỗi rời rạc. Lần click mới (hoặc job nền mới) nên có ID mới.
Với WebSockets, đưa ID vào envelope của message, không chỉ ở handshake ban đầu. Một kết nối có thể mang nhiều hành động người dùng.
Nếu muốn kiểm tra nhanh độ tin cậy, giữ cho đơn giản:
- Một helper client chung thêm header trên mọi request.
- Retry tái sử dụng cùng ID cho cùng một hành động.
- Bất kỳ fallback body/query dùng một tên trường đã được document.
- Tin nhắn WebSocket bao gồm trường
correlationIdrõ ràng.
Hành vi ở điểm vào API (API entry point)
Edge của API (gateway, load balancer, hoặc service đầu tiên nhận traffic) là nơi correlation ID trở nên đáng tin cậy hoặc biến thành sự đoán mò. Xử lý điểm vào này như nguồn chân lý.
Chấp nhận ID tới nếu client gửi, nhưng đừng giả định luôn có. Nếu thiếu, sinh mới ngay lập tức và dùng cho phần còn lại của request. Điều này giữ hệ thống hoạt động ngay cả khi một vài client cũ hoặc cấu hình sai.
Làm kiểm tra nhẹ để giá trị xấu không làm ô nhiễm logs. Giữ permissive: kiểm tra độ dài và ký tự cho phép, nhưng tránh định dạng quá chặt có thể từ chối traffic thật. Ví dụ, cho phép 16-64 ký tự và chữ, số, dấu gạch ngang, gạch dưới. Nếu giá trị không hợp lệ, thay bằng ID mới và tiếp tục.
Hiển thị ID cho caller. Luôn trả lại nó trong response headers và đưa vào body lỗi. Bằng cách đó người dùng có thể copy từ UI hoặc hỗ trợ có thể yêu cầu và tìm chính xác chuỗi log.
Chính sách edge thực tế như sau:
- Đọc
X-Correlation-ID(hoặc header bạn chọn) từ request. - Nếu thiếu hoặc không hợp lệ, tạo ID mới và gắn vào context của request.
- Thêm
X-Correlation-IDvào mọi response, kể cả lỗi. - Khi trả JSON lỗi, echo ID trong payload.
Ví dụ payload lỗi (những gì hỗ trợ nên nhìn thấy trong ticket và screenshot):
{
"error": {
"code": "PAYMENT_FAILED",
"message": "We could not confirm the payment.",
"correlation_id": "c3a8f2d1-9b24-4c61-8c4a-2a7c1b9c2f61"
}
}
Lan truyền ID giữa các dịch vụ backend
Khi request đến backend, xử lý correlation ID như một phần của context request, không phải thứ cất trong biến toàn cục. Global sẽ hỏng khi bạn xử nhiều request cùng lúc hoặc khi công việc async tiếp tục sau khi đã trả response.
Một quy tắc có thể mở rộng: mọi hàm có thể log hoặc gọi dịch vụ khác nên nhận context chứa ID. Trong dịch vụ Go, điều này thường có nghĩa là truyền context.Context xuống handlers, business logic và client code.
Khi Service A gọi Service B, sao chép cùng một ID vào request đi. Đừng tự sinh ID mới giữa đường trừ khi bạn cũng giữ bản gốc ở trường riêng (ví dụ parent_correlation_id). Nếu đổi ID, hỗ trợ sẽ mất sợi chỉ nối câu chuyện lại.
Không lan truyền thường bị bỏ sót ở vài chỗ dự đoán được: job nền khởi trong request, retry bên trong thư viện client, webhook trigger sau này, và các cuộc gọi fan-out. Bất kỳ message async (queue/job) nào cũng nên mang ID, và logic retry nên giữ nó.
Log nên có cấu trúc với tên trường ổn định như correlation_id. Chọn một cách viết và giữ nó ở mọi nơi. Tránh trộn requestId, req_id và traceId trừ khi bạn định nghĩa rõ mapping.
Nếu có thể, đưa ID vào visibility của database nữa. Cách thực tế là thêm nó vào comment của query hoặc metadata phiên để slow query logs cũng có thể hiển thị. Khi ai đó báo "Nhấn Save treo 10 giây", hỗ trợ có thể tìm correlation_id=abc123 và thấy log API, cuộc gọi service xuống, và câu SQL chậm duy nhất gây ra trễ.
Đưa ID vào các log mà con người có thể dùng
ID tương quan chỉ hữu ích khi mọi người có thể tìm và theo dõi nó. Làm cho nó thành trường log hàng đầu (không chôn trong message string), và giữ phần còn lại của entry nhất quán giữa các service.
Các trường log giúp ID có ích
Kết hợp correlation ID với vài trường nhỏ trả lời: khi nào, ở đâu, chuyện gì xảy ra, và ai (theo cách an toàn với người dùng). Với hầu hết đội, nghĩa là:
timestamp(có timezone)servicevàenv(api, worker, prod, staging)route(hoặc tên operation) vàmethodstatusvàduration_ms- một định danh an toàn của người dùng (ví dụ
account_idhoặc user id băm, không phải email)
Với những thông tin này, hỗ trợ có thể tìm theo ID, xác nhận họ đang xem đúng request và thấy dịch vụ nào đã xử lý nó.
Ghi gì ở bắt đầu, thành công và thất bại
Hướng tới vài dấu vết mạnh cho mỗi request, không phải bản ghi mọi thứ.
- Start: correlation ID, route, định danh người dùng an toàn, và các input chính (tóm tắt).
- Success: correlation ID, status, duration và kết quả ngắn (ví dụ
rows=12). - Failure: correlation ID, loại lỗi, ngữ cảnh an toàn, và nơi xảy ra (handler, dependency).
Để tránh log ồn, giữ chi tiết mức debug tắt mặc định và chỉ nâng cấp những event giúp trả lời câu "Nó lỗi ở đâu?". Nếu một dòng không giúp định vị vấn đề hoặc đo tác động, có lẽ không nên ở mức info.
Redaction (gở bỏ dữ liệu nhạy cảm) quan trọng như cấu trúc. Không bỏ PII vào correlation ID hay log: không email, tên, số điện thoại, địa chỉ đầy đủ hay token thô. Nếu cần định danh người dùng, log internal ID hoặc một hash một chiều.
Ví dụ: theo dấu một báo cáo người dùng từ UI tới database
Người dùng nhắn hỗ trợ: "Checkout failed when I clicked Pay." Câu hỏi theo sau tốt nhất là: "Bạn dán correlation ID hiển thị trên màn hình lỗi không?" Họ trả về cid=9f3c2b1f6a7a4c2f.
Hỗ trợ bây giờ có một tay nắm kết nối UI, API và database. Mục tiêu là mọi dòng log cho hành động đó mang cùng một ID.
Hỗ trợ tìm kiếm logs cho 9f3c2b1f6a7a4c2f và thấy luồng:
frontend INFO cid=9f3c2b1f6a7a4c2f event="checkout_submit" cart=3 items
api INFO cid=9f3c2b1f6a7a4c2f method=POST path=/api/checkout user=1842
api ERROR cid=9f3c2b1f6a7a4c2f msg="payment failed" provider=stripe status=502
Từ đó, kỹ sư theo ID này vào bước tiếp theo. Điều then chốt là các cuộc gọi backend (và job queue) cũng phải chuyển tiếp ID.
payments INFO cid=9f3c2b1f6a7a4c2f action="charge" amount=49.00 currency=USD
payments ERROR cid=9f3c2b1f6a7a4c2f err="timeout" upstream=stripe timeout_ms=3000
db INFO cid=9f3c2b1f6a7a4c2f query="insert into failed_payments" rows=1
Bây giờ vấn đề rõ ràng: dịch vụ thanh toán timeout sau 3 giây và một bản ghi thất bại đã được ghi. Kỹ sư có thể kiểm tra deploy gần đây, xác nhận cài đặt timeout có thay đổi không, và xem liệu có retry xảy ra.
Để đóng vòng, kiểm tra bốn bước:
- Sửa nguyên nhân (ví dụ điều chỉnh timeout và thêm retry an toàn).
- Đảm bảo lỗi hiển thị cho người dùng bao gồm correlation ID.
- Theo dõi log mới với cùng mẫu lỗi nhưng ID khác.
- Xác nhận ID tồn tại qua mọi hop (kể cả worker và message queue).
Lỗi thường gặp và cách tránh
Cách nhanh nhất làm cho correlation ID vô dụng là làm đứt chuỗi. Hầu hết lỗi xuất phát từ những quyết định nhỏ có vẻ vô hại trong khi xây dựng, nhưng gây hại khi hỗ trợ cần câu trả lời.
Sai lầm kinh điển là sinh ID mới ở mỗi hop. Nếu trình duyệt gửi ID, API gateway của bạn nên giữ nó, không thay thế. Nếu bạn thực sự cần một ID nội bộ (cho message queue hoặc job nền), giữ bản gốc như trường parent để câu chuyện vẫn nối được.
Một khoảng trống phổ biến khác là ghi log không đầy đủ. Các đội thêm ID vào API đầu nhưng quên nó trong process worker, scheduled jobs, hoặc layer truy cập database. Kết quả là dead end: bạn thấy request vào hệ thống nhưng không biết nó đi đâu tiếp theo.
Tránh vấn đề "nhiễu tên"
Ngay cả khi ID có ở mọi nơi, vẫn khó tìm nếu mỗi service dùng tên trường hoặc định dạng khác nhau. Chọn một tên và giữ nó trên frontend, API và logs (ví dụ correlation_id). Cũng chọn một định dạng (thường là UUID), và coi nó phân biệt chữ hoa/chữ thường để copy-paste hoạt động.
Đừng để ID mất khi có lỗi. Nếu API trả 500 hoặc lỗi validate, đưa correlation ID trong phản hồi (và tốt nhất là cả header). Khi đó người dùng có thể paste vào chat hỗ trợ, và đội bạn có thể ngay lập tức đi theo đường dẫn đầy đủ.
Một bài kiểm tra nhanh: nhân viên hỗ trợ có thể bắt đầu từ một ID và theo nó qua mọi dòng log liên quan, kể cả failures?
Checklist nhanh để xác nhận độ phủ end-to-end
Dùng đây như kiểm tra trước khi bảo hỗ trợ "chỉ cần tìm trong logs." Cách này chỉ hoạt động khi mọi hop tuân theo cùng quy tắc.
Các kiểm tra bắt buộc
- Bạn có một định dạng ID và một tên header duy nhất, dùng ở mọi nơi (frontend, gateway, API, worker).
- Frontend tạo (hoặc nhận) ID khi bắt đầu hành động người dùng và giữ nó ổn định đến khi hành động kết thúc.
- API entry point tạo ID nếu thiếu và luôn trả lại nó trong response headers.
- Mọi backend service bao gồm
correlation_idtrong logs liên quan đến request như một trường có cấu trúc. - On-call có thể dán một ID vào công cụ tìm kiếm log và thấy toàn bộ đường dẫn trong vài phút: request edge, auth, các cuộc gọi service, thao tác database và retry.
Nếu có kiểm tra thất bại, sửa như sau
Chọn thay đổi nhỏ nhất giữ cho chuỗi không bị đứt.
- Nếu ID thay đổi giữa chặng, ngưng sinh ID mới trong service nội bộ. Giữ
correlation_idgốc và thêmspan_idnếu cần chi tiết hơn. - Nếu logs thiếu trường, thêm middleware logging để engineer không phải nhớ bật nó.
- Nếu hỗ trợ không lấy được ID, đảm bảo UI hiển thị nó trên màn hình lỗi và gateway echo lại trong mọi phản hồi.
Một bài kiểm tra nhanh bắt lỗi: mở devtools, thực hiện một hành động, sao chép correlation ID từ request đầu, rồi xác nhận bạn thấy cùng giá trị trong mọi request API liên quan và mọi dòng log tương ứng.
Bước tiếp theo: nhúng vào quy trình phát hành
Correlation ID chỉ hữu ích khi mọi người dùng cùng một cách, mọi lúc. Hãy coi hành vi correlation ID như một phần bắt buộc của việc phát hành, không phải một tweak logging tuỳ ý.
Thêm bước traceability nhỏ vào định nghĩa hoàn thành (definition of done) cho mọi endpoint hoặc hành động UI mới. Bao gồm cách ID được tạo (hoặc tái sử dụng), nơi nó tồn tại trong flow, header nào mang nó, và dịch vụ sẽ làm gì khi header thiếu.
Một checklist nhẹ thường đủ:
- Frontend: sinh hoặc tái dùng một ID cho mỗi hành động người dùng, và đính nó vào mọi cuộc gọi API cho hành động đó.
- API entry point: chấp nhận header, validate hoặc sinh, rồi echo lại trong phản hồi.
- Backend: truyền nó đến downstream services và jobs, và đưa vào logs.
- Logging: giữ tên trường nhất quán (ví dụ,
correlation_id) trên mọi app và service. - Reviews: từ chối PR thêm endpoint mà không có test chứng minh ID xuất hiện trong logs.
Hỗ trợ cũng cần một script đơn giản để gỡ lỗi nhanh và lặp lại. Quyết định nơi ID xuất hiện cho người dùng (ví dụ nút "Copy debug ID" trên các dialog lỗi), và ghi rõ hỗ trợ nên hỏi gì và tìm ở đâu.
Trước khi dựa vào nó ở production, chạy một flow staged giống dùng thực tế: nhấn nút, gây lỗi validate, rồi hoàn tất action. Xác nhận bạn có thể theo cùng một ID từ request trình duyệt, qua logs API, vào worker nền, và tới log câu lệnh database nếu bạn ghi chép chúng.
Nếu bạn xây dựng app trên Koder.ai, sẽ có lợi khi viết quy ước header và logging cho correlation ID vào Planning Mode để frontend React và dịch vụ Go được sinh ra mặc định theo cùng tiêu chuẩn.
Câu hỏi thường gặp
What is a correlation ID in plain terms?
Một ID tương quan là một mã định danh duy nhất gắn với mọi thứ liên quan đến một hành động hoặc workflow của người dùng — từ trình duyệt, API, dịch vụ đến các worker. Nó cho phép bộ phận hỗ trợ bắt đầu từ một ID duy nhất và kéo ra toàn bộ dòng thời gian thay vì phải đoán các dòng nhật ký liên quan.
When should I use a correlation ID instead of a session ID or request ID?
Dùng ID tương quan khi bạn muốn gỡ lỗi một sự cố end-to-end cho một hành động cụ thể, ví dụ “nhấn Pay và bị lỗi”. Session ID quá rộng vì nó bao phủ nhiều hành động, còn request ID thì quá hẹp vì chỉ áp dụng cho một yêu cầu HTTP và sẽ thay đổi khi retry.
Where should the correlation ID be created: frontend or backend?
Nên tạo ID ở frontend ngay khi bắt đầu hành động của người dùng (submit form, nhấn nút, bắt đầu flow). Làm vậy giữ lại phần sớm nhất của câu chuyện — lỗi UI, retry, hoặc request bị hủy — thay vì để backend sinh ID và có thể bỏ lỡ những bước đầu.
What format should a correlation ID use?
Dùng một giá trị dạng UUID hoặc tương tự, mờ (opaque), dễ sao chép và an toàn để chia sẻ trong ticket. Không mã hóa dữ liệu cá nhân, email, số đơn hàng hay timestamps vào ID; những ngữ cảnh đó nên nằm trong các trường log riêng và có kiểm soát quyền riêng tư.
What header and log field name should we standardize on?
Chọn một tên header chuẩn và dùng nó ở mọi nơi, ví dụ X-Correlation-ID, và lưu log dưới một trường có cấu trúc nhất quán như correlation_id. Tính nhất quán quan trọng hơn tên cụ thể, vì bộ phận hỗ trợ cần một giá trị cố định để tìm kiếm.
Should a retry reuse the same correlation ID or generate a new one?
Giữ cùng một correlation ID cho các retry nếu đó vẫn là cùng một hành động của người dùng, để các log được nối với nhau. Chỉ tạo ID mới khi người dùng bắt đầu một lần thử mới như nhấn nút lần nữa sau đó.
What should the API gateway or first service do if the header is missing?
Entry point của API nên chấp nhận ID nếu client gửi, và sinh ID mới nếu thiếu hoặc không hợp lệ. Đồng thời echo lại ID trong header phản hồi (kể cả lỗi) để người dùng và hỗ trợ có thể sao chép từ UI hoặc màn hình debug.
How do we propagate the correlation ID across microservices and background jobs?
Đưa ID vào ngữ cảnh request và sao chép nó vào mọi cuộc gọi xuống hạ tầng, gồm HTTP/gRPC nội bộ và job queue. Tránh tạo ID mới giữa chặng; nếu cần phân biệt chi tiết hơn, thêm một identifier nội bộ riêng mà không làm đứt chuỗi ban đầu.
What needs to be in logs for correlation IDs to actually help support?
Log nó như một trường có cấu trúc ưu tiên (không chôn trong chuỗi message), để có thể tìm và lọc. Kèm theo vài trường thiết thực như tên service, route, status, duration và một định danh an toàn của người dùng; đảm bảo lỗi cũng log ID để đường dẫn không bị cắt ở thời điểm quan trọng nhất.
How can we quickly verify we have true end-to-end coverage?
Thử: kích hoạt một hành động, sao chép correlation ID từ request đầu tiên hoặc màn hình lỗi, rồi xác nhận giá trị đó xuất hiện trong mọi header request liên quan và mọi dòng log của dịch vụ xử lý workflow. Nếu ID biến mất ở worker, retry hoặc phản hồi lỗi, đó là chỗ cần sửa.