Conversation
`--addon` was declared and documented on the command, but the handler threw
`Access Logs are not available for add-ons yet` right away.
The API has been able to serve them all along: the v4 endpoint reads
`/v4/accesslogs/organisations/{ownerId}/applications/{id}/accesslogs`, but its
`applications` path segment is a misnomer. Server side that segment is parsed as
a `LoggableId`, a union accepting every add-on prefix (`redis_`, `postgresql_`,
`cellar_`, `pulsar_`…), and the handler then just reads the Pulsar topic named
after it. Nothing along that path is application specific.
Add-ons are therefore resolved with `resolveAddon` and their real ID is passed
as the stream resource. The real ID matters: it is the topic name, an `addon_`
ID matches no topic at all and would silently stream nothing.
Verified against production on a Redis add-on.
Access logs carry no `http` section when the connection is cut before the
request line is parsed, when it goes through a TCP redirection, and for every
add-on exposed over raw TCP (Redis, PostgreSQL, MongoDB…). Both human and CLF
formatters silently skipped those, so `clever accesslogs` on such an add-on
printed nothing at all while the stream was in fact delivering events.
The human format now renders them on their own line, keeping the exact same
columns as HTTP lines so a mixed stream stays aligned: `TCP` where the status
code sits, connection details where the request line sits.
2026-08-13T05:31:10.793Z 91.231.89.104 FR/Gravelines TCP :53171 0B↑ 0B↓
The destination is dropped, it is the load balancer rather than the resource.
The target VM is printed only when the platform actually filled it, add-ons
leave it at the nil UUID today.
CLF keeps skipping them on purpose: it describes an HTTP request, a line with
neither request line nor status is not parsable by grok or GoAccess.
The command shipped in 2.1.0 and the endpoint it consumes is stable, the banner printed on every human run is just noise now.
|
🔎 A preview has been automatically published! If you created the alias to the preview script, you can run this command to download and install this preview: clever-preview update feat-accesslogs-addonsYou can also run it from your local repository: ./scripts/preview.js update feat-accesslogs-addons
This preview will be deleted once this PR is closed. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1126
What
clever accesslogs --addon <id>now works. The option was already declared and documented, but the handler threwAccess Logs are not available for add-ons yetbehind a// TODO: drop when add-ons are supported in API.Why the TODO was stale
The v4 endpoint reads
/v4/accesslogs/organisations/{ownerId}/applications/{id}/accesslogs, and thatapplicationssegment is a misnomer. Server side it is parsed as aLoggableId, a union accepting every add-on prefix (redis_,postgresql_,cellar_,pulsar_,keycloak_,otoroshi_…), and the handler then reads the Pulsar topic named after that ID. Nothing along that path is application specific — the API has been able to serve add-on access logs all along.The real ID is what matters: it is the topic name. An
addon_ID matches no topic and would silently stream nothing, so add-ons go throughresolveAddonfirst, exactly likeclever logs --addonalready does. Both ID forms work for the user.TCP access logs were being dropped
Add-ons exposed over raw TCP emit access logs with no
httpsection (so do TCP redirections on applications, and connections cut before the request line is parsed). Both thehumanandclfformatters skipped any log wherelog.http == null— meaning that without this second fix, the command would have connected, received events, and printed nothing.The human format now renders them, keeping the exact same columns as HTTP lines so a mixed stream stays aligned:
TCPwhere the status code sits, connection details where the request line sits.The destination is dropped, it is the load balancer rather than the resource. The target VM is printed only when the API resolved it.
clfkeeps skipping these on purpose: it describes an HTTP request, and a line with neither request line nor status is not parsable by grok or GoAccess.Two platform-side gaps, not addressed here
Observed in production across four add-ons:
bytesIn/bytesOutare always0, andinstanceIdis the nil UUID on Redis/PostgreSQL — but a real VM UUID on Elasticsearch. The CLI renders both correctly whenever the platform provides them; nothing more can be done client side.server_name, which is a bare UUID for some providers (c958d0a5-…) and<real_id>_<index>for others (postgresql_bde3942f-…_0) — see the access-logs-forwarder parser fixtures. The API parses that string as a UUID-typedInstanceIDand silently substitutes the nil UUID when it fails, so the information is dropped for a whole class of providers. Fix belongs in the API'sAccessLogView(or in a uniform load balancer server naming).protocolequals the literal string"TCP", and the v3→customer-avro conversion then defaults the counters to0when that envelope is absent. Needs confirmation by reading the raw customer topic (thesourceandproxy_hostnamefields, which the API drops, identify the emitter).Also for the record: the API hardcodes
region/zoneto""andtlstonullin its mapping — dead fields in the payload.Also
Drops the
/!\ This feature is in Beta testing phasebanner: the command shipped in 2.1.0 and the endpoint is stable.Testing
npm run validatepasses (lint, prettier, tsc, docs). Manually verified against production on Redis, PostgreSQL and Elasticsearch add-ons, with bothaddon_and real ID forms, acrosshuman,json,json-streamandclfformats.