Skip to content
Open
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
43 changes: 36 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. **MUST** be sent on runtimes with frozen or low-precision timers, **MAY** be omitted otherwise. See [Log Ordering](#log-ordering). |

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

Expand Down Expand Up @@ -290,6 +294,25 @@ 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. SDKs that target runtimes where timestamps may be frozen or lack sub-millisecond precision **MUST** attach a `sentry.timestamp.sequence` integer attribute to every log. SDKs that only target runtimes with reliable sub-millisecond timestamps **MAY** omit it.

When sent, the sequence number **MUST**:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
When sent, the sequence number **MUST**:
When sent, the sequence integer **MUST**:

I would do this, or change them both to 'number', just so we are consistent.

- 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">

### Debug Mode
Expand Down Expand Up @@ -563,7 +586,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 +612,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 +638,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 +665,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 +693,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 +723,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
40 changes: 34 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
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the changelog, version 2.6.0 is dated 2026-02-06 but the previous 2.5.0 entry is dated 2026-02-12. This makes the timeline inconsistent with the version ordering; update the 2.6.0 date (or the 2.5.0 date) so newer versions don’t appear to precede older ones.

Suggested change
date: 2026-02-06
date: 2026-02-19

Copilot uses AI. Check for mistakes.
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. **MUST** be sent on runtimes with frozen or low-precision timers, **MAY** be omitted otherwise. 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,25 @@ 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. SDKs that target runtimes where timestamps may be frozen or lack sub-millisecond precision **MUST** attach a `sentry.timestamp.sequence` integer attribute to every metric. SDKs that only target runtimes with reliable sub-millisecond timestamps **MAY** omit it.

When sent, the sequence number **MUST**:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
When sent, the sequence number **MUST**:
When sent, the sequence integer **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">

### Data Category and Rate Limiting
Expand Down Expand Up @@ -547,7 +570,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 +586,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" }
Comment on lines 586 to +590
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this full envelope example, the first metric item includes sentry.environment and sentry.release, but this item omits them even though they’re listed as default attributes (when defined) and would normally be consistent across metrics from the same SDK instance. Consider adding them here too, or removing them from the earlier item, so the example matches the spec rules.

Copilot uses AI. Check for mistakes.
}
},
{
Expand All @@ -577,7 +602,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 +619,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 +634,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