Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 34 additions & 7 deletions develop-docs/sdk/telemetry/logs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@
title: Logs
description: Structured logging protocol with severity levels, trace context, and batched envelope delivery.
spec_id: sdk/telemetry/logs
spec_version: 1.15.0
spec_version: 1.16.0
spec_status: stable
spec_depends_on:
- id: sdk/foundations/transport/envelopes
version: ">=1.0.0"
- id: sdk/foundations/state-management/scopes/attributes
version: ">=1.0.0"
spec_changelog:
- version: 1.16.0
date: 2026-02-06
summary: Added sentry.timestamp.sequence default attribute for deterministic log ordering
- version: 1.15.0
date: 2026-02-03
summary: Clarified 100 logs per envelope hard limit, SDKs MAY use lower buffer limit
Expand Down Expand Up @@ -153,6 +156,7 @@ SDKs **MUST** attach the following attributes to every log:
| `sentry.sdk.name` | 1.0.0 | The name of the SDK that sent the log. |
| `sentry.sdk.version` | 1.0.0 | The version of the SDK that sent the log. |
| `sentry.replay_id` | 1.8.0 | The replay ID of the active replay when the log was collected. **MUST NOT** be set if no replay is active. |
| `sentry.timestamp.sequence` | 1.16.0 | A monotonically incrementing integer counter used to determine correct ordering of logs when timestamps are identical. See [Log Ordering](#log-ordering). |

For parameterized logs, SDKs **MUST** also attach:

Expand Down Expand Up @@ -290,6 +294,23 @@ Logs **SHOULD** be associated with replays. If a log is recorded during an activ

</SpecSection>

### Log Ordering

<SpecSection id="log-ordering" status="candidate" since="1.16.0">

Some runtimes (notably Cloudflare Workers) freeze timer APIs (`Date.now()`, `performance.now()`) during synchronous execution, causing multiple logs to share identical timestamps. To guarantee deterministic ordering, SDKs **MUST** attach a `sentry.timestamp.sequence` integer attribute to every log.

The sequence number **MUST**:
- Start at `0` when the SDK initializes.
- Increment by `1` for each log that is captured.
- Reset to `0` when:
- The SDK is re-initialized.
- The current log's integer millisecond differs from the previous log's integer millisecond (i.e., `floor(timestamp_seconds * 1000)` changes).

The sequence provides deterministic ordering within a single SDK instance. It does not guarantee ordering across independent processes or workers, which have separate counters. The reset behavior ensures the sequence only increments for consecutive logs that share the same timestamp.

</SpecSection>

### Debug Mode

<SpecSection id="debug-mode" status="candidate" since="1.0.0">
Expand Down Expand Up @@ -563,7 +584,8 @@ A complete `log` envelope with six log entries at different severity levels:
},
"sentry.message.parameter.0": { "value": 120, "type": "integer" },
"sentry.message.parameter.1": { "value": 85, "type": "integer" },
"sentry.message.parameter.2": { "value": 60, "type": "integer" }
"sentry.message.parameter.2": { "value": 60, "type": "integer" },
"sentry.timestamp.sequence": { "value": 0, "type": "integer" }
}
},
{
Expand All @@ -588,7 +610,8 @@ A complete `log` envelope with six log entries at different severity levels:
"value": "ProductCard",
"type": "string"
},
"sentry.message.parameter.1": { "value": 3, "type": "integer" }
"sentry.message.parameter.1": { "value": 3, "type": "integer" },
"sentry.timestamp.sequence": { "value": 1, "type": "integer" }
}
},
{
Expand All @@ -613,7 +636,8 @@ A complete `log` envelope with six log entries at different severity levels:
"value": "checkout_form",
"type": "string"
},
"sentry.message.parameter.1": { "value": 8, "type": "integer" }
"sentry.message.parameter.1": { "value": 8, "type": "integer" },
"sentry.timestamp.sequence": { "value": 2, "type": "integer" }
}
},
{
Expand All @@ -639,7 +663,8 @@ A complete `log` envelope with six log entries at different severity levels:
"type": "string"
},
"sentry.message.parameter.1": { "value": 2500, "type": "integer" },
"sentry.message.parameter.2": { "value": 1000, "type": "integer" }
"sentry.message.parameter.2": { "value": 1000, "type": "integer" },
"sentry.timestamp.sequence": { "value": 3, "type": "integer" }
}
},
{
Expand All @@ -666,7 +691,8 @@ A complete `log` envelope with six log entries at different severity levels:
"sentry.message.parameter.0": {
"value": "prod_123, prod_456",
"type": "string"
}
},
"sentry.timestamp.sequence": { "value": 4, "type": "integer" }
}
},
{
Expand Down Expand Up @@ -695,7 +721,8 @@ A complete `log` envelope with six log entries at different severity levels:
"sentry.message.parameter.1": {
"value": "UPDATE_CART",
"type": "string"
}
},
"sentry.timestamp.sequence": { "value": 5, "type": "integer" }
}
}
]
Expand Down
38 changes: 32 additions & 6 deletions develop-docs/sdk/telemetry/metrics.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@
title: Metrics
description: Counter, gauge, and distribution metrics sent as batched trace_metric envelope items.
spec_id: sdk/telemetry/metrics
spec_version: 2.5.0
spec_version: 2.6.0
spec_status: stable
spec_depends_on:
- id: sdk/foundations/transport/envelopes
version: ">=1.0.0"
- id: sdk/foundations/state-management/scopes/attributes
version: ">=1.0.0"
spec_changelog:
- version: 2.6.0
date: 2026-02-06
summary: Added sentry.timestamp.sequence default attribute for deterministic metric ordering
- version: 2.5.0
date: 2026-02-12
summary: Clarified sendDefaultPii gating for user attributes — allowed when user manually sets data
Expand Down Expand Up @@ -114,6 +117,7 @@ SDKs **MUST** attach the following attributes to every metric by default:
2. `sentry.release` — the release set in the SDK, if defined.
3. `sentry.sdk.name` — the name of the SDK that sent the metric.
4. `sentry.sdk.version` — the version of the SDK that sent the metric.
5. `sentry.timestamp.sequence` — a monotonically incrementing integer counter used to determine correct ordering of metrics when timestamps are identical. See [Metric Ordering](#metric-ordering).

SDKs **SHOULD** minimize the number of default attributes. Metrics cardinality can explode quickly with too many attributes. New default attributes **SHOULD** only be added after significant feedback from users and discussion internally with the SDK and ingest teams.

Expand Down Expand Up @@ -187,6 +191,23 @@ Whenever possible, metrics **SHOULD** be linked to replays. If a metric is recor

</SpecSection>

### Metric Ordering

<SpecSection id="metric-ordering" status="candidate" since="2.6.0">

Some runtimes (notably Cloudflare Workers) freeze timer APIs (`Date.now()`, `performance.now()`) during synchronous execution, causing multiple metrics to share identical timestamps. To guarantee deterministic ordering, SDKs **MUST** attach a `sentry.timestamp.sequence` integer attribute to every metric.

The sequence number **MUST**:
- Start at `0` when the SDK initializes.
- Increment by `1` for each metric that is captured.
- Reset to `0` when:
- The SDK is re-initialized.
- The current metric's integer millisecond differs from the previous metric's integer millisecond (i.e., `floor(timestamp_seconds * 1000)` changes).

The sequence provides deterministic ordering within a single SDK instance. It does not guarantee ordering across independent processes or workers, which have separate counters. The reset behavior ensures the sequence only increments for consecutive metrics that share the same timestamp.

</SpecSection>

### Data Category and Rate Limiting

<SpecSection id="data-category-rate-limiting" status="stable" since="2.0.0">
Expand Down Expand Up @@ -547,7 +568,8 @@ SentrySDK.metrics()
"sentry.sdk.name": { "value": "sentry.javascript.browser", "type": "string" },
"sentry.sdk.version": { "value": "10.17.0", "type": "string" },
"sentry.environment": { "value": "production", "type": "string" },
"sentry.release": { "value": "1.0.0", "type": "string" }
"sentry.release": { "value": "1.0.0", "type": "string" },
"sentry.timestamp.sequence": { "value": 0, "type": "integer" }
}
},
{
Expand All @@ -562,7 +584,8 @@ SentrySDK.metrics()
"endpoint": { "value": "/api/users", "type": "string" },
"method": { "value": "POST", "type": "string" },
"sentry.sdk.name": { "value": "sentry.javascript.browser", "type": "string" },
"sentry.sdk.version": { "value": "10.17.0", "type": "string" }
"sentry.sdk.version": { "value": "10.17.0", "type": "string" },
"sentry.timestamp.sequence": { "value": 1, "type": "integer" }
}
},
{
Expand All @@ -577,7 +600,8 @@ SentrySDK.metrics()
"cache_name": { "value": "user_sessions", "type": "string" },
"region": { "value": "us-west-1", "type": "string" },
"sentry.sdk.name": { "value": "sentry.javascript.browser", "type": "string" },
"sentry.sdk.version": { "value": "10.17.0", "type": "string" }
"sentry.sdk.version": { "value": "10.17.0", "type": "string" },
"sentry.timestamp.sequence": { "value": 0, "type": "integer" }
}
},
{
Expand All @@ -593,7 +617,8 @@ SentrySDK.metrics()
"table": { "value": "users", "type": "string" },
"sentry.sdk.name": { "value": "sentry.javascript.browser", "type": "string" },
"sentry.sdk.version": { "value": "10.17.0", "type": "string" },
"sentry.origin": { "value": "auto.db.graphql", "type": "string" }
"sentry.origin": { "value": "auto.db.graphql", "type": "string" },
"sentry.timestamp.sequence": { "value": 1, "type": "integer" }
}
},
{
Expand All @@ -607,7 +632,8 @@ SentrySDK.metrics()
"cohort": { "value": "beta", "type": "string" },
"sentry.sdk.name": { "value": "sentry.javascript.browser", "type": "string" },
"sentry.sdk.version": { "value": "10.17.0", "type": "string" },
"sentry.replay_id": { "value": "36b75d9fa11f45459412a96c41bdf691", "type": "string" }
"sentry.replay_id": { "value": "36b75d9fa11f45459412a96c41bdf691", "type": "string" },
"sentry.timestamp.sequence": { "value": 0, "type": "integer" }
}
}
]
Expand Down
Loading