Skip to content

logging: add requestID for access logs, application logs and traceback logs - #1064

Open
boddumanohar wants to merge 3 commits into
mainfrom
logs-add-requestid
Open

logging: add requestID for access logs, application logs and traceback logs#1064
boddumanohar wants to merge 3 commits into
mainfrom
logs-add-requestid

Conversation

@boddumanohar

@boddumanohar boddumanohar commented May 26, 2026

Copy link
Copy Markdown
Member

currently in the WebApp API we have see 3 types of logs:

  1. Access logs --> ex: POST /cluster/<uid>.. 20ms "Go client
  2. Application logs --> ERROR: failed to clone volume
  3. Traceback logs --> Traceback: ...

To allow us to connect all these 3 together, have added a new field request_id to the logging filter.

So at the start of the request, within the middleware, we inject the request_id

token = core_utils.request_id_var.set(request_id)

and then reset it after the request ends

core_utils.request_id_var.reset(token)

But since the update has been to the core logger, simplyblock_core/utils/__init__.py for CLI, output, we'll see the extra [-] in between.

@boddumanohar
boddumanohar requested a review from mxsrc May 28, 2026 10:14
@boddumanohar
boddumanohar force-pushed the logs-add-requestid branch 2 times, most recently from c8c2b11 to 37c5276 Compare June 24, 2026 10:22

@mxsrc mxsrc left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally I like this, but in the case of sbctl execution, instead of -, establishing a context var with some random hash might be helpful

…s it

get_logger() wraps the stderr handler in a QueueHandler/QueueListener for
non-blocking logging: the listener formats and filters each record on its
own background thread. RequestIdFilter reads a contextvars.ContextVar set
by the request-handling thread, but ContextVars aren't inherited by a
plain threading.Thread — so with the filter on the handler, it would
always read the default '-' instead of the real request ID once records
started flowing through the queue.

Attach the filter to the logger instead: Logger.filter() runs
synchronously on the emitting thread before the record is queued, so
record.request_id is captured in the right context and just carried
through by the listener.
Copilot AI review requested due to automatic review settings August 3, 2026 08:06
@boddumanohar

Copy link
Copy Markdown
Member Author

rebased the PR. @mxsrc can you please re-review.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a per-request request_id to correlate FastAPI access logs, application logs, and traceback logs by propagating a request-scoped identifier via contextvars and injecting it into log records.

Changes:

  • Add a request_id_var ContextVar and RequestIdFilter to attach request_id onto log records in simplyblock_core.utils.
  • Inject/reset request_id in the web request middleware and include it in access log formatting.
  • Initialize a request_id for CLI runs to avoid placeholder [-] values in CLI log output.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
simplyblock_web/app.py Generates/propagates request_id per request and adds it to access log output.
simplyblock_core/utils/init.py Adds ContextVar + log filter and updates the core log formatter to include request_id.
simplyblock_cli/clibase.py Seeds a CLI-scoped request_id so CLI logs can include a stable correlation ID.
Suppressed comments (1)

simplyblock_web/app.py:86

  • request_id_var.reset(token) should be guaranteed even if access-log emission fails (e.g., handler/formatting issues). Wrap the access log call in try/finally and reset in the finally so the contextvar is always cleared.
        core_utils.request_id_var.reset(token)
        return response

Comment thread simplyblock_web/app.py
Comment on lines +64 to +68
except Exception:
logger.exception('Unhandled exception during %s %s (%.1fms)',
request.method, path, (time.monotonic() - start) * 1000)
core_utils.request_id_var.reset(token)
raise
Comment thread simplyblock_web/app.py
Comment on lines +54 to +55
request_id = request.headers.get('x-request-id') or uuid.uuid4().hex[:8]
token = core_utils.request_id_var.set(request_id)
Comment on lines +743 to +747
# Filter is on the logger, not the handler: it must run synchronously
# on the emitting thread to read the caller's contextvars.ContextVar,
# before the record crosses into the QueueHandler/listener thread
# below (which has no access to the emitting thread's context).
logg.addFilter(RequestIdFilter())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants