feat(api): log inbound User-Agent on management API and webhook receiver
Astrolabe (and any other PHP-side client) sends a stable User-Agent on
every outbound call to the MCP server. Capture it at the middleware
layer so backend access logs can attribute each request to a specific
client build — e.g. ``Nextcloud-Astrolabe/0.14.1``.
The middleware fires only for /api/v1/* and /webhooks/nextcloud,
which is the surface PHP-side clients hit; /mcp and /health stay
silent. The structured ``extra`` ({user_agent, http_method, http_path})
flows into OTel spans so the field is queryable in Grafana / Loki.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
fdcbd7bd3f
commit
7da72a3888
@@ -2475,6 +2475,29 @@ def get_app(transport: str = "streamable-http", enabled_apps: list[str] | None =
|
|||||||
response = await call_next(request)
|
response = await call_next(request)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
# Log the inbound User-Agent on management API and webhook receiver routes
|
||||||
|
# so we can tell which Astrolabe (or other PHP-side client) build is
|
||||||
|
# talking to the backend. Astrolabe sends ``Nextcloud-Astrolabe/<version>``.
|
||||||
|
_UA_LOGGED_PATH_PREFIXES = ("/api/v1/", "/webhooks/nextcloud")
|
||||||
|
|
||||||
|
@app.middleware("http")
|
||||||
|
async def log_client_user_agent(request, call_next):
|
||||||
|
path = request.url.path
|
||||||
|
if path.startswith(_UA_LOGGED_PATH_PREFIXES):
|
||||||
|
ua = request.headers.get("user-agent") or "(none)"
|
||||||
|
logger.info(
|
||||||
|
"%s %s from %s",
|
||||||
|
request.method,
|
||||||
|
path,
|
||||||
|
ua,
|
||||||
|
extra={
|
||||||
|
"user_agent": ua,
|
||||||
|
"http_method": request.method,
|
||||||
|
"http_path": path,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
return await call_next(request)
|
||||||
|
|
||||||
# Add CORS middleware to allow browser-based clients like MCP Inspector
|
# Add CORS middleware to allow browser-based clients like MCP Inspector
|
||||||
app.add_middleware(
|
app.add_middleware(
|
||||||
CORSMiddleware, # type: ignore[invalid-argument-type]
|
CORSMiddleware, # type: ignore[invalid-argument-type]
|
||||||
|
|||||||
Reference in New Issue
Block a user