Trong năm bài học trước của module này, bạn đã lần lượt tìm hiểu Sentry MCP là gì, cách kết nối nó với Claude Code CLI, OpenCode, Gemini CLI và Cursor. Đến bài học cuối cùng — bài học "capstone" — đã đến lúc ghép tất cả những mảnh ghép đó lại thành một câu chuyện thực chiến, đúng như những gì bạn sẽ gặp trong một ca trực on-call thật sự.
Kịch bản của chúng ta: checkout-service — service xử lý thanh toán trong hệ thống e-commerce — bắt đầu ném lỗi PaymentTimeoutError một cách ngắt quãng (intermittent) ngay sau một lần deploy gần đây. Sentry bắn alert. Bạn — engineer trực ca — mở Claude Code, và đi từ một dòng thông báo lỗi đến một PR (pull request — yêu cầu gộp mã nguồn) đã được merge và deploy, khép kín toàn bộ vòng đời xử lý sự cố (incident) chỉ trong một phiên làm việc với AI. Đây chính là giá trị thực của Sentry MCP: biến AI agent thành một cầu nối liền mạch giữa observability (khả năng quan sát hệ thống) và codebase.
Workflow Overview: From Sentry Alert to Deployed Bug Fix
Trước khi đi vào chi tiết từng bước, hãy nhìn toàn cảnh pipeline (quy trình xử lý) mà chúng ta sẽ thực hiện. Đây là quy trình chuẩn mà bạn có thể áp dụng cho bất kỳ issue (sự cố/lỗi được Sentry ghi nhận) nào trong production:
- Sentry alert fires — Sentry phát hiện
PaymentTimeoutErrorvượt ngưỡng (threshold) đã cấu hình trongcheckout-service, gửi cảnh báo qua Slack/email với issue ID, ví dụCHECKOUT-API-128. - Engineer mở Claude Code với Sentry MCP đã kết nối — bạn mở terminal, chạy
claude, agent đã có sẵn quyền truy cập vào toàn bộ dữ liệu Sentry qua MCP (Model Context Protocol — giao thức kết nối AI với công cụ/dữ liệu bên ngoài). - Pull issue — yêu cầu Claude Code lấy chi tiết issue: event (lần lỗi cụ thể được ghi nhận) mới nhất, stack trace (dấu vết ngăn xếp cuộc gọi hàm dẫn đến lỗi), breadcrumbs (dấu vết các hành động/sự kiện xảy ra trước khi lỗi phát sinh).
- AI thực hiện root cause analysis (RCA — phân tích nguyên nhân gốc rễ) — đối chiếu stack trace với source code thật, tra cứu lịch sử commit và release (bản phát hành) gần nhất.
- AI đề xuất fix (bản sửa lỗi) kèm regression test (bài kiểm thử hồi quy — đảm bảo lỗi không tái diễn).
- Engineer review diff — bạn đọc kỹ từng dòng thay đổi, không bao giờ apply mù quáng.
- Commit, push branch.
- Mở GitHub PR, tham chiếu (reference) tới Sentry issue.
- Deploy sau khi CI pass và được approve.
- Đánh dấu Sentry issue là resolved (đã giải quyết), gắn với next release (bản phát hành kế tiếp) — Sentry sẽ tự động regression-alert nếu lỗi này xuất hiện trở lại ở version mới hơn.
Trước khi bắt tay vào bất kỳ bước nào, hãy làm ba pre-flight check (kiểm tra trước khi bắt đầu) sau — bỏ qua bước này là nguyên nhân phổ biến nhất khiến workflow AI-assisted debug đi vào ngõ cụt giữa chừng:
claude mcp list
claude mcp add --transport http sentry https://mcp.sentry.dev/mcp
gh auth status
git status
git checkout main && git pull
Ba lệnh này chỉ mất khoảng 30 giây nhưng đảm bảo bạn không rơi vào tình huống dở khóc dở cười: code fix xong rồi mới phát hiện MCP mất kết nối giữa chừng, hoặc push nhầm lên một nhánh feature cũ còn sót lại từ tuần trước.
Mẹo: Hãy tạo một alias hoặc script nhỏ (ví dụ
preflight.sh) chạy cả ba lệnh kiểm tra trên cùng lúc mỗi khi bắt đầu ca trực on-call. Việc chuẩn hóa pre-flight check thành thói quen giúp giảm đáng kể thời gian phản ứng (MTTR — Mean Time To Resolution) khi có alert thật sự khẩn cấp.
Step 1: Pulling the Error Event, Stack Trace, and Breadcrumbs via MCP
Sau khi pre-flight check đã xong, bạn mở Claude Code ngay trong thư mục repo của checkout-service và bắt đầu với một prompt (câu lệnh/yêu cầu gửi cho AI) trực tiếp, cụ thể:
Get the latest event for issue CHECKOUT-API-128, show me the full stack trace
and the last 10 breadcrumbs before the error.
Claude Code sẽ gọi tool get_issue_details (hoặc tương đương, tùy phiên bản Sentry MCP server) để lấy dữ liệu, sau đó trình bày lại theo dạng dễ đọc. Output thực tế trông sẽ giống thế này:
Issue: CHECKOUT-API-128
Title: PaymentTimeoutError: Gateway did not respond within 3000ms
Culprit: checkout_service.payment.gateway_client in charge_customer
Level: error
Events: 47 in last 24h
First seen: 2026-07-07 14:22 UTC (release v2.14.0)
Last seen: 2026-07-09 09:41 UTC
--- Stack Trace ---
File "checkout_service/payment/gateway_client.py", line 88, in charge_customer
response = self.session.post(GATEWAY_URL, json=payload, timeout=3.0)
File "checkout_service/payment/gateway_client.py", line 41, in _send_request
return self._retry_with_backoff(request_fn)
File "checkout_service/payment/gateway_client.py", line 22, in _retry_with_backoff
raise PaymentTimeoutError("Gateway did not respond within 3000ms")
--- Breadcrumbs (last 10 before error) ---
1. [09:40:58] navigation User navigated to /checkout/review
2. [09:40:59] ui.click User clicked "Confirm Order" button
3. [09:41:00] http POST /api/cart/lock -> 200 OK (142ms)
4. [09:41:00] http POST /api/inventory/reserve -> 200 OK (89ms)
5. [09:41:01] info charge_customer() invoked for order_id=88213
6. [09:41:01] http POST https://payment-gateway.internal/charge -> (pending)
7. [09:41:02] info Retry attempt 1/3 triggered by _retry_with_backoff
8. [09:41:02] http POST https://payment-gateway.internal/charge -> (pending)
9. [09:41:04] info Retry attempt 2/3 triggered by _retry_with_backoff
10. [09:41:04] error PaymentTimeoutError raised after 3 attempts
Nhìn vào breadcrumb trail (chuỗi dấu vết hành vi), ta thấy ngay một chi tiết đáng chú ý: lỗi không xảy ra ngay lần gọi đầu tiên, mà xảy ra sau nhiều lần retry — và các request đều ở trạng thái "(pending)" chứ không hề nhận được response lỗi rõ ràng từ gateway. Đây là dấu hiệu kinh điển của một vấn đề timeout/connection, chứ không phải lỗi logic nghiệp vụ đơn thuần.
Bạn có thể đào sâu hơn bằng một prompt tiếp theo để xem issue này có tương quan (correlate) với release nào:
Which release introduced this issue, and how many distinct users are affected?
Also check if there are related issues in checkout-service tagged with the
same release version.
Sentry MCP sẽ trả về: issue bắt đầu xuất hiện từ v2.14.0, ảnh hưởng khoảng 12 user riêng biệt trong 24 giờ qua, với tỷ lệ xảy ra tăng dần vào các khung giờ cao điểm — một chi tiết quan trọng sẽ dẫn dắt bước phân tích tiếp theo.
Mẹo: Luôn yêu cầu AI lấy breadcrumbs (thường 10-20 mục gần nhất) chứ không chỉ dừng ở stack trace. Stack trace chỉ cho biết lỗi nổ ra ở đâu trong code, còn breadcrumb trail cho biết chuỗi sự kiện dẫn đến lỗi — đó là mảnh ghép còn thiếu để phân biệt giữa lỗi logic và lỗi do điều kiện môi trường/tải hệ thống (ví dụ: timeout khi traffic cao).
Step 2: AI Root Cause Analysis and Code Fix Proposal
Với dữ liệu đã có trong context window (cửa sổ ngữ cảnh — lượng thông tin AI có thể "nhớ" và xử lý cùng lúc trong một phiên làm việc), bạn giao cho Claude Code nhiệm vụ điều tra sâu hơn:
Correlate this stack trace with the actual source file gateway_client.py.
Check the git log for commits touching this file around release v2.14.0 to
see if anything changed the retry or timeout logic. Then give me a root
cause analysis (RCA — phân tích nguyên nhân gốc rễ).
Claude Code lúc này sẽ tự phối hợp nhiều tool: đọc file checkout_service/payment/gateway_client.py trong repo, chạy git log -p --since="2026-06-25" -- checkout_service/payment/gateway_client.py để soi lịch sử thay đổi, rồi đối chiếu ngược lại với dữ liệu Sentry đã lấy ở Step 1. Quá trình lý luận (reasoning) của AI thường được trình bày tường minh như sau:
- Đối chiếu stack trace với source thật: dòng 22 của
gateway_client.pygọi_retry_with_backoff, dòng 41 gọi_send_request, dòng 88 gọisession.post(..., timeout=3.0)— khớp hoàn toàn với stack trace từ Sentry. - Kiểm tra commit gần release v2.14.0:
git logcho thấy commita3f9c21— "Refactor payment gateway client to share HTTP session across requests" — được merge 2 ngày trước khi issue này xuất hiện lần đầu. Commit này thay đổi từ việc tạorequests.Session()mới cho mỗi request, sang dùng chung (share) một session object toàn cục giữa các thread xử lý đơn hàng đồng thời. - Xác định root cause: đây là race condition (điều kiện tranh chấp — nhiều luồng xử lý cùng truy cập một tài nguyên chia sẻ mà không đồng bộ hóa đúng cách). Khi nhiều order được xử lý đồng thời (concurrent), connection pool của session dùng chung bị cạn kiệt (exhausted) ở các khung giờ cao điểm, khiến một số request bị "kẹt" chờ connection khả dụng, dẫn đến timeout dù bản thân payment gateway vẫn phản hồi bình thường. Đây lý giải hoàn hảo lý do tỷ lệ lỗi tăng theo traffic — điều mà bước phân tích Sentry ở trên đã hé lộ.
- Vấn đề phụ:
_retry_with_backoffretry ngay lập tức mà không có backoff thật sự (không tăng dần thời gian chờ) và không tăng timeout giữa các lần retry — khiến 3 lần retry đều thất bại với cùng một nguyên nhân gốc, tốn thêm ~3 giây độ trễ vô ích cho user trước khi báo lỗi.
Sau khi trình bày RCA, Claude Code đề xuất một diff (bản chênh lệch mã nguồn) tối giản, đúng tinh thần "sửa đúng-đủ, không refactor lan man":
- self.session = requests.Session() # shared globally across requests
+ def _get_session(self) -> requests.Session:
+ """Return a thread-local session to avoid connection-pool contention
+ under concurrent checkout load (root cause of CHECKOUT-API-128)."""
+ if not hasattr(self._local, "session"):
+ self._local.session = requests.Session()
+ return self._local.session
def _retry_with_backoff(self, request_fn, max_retries=3):
for attempt in range(max_retries):
try:
- return request_fn()
+ return request_fn(timeout=3.0 + attempt * 2.0)
except requests.Timeout:
+ time.sleep(0.5 * (2 ** attempt)) # exponential backoff
if attempt == max_retries - 1:
raise PaymentTimeoutError(
f"Gateway did not respond after {max_retries} attempts"
)
Kèm theo đó là một regression test mới, mô phỏng đúng kịch bản concurrent request đã gây ra lỗi:
def test_concurrent_requests_do_not_share_session(gateway_client):
"""Regression test for CHECKOUT-API-128: ensure each thread gets its
own session so connection-pool contention cannot cause spurious
timeouts under concurrent checkout load."""
sessions_seen = []
def worker():
sessions_seen.append(id(gateway_client._get_session()))
threads = [threading.Thread(target=worker) for _ in range(20)]
for t in threads:
t.start()
for t in threads:
t.join()
assert len(set(sessions_seen)) == len(threads), (
"Expected each thread to receive an isolated session instance"
)
Đây là bước quan trọng nhất trong cả workflow: tuyệt đối không apply diff do AI đề xuất một cách mù quáng. Hãy tự tay chạy các bước review sau:
git status
git diff checkout_service/payment/gateway_client.py
pytest tests/ -v
pytest tests/payment/test_gateway_client.py -v --count=10
Chỉ khi toàn bộ test suite pass (bao gồm cả test cũ lẫn regression test mới) và bạn tự tin đã hiểu rõ tại sao fix này đúng — không phải chỉ vì AI nói vậy — mới chuyển sang bước tiếp theo.
Mẹo: Khi yêu cầu AI làm RCA, luôn thêm câu "explain your reasoning step by step, and cite the exact commit hash/line number for each claim" (giải thích quá trình lý luận từng bước, trích dẫn commit hash/số dòng cụ thể cho mỗi luận điểm). Điều này buộc AI phải bám sát bằng chứng thay vì suy đoán chung chung, đồng thời giúp bạn review nhanh và chính xác hơn.
Step 3: Opening a GitHub PR with the Fix Linked to the Sentry Issue
Sau khi đã review kỹ và test suite pass, đây là lúc đưa fix vào quy trình chuẩn của team: commit, push, mở PR (pull request), và quan trọng không kém — khép lại vòng lặp bằng cách liên kết ngược (link back) từ Sentry issue sang PR.
Bắt đầu bằng việc tạo nhánh (branch) mới, stage và commit thay đổi:
git checkout -b fix/checkout-api-128-payment-timeout
git add checkout_service/payment/gateway_client.py tests/payment/test_gateway_client.py
git commit -m "fix(payment): use thread-local session to prevent connection-pool
race condition
Resolves intermittent PaymentTimeoutError under concurrent checkout load.
Root cause: commit a3f9c21 introduced a shared requests.Session across
threads, causing connection-pool contention at peak traffic. Also adds
exponential backoff and progressive timeout to the retry logic.
Sentry: CHECKOUT-API-128"
git push -u origin fix/checkout-api-128-payment-timeout
Tiếp theo, tạo PR bằng GitHub CLI (gh pr create), với một PR body (nội dung mô tả PR) đầy đủ theo template chuẩn — bao gồm Summary, Root Cause, Testing, liên kết tới Sentry, và checklist:
gh pr create \
--title "fix(payment): resolve intermittent PaymentTimeoutError from shared session race condition" \
--body "$(cat <<'EOF'
## Summary
Fixes an intermittent `PaymentTimeoutError` in `checkout-service` that
started appearing after release v2.14.0. Under concurrent checkout load,
requests using a shared HTTP session were contending for a limited
connection pool, causing some requests to time out even though the
payment gateway itself was healthy.
## Root Cause
Commit a3f9c21 ("Refactor payment gateway client to share HTTP session
across requests") replaced a per-request `requests.Session()` with a
single session shared across all threads. At peak traffic, concurrent
checkout requests exhausted the shared connection pool, producing
timeouts that scaled with request volume — matching the breadcrumb
trail and event frequency observed in Sentry.
Fix: each thread now gets its own thread-local session
(`_get_session()`), removing the shared resource contention. The retry
logic also now uses exponential backoff and a progressively longer
timeout per attempt, instead of retrying immediately with the same
3-second timeout.
## Testing
- Added `test_concurrent_requests_do_not_share_session`, a regression
test that spins up 20 threads and asserts each receives an isolated
session instance.
- Ran the full test suite locally: `pytest tests/ -v` — all 214 tests
pass.
- Ran the new regression test 10x in a loop to rule out flakiness:
`pytest tests/payment/test_gateway_client.py -v --count=10` — all
pass.
## Sentry
Issue: https://sentry.io/organizations/our-org/issues/CHECKOUT-API-128/
Affected release: v2.14.0
Events: 47 in 24h, ~12 distinct users affected
## Checklist
- [x] Root cause identified and documented above
- [x] Minimal, targeted diff (no unrelated refactors)
- [x] Regression test added and passing
- [x] Full test suite passing locally
- [x] Sentry issue linked
- [ ] Reviewed and approved by at least one teammate
- [ ] Verified in staging before merge
EOF
)"
Sau khi tạo PR xong, lấy URL của PR để dùng cho bước tiếp theo:
gh pr view --json url --jq .url
Bước cuối cùng — thường bị bỏ quên nhưng lại là bước khép kín vòng lặp quan trọng nhất của cả workflow — là quay lại Sentry issue và để lại comment (bình luận) liên kết tới PR vừa tạo, để bất kỳ ai khác đang theo dõi issue này (support, QA, PM) cũng biết fix đã đang trong quá trình xử lý. Nếu Sentry MCP server bạn dùng hỗ trợ tool comment/update trực tiếp, bạn có thể yêu cầu Claude Code thực hiện luôn trong cùng phiên làm việc:
Add a comment on Sentry issue CHECKOUT-API-128 linking to
https://github.com/our-org/checkout-service/pull/482, noting that the
fix is in code review.
Claude Code sẽ gọi tool tương ứng (ví dụ update_issue hoặc create_issue_comment tùy phiên bản MCP server) để đăng comment tự động. Nếu MCP server hiện tại chưa hỗ trợ thao tác ghi (write) này, bạn vẫn có thể làm tương tự bằng cách gọi thẳng Sentry API qua curl như một phương án dự phòng (fallback):
curl -X POST \
"https://sentry.io/api/0/issues/CHECKOUT-API-128/comments/" \
-H "Authorization: Bearer $SENTRY_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"text": "Fix opened: https://github.com/our-org/checkout-service/pull/482 — root cause identified as a connection-pool race condition introduced in v2.14.0. In code review."
}'
($SENTRY_AUTH_TOKEN — auth token — mã xác thực truy cập API, nên được lưu trong biến môi trường hoặc secret manager, không bao giờ hard-code trực tiếp vào script hay commit vào repo.)
Sau khi PR được review, CI pass, và merge, quy trình được khép lại bằng bước deploy và đánh dấu issue resolved gắn với next release đúng như đã mô tả trong phần Workflow Overview: đội DevOps deploy bản build mới (ví dụ v2.14.3) chứa fix, sau đó bạn (hoặc tự động qua Sentry's release integration) đánh dấu CHECKOUT-API-128 là Resolved in next release. Từ thời điểm này, nếu PaymentTimeoutError xuất hiện trở lại ở bất kỳ version nào sau v2.14.3, Sentry sẽ tự động mở lại issue và gắn cờ regression (hồi quy — lỗi cũ tái xuất hiện) rõ ràng, thay vì âm thầm gộp chung với dữ liệu lỗi cũ đã xử lý.
Mẹo: Luôn đặt tên PR title theo convention nhất quán (ví dụ
fix(scope): mô tả ngắn gọn) và luôn nhắc tới Sentry issue ID trong cả commit message lẫn PR body. Thói quen này giúp việc tra cứu về sau — khi cần audit "issue này đã được fix trong PR nào, deploy ở version nào" — trở nên tức thời thay vì phải lục lại lịch sử Slack hay hỏi lại đồng nghiệp.
Qua toàn bộ ví dụ CHECKOUT-API-128, bạn đã đi trọn vẹn một vòng đời xử lý sự cố production: từ một dòng alert khô khan, qua Sentry MCP để lấy stack trace và breadcrumbs, để AI làm root cause analysis dựa trên bằng chứng thật (git log, source code), tự tay review từng dòng diff, cho đến khi mở PR liên kết ngược lại Sentry và đóng vòng lặp. Đây chính là mô hình làm việc mà Sentry MCP hướng tới: không phải để AI "tự động sửa lỗi thay bạn", mà để AI trở thành một cộng sự điều tra nhanh, chính xác, và luôn minh bạch bằng chứng — còn quyết định cuối cùng, luôn thuộc về engineer.