Feature: Frontend and app observability on OTel semconv (lts) (#17541)
* Feature: Frontend and app observability on OTel semconv (lts-3.16 port)
Port of #17434 (feat/frontend-metrics-lean, base main) onto lts-3.16.
Squashed diff applied 3-way; lts-specific resolutions:
- jwt.strategy: only extractAppIdFromPath/appId (no admin-API-key flow on lts)
- data-queries: appName from appToUse (no branch metadata on lts)
- session util: keep lts ability imports, drop session metric calls
- database.helper: export getConnectionInstance, add getDBConnection (present on main)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(otel): read app names from apps.name on lts, isolate lookup failure
lts-3.16 has no app_versions.app_name column (branch-aware metadata is
main-only), so the ported APP_NAME_QUERY threw on every seat poll and, being
inside the same try as SEAT_QUERY, silently kept the whole seat/role/org-name
snapshot empty. Query apps.name instead and wrap the optional lookup in its own
try/catch so it can never take the seat snapshot down.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Feature: Stream server logs to OTEL, readable log levels in prod (#17561)
* feat(logging): implement OtelLogStream for OpenTelemetry log streaming
* feat(logging): enhance logging with OpenTelemetry integration and sensitive data redaction
* feat(logging): enhance OtelLogStream to include LogAttributes and improve error handling
* feat(logging): refactor logging structure and enhance sensitive data redaction
* refactor to use TransactionLogger in CustomDomainCacheService and CustomDomainStatusScheduler
* refactor(logging): drop OTEL_LOGS_LEVEL, one level for both destinations
LOG_LEVEL now sets the pino instance level and that is the only filter in
the system — stdout and the OTLP stream receive exactly the same records.
A line visible in `docker logs` is a line in the logs backend, and vice versa.
level:0 on both multistream legs is required, not decorative: multistream's
own per-stream default is 'info', so omitting it would silently clamp a
LOG_LEVEL of debug/trace on both destinations.
If the backend ever needs to be quieter than the console, that belongs in the
collector's filter processor rather than a second app-side knob.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* chore(logging): trim comments to the non-obvious
Five-line rationale block reduced to the one thing the code cannot say:
multistream's per-stream default is 'info', so the explicit 0 is required.
The rest — why one level, where to filter instead — belongs in the docs, not
above the call site.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* test(logging): guard the invalid-LOG_LEVEL boot path, clarify env docs
pino throws on an unknown level, so validLevel() is the only thing between a
typo'd LOG_LEVEL and a failed boot. That path lost its only coverage when the
OTEL_LOGS_LEVEL tests went — LOG_LEVEL is now the sole knob, so it needs its own.
.env.example: LOG_LEVEL now drives the logs backend as well as docker logs, and
at the default (warn) per-request access logs reach neither. Say so where an
operator reads it, and fold the orphaned OTLP comment back onto the variable it
describes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* chore: bump version to 3.20.214-lts across all components
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Adish M <44204658+adishM98@users.noreply.github.com>