Skip to content

feat(events): expose user_agent and client_ip in /v1/events#5

Merged
bravo1goingdark merged 1 commit into
mainfrom
feat/expose-user-agent-client-ip
May 5, 2026
Merged

feat(events): expose user_agent and client_ip in /v1/events#5
bravo1goingdark merged 1 commit into
mainfrom
feat/expose-user-agent-client-ip

Conversation

@bravo1goingdark
Copy link
Copy Markdown
Owner

Summary

Both fields are already accepted on ingest and stored in the label table (`LABEL_CLIENT_IP=3`, `LABEL_USER_AGENT=4`) — they survive the event roundtrip into `LlmEvent`. This change just plumbs them through the read path so `/v1/events` consumers can derive SDK / geographic breakdowns without re-querying the raw event row.

  • `EventSummary` (keplor-store/types.rs) gains `client_ip` + `user_agent`.
  • `llm_to_summary` copies them from the underlying `LlmEvent`.
  • `EventResponse` (keplor-server/routes.rs) gains the same two fields, serialized with `skip_serializing_if = Option::is_none` so events without recorded IP/UA stay compact on the wire.
  • `export_events` and the s3 archive-merge path mirror the change.

No schema change. No new column read on the hot path.

This unblocks Obol PR (forthcoming) that adds SDK + geographic widgets to `/monitor`.

Test plan

  • `cargo build --workspace` clean
  • `cargo test --workspace` — all suites pass
  • `cargo clippy --workspace --all-targets -- -D warnings` — clean
  • After deploy on prod VM: send a request with `User-Agent: openai-python/1.42` to a live endpoint and verify both fields appear in `/v1/events` JSON

Both fields are already accepted on ingest and stored in the label
table (LABEL_CLIENT_IP=3, LABEL_USER_AGENT=4) — they survive the
event roundtrip into LlmEvent. This change just plumbs them through
the read path so /v1/events consumers can derive SDK / geographic
breakdowns without re-querying the raw event row.

- EventSummary (keplor-store/types.rs) gains client_ip + user_agent.
- llm_to_summary copies them from the underlying LlmEvent.
- EventResponse (keplor-server/routes.rs) gains the same two fields,
  serialized with skip_serializing_if = Option::is_none so events
  without recorded IP/UA stay compact on the wire.
- export_events and the s3 archive-merge path mirror the change.

No schema change. No new column read on the hot path.
@bravo1goingdark bravo1goingdark merged commit 6422033 into main May 5, 2026
5 checks passed
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.

1 participant