Link logs to a person

PostHog can surface every log emitted on behalf of a specific user on that user's profile in the Logs tab. The link is attribute-based: each log carries a person identifier as an OpenTelemetry log attribute, and PostHog matches it to a person's distinct_id.

When logs are linked to a person you can:

  • Debug a specific user's issue: jump from the person's profile straight to every backend log written while they were active, no service-name guessing.
  • Trace failures across services: frontend SDK logs, backend OTel logs, and any other source converge under one identity.
  • Pivot from logs to other product data: events, recordings, feature flags, and surveys are all on the same person.

Prerequisites

  • Logs is enabled for your project.
  • A logging client installed on your backend (or you use the JavaScript / React Native SDKs which handle this automatically — see below).
  • Each log record carries the person identifier as an attribute. By default the attribute key is posthogDistinctId — the same key the PostHog JavaScript SDK and React Native SDK auto-attach.

Logs captured client-side: When you call posthog.captureLog / posthog.logger.* from the JavaScript web SDK or React Native SDK, the current distinct_id is attached as posthogDistinctId on every log automatically. No further setup needed.

Implementation

Backend (OpenTelemetry)

When you emit logs directly via OpenTelemetry from a backend — Python, Go, Node.js without posthog.logger, or your own collector pipeline — add posthogDistinctId to each log record's attributes. Set it to the same distinct_id you use when calling posthog.capture.

import { logs } from '@opentelemetry/api-logs'
const logger = logs.getLogger('my-app')
app.post('/api/checkout', async (req, res) => {
const userId = req.userId // ... get your user ID
logger.emit({
severityText: 'info',
body: 'Checkout completed',
attributes: {
posthogDistinctId: userId, // Links to PostHog person
orderId: 'A-123',
},
})
res.json({ success: true })
})

Note: PostHog matches the value against every distinct_id we know about for the person, so as long as the value matches one of their identifiers, the log will appear on the profile. Identified-after-anonymous flows still link correctly.

  1. Send a log carrying posthogDistinctId set to a known user.
  2. Open that user's profile in the People tab.
  3. Open the Logs tab. The log appears within a few seconds.

If the log does not appear, check:

  • Attribute key spelling: posthogDistinctId is camelCase with a lowercase p. PostHog matches it exactly. distinct_id, posthog_distinct_id, and user_id are not equivalent unless you've explicitly configured one of them — see Customizing the attribute key below.
  • Attribute value: must equal one of the person's distinct_ids. Prefixed or partial matches are not picked up.
  • The log's timestamp: the Logs tab respects the date range picker. Extend the range if the log is older than the default window.

Customizing the attribute key

If your pipeline emits the person identifier under a different key (for example user.id, customerId, or a legacy distinct_id), point PostHog at that key with the logs_config endpoint:

Terminal
curl -X PATCH "https://app.posthog.com/api/projects/<PROJECT_ID>/logs_config/" \
-H "Authorization: Bearer <PERSONAL_API_KEY>" \
-H "Content-Type: application/json" \
-d '{"logs_distinct_id_attribute_key": "user.id"}'

Only one key per project. Pick the key your pipeline actually emits — there is no fallback chain, so a log that lacks the configured key is unlinked from any person.

When the key has been customized, the person profile's Logs tab shows a small hint above the volume chart indicating which attribute is being used as the person pivot.

What this does not do

  • It does not retroactively re-link old logs after you change the configured key. Logs are matched at query time, so the new key applies as soon as it's saved, but logs ingested under the old key still need to match the configured key to appear on a person profile.
  • It does not link by IP, user-agent, or any other heuristic. Only attribute-value equality.
  • It does not affect ingestion. Logs without the configured attribute are stored normally; they're just not surfaced on any person profile.

See also

Community questions

Was this page useful?

Questions about this page? or post a community question.