OAuth2 Observability Design
The system integrates complete Prometheus monitoring metrics and structured, context-aware logging, supporting real-time monitoring and troubleshooting in production.
1. Prometheus Metrics
The system exposes standard Prometheus metrics through an exporter.
1.1 Metric List
| Metric | Type | Labels | Description |
|---|---|---|---|
oauth2_requests_total | Counter | endpoint, status | Total OAuth2 requests |
oauth2_login_failures_total | Counter | reason | Login failures |
oauth2_introspect_requests_total | Counter | client_id | Total token introspection requests |
oauth2_introspect_errors_total | Counter | client_id, error | Introspection errors |
oauth2_revocation_requests_total | Counter | client_id | Total token revocation requests |
oauth2_revocation_errors_total | Counter | client_id, error | Revocation errors |
oauth2_latency_seconds | Histogram | operation, storage | Latency distribution of key steps (including storage backend) |
oauth2_active_tokens | Gauge | — | Current estimate of active (unexpired) tokens |
Metrics are emitted uniformly by
libs/drogon/src/observability/Metrics.ccandlibs/drogon/src/adapters/DrogonMetrics.cc(as[METRIC]structured logs viaLOG_INFO, consumed by PromExporter/log collectors); definitions live inlibs/drogon/include/fulla/drogon/observability/Metrics.h.
1.2 Sample Dashboard Panels (Grafana)
Recommended panels:
- QPS & Error Rate:
rate(oauth2_requests_total[1m])vsrate(oauth2_login_failures_total[1m]) - P99 Latency:
histogram_quantile(0.99, rate(oauth2_latency_seconds_bucket[1m])) - Business: Active tokens trend.
2. Structured Logging
The system uses context-aware structured logging that Splunk/ELK can easily collect and analyze.
2.1 Audit Logs
Critical security operations (such as token issuance) emit logs tagged with [AUDIT].
Format:
[AUDIT] Action={Action} User={UserId} Client={ClientId} Success={True/False} IP={RemoteAddr}
Example:
2026-01-18 10:00:00 INFO [AUDIT] Action=IssueToken User=admin Client=vue-client Success=True
2026-01-18 10:05:00 WARN [AUDIT] Action=ExchangeCode User=admin Client=vue-client Success=False Reason="Replay Detected"
2.2 Contextual Logs
Along the request-processing chain, every log line automatically carries a RequestId for correlation in distributed tracing.
LOG_INFO << "Processing request"; // 输出: [ReqId: abc-123] Processing request
3. Configuration and Integration
3.1 Enabling Metrics
By default the metrics exporter listens on the /metrics endpoint (the exporter must be enabled in the Drogon configuration file).
3.2 Log Levels
The system uses six log levels throughout, mapping one-to-one to Drogon/Trantor's built-in levels (trace < debug < info < warn < error < fatal):
| Level | Meaning | Typical scenarios |
|---|---|---|
trace | Finest-grained tracing | Function inputs/outputs, loop iterations, line-by-line execution traces — for deep debugging and pinpointing |
debug | Debug information | Variable values, branch decisions, internal state changes — for troubleshooting during development |
info | Routine information | Service start/stop, key flow milestones, user logins, task completion and other normal business events |
warn | Warnings | Recoverable anomalies, degraded handling, configuration falling back to defaults, resources nearing thresholds — the system still runs normally |
error | Errors | Feature failures, request errors, database connection failures — affect a single operation but the service remains available overall |
fatal | Fatal errors | Severe faults that crash the service or prevent it from running; requires immediate alerting and human intervention |
Conventions:
- Production enables
infoand above by default;trace/debugare enabled dynamically on demand. - Higher levels log less;
fatalshould be extremely rare. apps/server/config/config.prod.jsondefaults toINFO,config.dev.jsondefaults toDEBUG, andconfig.json/config.ci.jsondefault toDEBUG.
Dynamic adjustment: edit the app.log.log_level field in the configuration file; allowed values are TRACE/DEBUG/INFO/WARN/ERROR/FATAL (case-insensitive):
"app": {
"log": {
"log_level": "INFO"
}
}
Code conventions:
- The domain layer (
libs/common,libs/oauth2,libs/identity) must not use Drogon'sLOG_*macros directly; it must go through thefulla::common::ports::ILoggerport so that unit tests can capture and assert withFakeLogger. - The adapter / infrastructure layer (
libs/drogon,libs/storage-*,apps/server) may useLOG_*macros directly. - Six-level mapping:
LogLevel::Trace→LOG_TRACE,Debug→LOG_DEBUG,Info→LOG_INFO,Warn→LOG_WARN,Error→LOG_ERROR,Fatal→LOG_FATAL.
For the test-output minimization strategy (ctest prints only failed cases and a summary by default), see testing-guide.md.