# Logs

This document uses key words such as "MUST", "SHOULD", and "MAY" as defined in

<!-- -->

[RFC 2119](https://www.ietf.org/rfc/rfc2119.txt) to indicate requirement levels.

Statusstable

Version`1.16.0`[(changelog)](https://develop.sentry.dev/sdk/telemetry/logs.md#changelog)

## [Overview](https://develop.sentry.dev/sdk/telemetry/logs.md#overview)

Logs allow Sentry to ingest structured log data from SDKs. SDKs send log envelopes containing structured log payloads with severity levels, trace context, and arbitrary attributes. Sentry uses this data to provide searchable, correlated log views alongside errors and traces.

There are two wire protocols: the `log` envelope with the Sentry Log protocol (preferred), and the `otel_log` envelope with the OpenTelemetry Log protocol. All SDKs **MUST** send logs via the `log` envelope and Sentry Log protocol. The `otel_log` format is documented in [Appendix: `otel_log` Format](https://develop.sentry.dev/sdk/telemetry/logs.md#otel_log-envelope-item-payload) for completeness.

Related specs:

* [Envelopes](https://develop.sentry.dev/sdk/foundations/transport/envelopes.md) — transport format
* [Attributes](https://develop.sentry.dev/sdk/foundations/state-management/scopes/attributes.md) — attribute type system
* [Tracing without Performance](https://develop.sentry.dev/sdk/foundations/trace-propagation.md#default-propagation) — required for trace context
* [Trace Origin](https://develop.sentry.dev/sdk/telemetry/traces/trace-origin.md) — origin attribute format

***

## [Concepts](https://develop.sentry.dev/sdk/telemetry/logs.md#concepts)

### [Structured Logging](https://develop.sentry.dev/sdk/telemetry/logs.md#structured-logging)

Logs support parameterized message templates for structured logging. Instead of interpolating values into the message body directly, SDKs send the template and parameters separately. This enables Sentry to group similar log messages and perform efficient searching.

```bash
Template:    "User %s has logged in!"
Parameter 0: "John"
Body:        "User John has logged in!"
```

The SDK sends the interpolated `body`, the `sentry.message.template`, and `sentry.message.parameter.X` attributes.

### [Severity Levels](https://develop.sentry.dev/sdk/telemetry/logs.md#severity-levels)

Logs use a severity model with six levels (lowest to highest): `trace`, `debug`, `info`, `warn`, `error`, `fatal`. These map exactly to [OpenTelemetry's Severity text field](https://opentelemetry.io/docs/specs/otel/logs/data-model/#field-severitytext).

Each level maps to a numeric severity range following the [OpenTelemetry Severity Number](https://opentelemetry.io/docs/specs/otel/logs/data-model/#field-severitynumber) specification:

| SeverityNumber range | Range name | Meaning                                                                                 |
| -------------------- | ---------- | --------------------------------------------------------------------------------------- |
| 1-4                  | Trace      | A fine-grained debugging event. Typically disabled in default configurations.           |
| 5-8                  | Debug      | A debugging event.                                                                      |
| 9-12                 | Info       | An informational event. Indicates that an event happened.                               |
| 13-16                | Warn       | A warning event. Not an error but is likely more important than an informational event. |
| 17-20                | Error      | An error event. Something went wrong.                                                   |
| 21-24                | Fatal      | A fatal error such as application or system crash.                                      |

SDKs **SHOULD** set the lowest severity number for a given severity level (e.g., `warn` uses severity number `13`).

### [Log Buffering](https://develop.sentry.dev/sdk/telemetry/logs.md#log-buffering)

Logs are buffered before sending. SDKs collect logs into a buffer and flush them as a batch in a single `log` envelope item, rather than sending each log individually. This reduces network overhead and aligns with Relay, which is optimized for up to 100 logs per envelope.

***

## [Behavior](https://develop.sentry.dev/sdk/telemetry/logs.md#behavior)

### [Log Processing Pipeline](https://develop.sentry.dev/sdk/telemetry/logs.md#log-processing-pipeline)

Candidatespecified since

<!-- -->

1.3.0

Log processing **MUST** follow this order:

1. Capture log via [Public APIs](https://develop.sentry.dev/sdk/telemetry/logs.md#logger-module) (e.g. `Sentry.logger.info`) or via [SDK integrations](https://develop.sentry.dev/sdk/telemetry/logs.md#sdk-integrations).
2. Check if logging is enabled via `enableLogs`/`enable_logs` — if not, skip remaining steps.
3. Pass the log to Hub/Scope, which **MUST** offer the same methods as the static API `Sentry.logger.X`.
4. Pass the log to the Client via a generic method (e.g., `captureLog(log, scope)`).
5. Process captured log (attach attributes per [Default Attributes](https://develop.sentry.dev/sdk/telemetry/logs.md#default-attributes)).
6. Run `beforeSendLog`/`before_send_log` to filter or modify the log.
7. Add log to buffer/batch processor per [Buffering](https://develop.sentry.dev/sdk/telemetry/logs.md#buffering).
8. At flush time, send array of logs to Sentry via `log` envelope, applying rate limiting per [Data Category and Rate Limiting](https://develop.sentry.dev/sdk/telemetry/logs.md#data-category-and-rate-limiting).

##### Note

An SDK **SHOULD** implement [Tracing without Performance](https://develop.sentry.dev/sdk/foundations/trace-propagation.md#default-propagation) before adding support for logs. This is required to ensure logs are associated with traces and that the correct trace context is sent to Sentry.

### [Default Attributes](https://develop.sentry.dev/sdk/telemetry/logs.md#default-attributes)

Candidatespecified since

<!-- -->

1.0.0

SDKs **MUST** attach the following attributes to every log:

| Attribute            | Since | Description                                                                                                |
| -------------------- | ----- | ---------------------------------------------------------------------------------------------------------- |
| `sentry.environment` | 1.0.0 | The environment set in the SDK, if defined.                                                                |
| `sentry.release`     | 1.0.0 | The release set in the SDK, if defined.                                                                    |
| `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. |

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

| Attribute                    | Since | Description                                                                                                                         |
| ---------------------------- | ----- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `sentry.message.template`    | 1.0.0 | The parameterized template string.                                                                                                  |
| `sentry.message.parameter.X` | 1.0.0 | Parameters to the template. `X` is either the positional index (`0`, `1`, etc.) or the parameter name (`item_id`, `user_id`, etc.). |

If there are no `sentry.message.parameter.X` attributes, SDKs **MUST NOT** attach `sentry.message.template` (since 1.7.0). This reduces duplicate content and simplifies PII processing.

SDKs **SHOULD** minimize default attributes. Logs are charged per byte size. New default attributes **SHOULD** only be added after significant user feedback and discussion with the SDK and ingest teams.

### [SDK Integration Origin](https://develop.sentry.dev/sdk/telemetry/logs.md#sdk-integration-origin)

Candidatespecified since

<!-- -->

1.0.0

If a log is generated by an SDK integration, the SDK **SHOULD** set the `sentry.origin` attribute per the [Trace Origin](https://develop.sentry.dev/sdk/telemetry/traces/trace-origin.md) documentation.

Since 1.9.0, logs follow these rules:

1. **User calls Sentry's Logging API directly:** SDKs **MUST NOT** send `sentry.origin`. This intentionally deviates from the Trace Origin spec to minimize log size.
2. **Captured from a logging library:** Use `auto.log.<name>` format (e.g., `"auto.log.serilog"`).
3. **Auto-emitted from other instrumented systems:** Use `auto.<category>.<integration-name>` format (e.g., `"auto.db.prisma"`).

### [User Attributes](https://develop.sentry.dev/sdk/telemetry/logs.md#user-attributes)

Candidatespecified since

<!-- -->

1.5.0

SDKs **MAY** attach user information as attributes, guarded by `sendDefaultPii` (since 1.14.0):

| Attribute    | Description                                                                                                                            |
| ------------ | -------------------------------------------------------------------------------------------------------------------------------------- |
| `user.id`    | The user ID. Maps to `id` in the [User](https://develop.sentry.dev/sdk/foundations/transport/event-payloads/user.md) payload.          |
| `user.name`  | The username. Maps to `username` in the [User](https://develop.sentry.dev/sdk/foundations/transport/event-payloads/user.md) payload.   |
| `user.email` | The email address. Maps to `email` in the [User](https://develop.sentry.dev/sdk/foundations/transport/event-payloads/user.md) payload. |

### [User Agent Parsing](https://develop.sentry.dev/sdk/telemetry/logs.md#user-agent-parsing)

Candidatespecified since

<!-- -->

1.5.0

By default, Relay parses the user agent attached to an incoming log envelope to extract `browser` and `os` information. SDKs **MAY** attach these attributes if they do not forward a user agent:

| Attribute         | Description                                                                                                                                                             |
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `browser.name`    | Display name of the browser. Maps to `name` in [Browser Context](https://develop.sentry.dev/sdk/foundations/transport/event-payloads/contexts.md#browser-context).      |
| `browser.version` | Version string of the browser. Maps to `version` in [Browser Context](https://develop.sentry.dev/sdk/foundations/transport/event-payloads/contexts.md#browser-context). |

### [Backend SDK Attributes](https://develop.sentry.dev/sdk/telemetry/logs.md#backend-sdk-attributes)

Candidatespecified since

<!-- -->

1.0.0

Backend SDKs (Node.js, Python, PHP, etc.) **SHOULD** attach:

| Attribute        | Description                                                                                                                                                               |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `server.address` | The server address. Equivalent to [`server_name`](https://develop.sentry.dev/sdk/foundations/transport/event-payloads.md#optional-attributes) on errors and transactions. |

### [Mobile, Desktop, and Native SDK Attributes](https://develop.sentry.dev/sdk/telemetry/logs.md#mobile-desktop-and-native-sdk-attributes)

Candidatespecified since

<!-- -->

1.5.0

Mobile, desktop, and native SDKs (Android, Apple, Electron, etc.) **SHOULD** attach:

| Attribute       | Description                                                                                                                                          |
| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `os.name`       | OS name. Maps to `name` in [OS Context](https://develop.sentry.dev/sdk/foundations/transport/event-payloads/contexts.md#os-context).                 |
| `os.version`    | OS version. Maps to `version` in [OS Context](https://develop.sentry.dev/sdk/foundations/transport/event-payloads/contexts.md#os-context).           |
| `device.brand`  | Device brand. Maps to `brand` in [Device Context](https://develop.sentry.dev/sdk/foundations/transport/event-payloads/contexts.md#device-context).   |
| `device.model`  | Device model. Maps to `model` in [Device Context](https://develop.sentry.dev/sdk/foundations/transport/event-payloads/contexts.md#device-context).   |
| `device.family` | Device family. Maps to `family` in [Device Context](https://develop.sentry.dev/sdk/foundations/transport/event-payloads/contexts.md#device-context). |

### [Buffering](https://develop.sentry.dev/sdk/telemetry/logs.md#buffering)

Candidatespecified since

<!-- -->

1.0.0

SDKs **MUST** buffer logs before sending. A simple initial strategy is flushing when the buffer exceeds 100 items or 5 seconds have passed. The buffer **SHOULD** forward logs to the transport in the scenarios outlined in the [telemetry buffer data forwarding scenarios](https://develop.sentry.dev/sdk/foundations/processing/telemetry-processor.md#data-forwarding-scenarios).

SDKs **MUST NOT** send more than 100 logs per envelope (since 1.15.0). Relay is optimized for this limit.

SDKs **MUST** enforce a hard limit of 1000 queued log events to prevent out-of-memory issues (since 1.12.0). Logs added beyond this limit are dropped. SDKs **MAY** use a lower limit but **MUST NOT** exceed 1000.

SDKs **MUST NOT** release logging capabilities to users without a buffering implementation.

### [Data Category and Rate Limiting](https://develop.sentry.dev/sdk/telemetry/logs.md#data-category-and-rate-limiting)

Candidatespecified since

<!-- -->

1.0.0

Logs use the `log_item` data category for rate limiting in Relay. Both `log` and `otel_log` envelopes are covered by this data category. SDKs **MUST** implement this data category. Rate limiting applies as usual with no special behavior for logs.

SDKs **MUST** track client outcomes for this data category to report how often logs are dropped.

### [SDK Integrations](https://develop.sentry.dev/sdk/telemetry/logs.md#sdk-integrations)

Candidatespecified since

<!-- -->

1.0.0

SDKs **SHOULD** provide integrations that capture logs from platform logging libraries (e.g., JavaScript's `console`, Python's `logging`, Java's `Log4j`) when `enableLogs`/`enable_logs` is set to `true`.

SDKs **MAY** introduce additional options beyond `enableLogs`/`enable_logs` to gate integration-specific functionality (e.g., controlling log appenders added via external config).

### [Tracing Association](https://develop.sentry.dev/sdk/telemetry/logs.md#tracing-association)

Candidatespecified since

<!-- -->

1.0.0

Logs **SHOULD** be associated with traces. If a log is recorded during an active span, SDKs **SHOULD** set the `span_id` property to the active span's ID.

### [Replay Association](https://develop.sentry.dev/sdk/telemetry/logs.md#replay-association)

Candidatespecified since

<!-- -->

1.8.0

Logs **SHOULD** be associated with replays. If a log is recorded during an active replay, SDKs **SHOULD** set the `sentry.replay_id` attribute to the active replay's ID.

### [Log Ordering](https://develop.sentry.dev/sdk/telemetry/logs.md#log-ordering)

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.

Candidatespecified since

<!-- -->

1.16.0

When sent, the sequence integer **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.

### [Debug Mode](https://develop.sentry.dev/sdk/telemetry/logs.md#debug-mode)

### [Debug Mode](https://develop.sentry.dev/sdk/telemetry/logs.md#debug-mode-1)

Candidatespecified since

<!-- -->

1.0.0

If `debug` is set to `true` in SDK init, calls to the Sentry logger API **SHOULD** also print to the console with the appropriate log level. This aids debugging of logging setups.

### [Client Reports](https://develop.sentry.dev/sdk/telemetry/logs.md#client-reports)

Candidatespecified since

<!-- -->

1.13.0

SDKs **MUST** report count (`log_item`) and size in bytes (`log_byte`) of discarded log messages. An approximation of log size is sufficient (e.g., by counting as if serialized).

***

## [Wire Format](https://develop.sentry.dev/sdk/telemetry/logs.md#wire-format)

### [`log` Envelope Item](https://develop.sentry.dev/sdk/telemetry/logs.md#log-envelope-item)

Candidatespecified since

<!-- -->

1.1.0

The `log` envelope item contains an array of log payloads encoded as JSON, allowing multiple logs per envelope item.

An envelope **MUST** contain at most one `log` envelope item — all log entries for a flush are batched into a single item's `items` array. Logs from different traces **MAY** be mixed into the same `log` item, but if they are, the envelope **MUST NOT** include a DSC (dynamic sampling context) header.

**Item Headers:**

| Field          | Type    | Required     | Description                                                                      |
| -------------- | ------- | ------------ | -------------------------------------------------------------------------------- |
| `type`         | String  | **REQUIRED** | **MUST** be `"log"`.                                                             |
| `item_count`   | Integer | **REQUIRED** | The number of log entries in the `items` array. **MUST** match the actual count. |
| `content_type` | String  | **REQUIRED** | **MUST** be `"application/vnd.sentry.items.log+json"`.                           |

```json
{
  "type": "log",
  "item_count": 5,
  "content_type": "application/vnd.sentry.items.log+json"
}
{
  "items": [{..log..}, {..log..}, {..log..}, {..log..}, {..log..}]
}
```

### [`log` Envelope Item Payload](https://develop.sentry.dev/sdk/telemetry/logs.md#log-envelope-item-payload)

Candidatespecified since

<!-- -->

1.0.0

Each log in the `items` array is a JSON object:

```json
{
  "timestamp": 1544719860.0,
  "trace_id": "5b8efff798038103d269b633813fc60c",
  "span_id": "b0e6f15b45c36b12",
  "level": "info",
  "body": "User John has logged in!",
  "severity_number": 9,
  "attributes": {
    "sentry.message.template": {
      "value": "User %s has logged in!",
      "type": "string"
    },
    "sentry.message.parameter.0": {
      "value": "John",
      "type": "string"
    }
  }
}
```

| Field             | Type    | Required     | Since  | Description                                                                                                                                                                |
| ----------------- | ------- | ------------ | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `timestamp`       | Number  | **REQUIRED** | 1.0.0  | Timestamp of the log in seconds since the Unix epoch.                                                                                                                      |
| `trace_id`        | String  | **REQUIRED** | 1.0.0  | Trace ID as 16 random bytes encoded as a hex string (32 characters). **MUST** be grabbed from the current propagation context.                                             |
| `level`           | String  | **REQUIRED** | 1.0.0  | Severity level. One of `trace`, `debug`, `info`, `warn`, `error`, `fatal`.                                                                                                 |
| `body`            | String  | **REQUIRED** | 1.0.0  | The log body/message.                                                                                                                                                      |
| `span_id`         | String  | **OPTIONAL** | 1.11.0 | Span ID of the active span when the log was collected, as 8 random bytes encoded as a hex string (16 characters).                                                          |
| `severity_number` | Integer | **OPTIONAL** | 1.0.0  | Severity number per [Severity Levels](https://develop.sentry.dev/sdk/telemetry/logs.md#severity-levels). Inferred from `level` unless explicitly set.                      |
| `attributes`      | Object  | **OPTIONAL** | 1.0.0  | Key-value pairs of arbitrary data. Values **MUST** declare their type. See [Attributes](https://develop.sentry.dev/sdk/foundations/state-management/scopes/attributes.md). |

### [`otel_log` Envelope Item Payload](https://develop.sentry.dev/sdk/telemetry/logs.md#otel_log-envelope-item-payload)

Candidatespecified since

<!-- -->

1.0.0

Click to expand/collapse details about the \`otel\_log\` envelope item payload.

The `otel_log` envelope item payload is a JSON object implementing the [OpenTelemetry Log Data Model](https://opentelemetry.io/docs/specs/otel/logs/data-model/). Multiple `otel_log` items **MAY** be sent per envelope.

```json
{
  "severity_text": "info",
  "body": {
    "string_value": "User John has logged in!"
  },
  "attributes": [
    {
      "key": "sentry.message.template",
      "value": { "string_value": "User %s has logged in!" }
    },
    {
      "key": "sentry.message.parameters.0",
      "value": { "string_value": "John" }
    }
  ],
  "time_unix_nano": "1741191250694000000",
  "trace_id": "edec519707974fc8bfccb5a017e17394",
  "severity_number": 9
}
```

| Field             | Type           | Required     | Description                                                                                                                                                                           |
| ----------------- | -------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `severity_text`   | String         | **REQUIRED** | Severity level. One of `trace`, `debug`, `info`, `warn`, `error`, `fatal`.                                                                                                            |
| `body`            | Object         | **REQUIRED** | The log body. Contains `string_value` with the message text.                                                                                                                          |
| `trace_id`        | String         | **OPTIONAL** | Trace ID for linking logs to traces and errors. Heavily recommended.                                                                                                                  |
| `severity_number` | Integer        | **OPTIONAL** | Severity number per [Severity Levels](https://develop.sentry.dev/sdk/telemetry/logs.md#severity-levels).                                                                              |
| `attributes`      | Array\<Object> | **OPTIONAL** | Key-value pairs. Each entry has `key` (string) and `value` (object with typed value). Supported value fields: `stringValue`, `intValue` (string-encoded), `boolValue`, `doubleValue`. |
| `time_unix_nano`  | String         | **OPTIONAL** | Creation time in Unix nanoseconds. SDKs **SHOULD** set this to the current time if not provided.                                                                                      |

***

## [Public API](https://develop.sentry.dev/sdk/telemetry/logs.md#public-api)

### [Initialization Options](https://develop.sentry.dev/sdk/telemetry/logs.md#initialization-options)

Candidatespecified since

<!-- -->

1.0.0

SDKs **MUST** expose the following configuration options:

| Option                              | Type     | Default | Since | Description                                                                                        |
| ----------------------------------- | -------- | ------- | ----- | -------------------------------------------------------------------------------------------------- |
| `enableLogs` / `enable_logs`        | Boolean  | `false` | 1.0.0 | Controls whether log envelopes are generated and sent. If `false`, the SDK **MUST NOT** send logs. |
| `beforeSendLog` / `before_send_log` | Function | —       | 1.0.0 | **OPTIONAL** callback receiving a log object. Returns a modified log or `null` to drop it.         |

While logs functionality is in an experimental state, SDKs **SHOULD** put these options in an experimental namespace:

```js
Sentry.init({
  _experiments: { enableLogs: true },
});
```

### [Logger Module](https://develop.sentry.dev/sdk/telemetry/logs.md#logger-module)

Candidatespecified since

<!-- -->

1.0.0

SDKs **MUST** expose logging methods in a `logger` module or namespace, with one method per [severity level](https://develop.sentry.dev/sdk/telemetry/logs.md#severity-levels):

* `Sentry.logger.trace`
* `Sentry.logger.debug`
* `Sentry.logger.info`
* `Sentry.logger.warn`
* `Sentry.logger.error`
* `Sentry.logger.fatal`

These methods accept a string template and parameters for structured logging. They **MAY** also accept arbitrary attributes.

The Hub/Scope **MUST** offer the same methods as the static `Sentry.logger.X` API (since 1.10.0). The Client **SHOULD** only offer one generic method (e.g., `captureLog(log, scope)`).

SDKs **MAY** add additional helpers (e.g., decorators, string template helpers) as appropriate for their platform.

### [Threading and Concurrency](https://develop.sentry.dev/sdk/telemetry/logs.md#threading-and-concurrency)

Candidatespecified since

<!-- -->

1.0.0

The `Sentry.logger.X` methods are fire-and-forget (no return value). SDKs **MAY** run these methods on a separate thread or queue them for later processing, including evaluating the string template and running internal hooks like `beforeSendLog`.

SDKs **MUST** ensure logs are sent in the order they are received.

##### Note

Putting everything on a background thread risks losing logs that occur directly before a crash. Mobile SDKs will need a more robust mechanism. The individual SDK will need to determine the best approach for their platform.

***

## [Examples](https://develop.sentry.dev/sdk/telemetry/logs.md#examples)

### [SDK API Usage](https://develop.sentry.dev/sdk/telemetry/logs.md#sdk-api-usage)

These examples are illustrative, not normative. SDK authors **SHOULD** ensure the API best fits their platform.

```jsx
// Browser - tagged template literals
Sentry.logger.info(
  Sentry.logger.fmt`Adding item ${itemId} for user ${userId}`,
);

// Server-side - printf-like syntax
Sentry.logger.info("Adding item %s for user %s", [itemId, userId], {
  extra: 123,
});
```

### [Full `log` Envelope](https://develop.sentry.dev/sdk/telemetry/logs.md#full-log-envelope)

A complete `log` envelope with six log entries at different severity levels:

```json
{ "sdk": { "name": "sentry.javascript.browser", "version": "9.15.0" } }
{
  "type": "log",
  "item_count": 6,
  "content_type": "application/vnd.sentry.items.log+json"
}
{
  "items": [
    {
      "timestamp": 1746456149.0191,
      "level": "trace",
      "body": "Modal animation performance: openTime=120ms, closeTime=85ms, fps=60",
      "trace_id": "624f66e93a04469f9992c7e9f1485056",
      "severity_number": 1,
      "attributes": {
        "modalId": { "value": "product_details", "type": "string" },
        "animationType": { "value": "slide-up", "type": "string" },
        "devicePixelRatio": { "value": 2, "type": "integer" },
        "browser": { "value": "Chrome", "type": "string" },
        "memoryUsage": { "value": "45MB", "type": "string" },
        "sentry.sdk.name": {
          "value": "sentry.javascript.browser",
          "type": "string"
        },
        "sentry.sdk.version": { "value": "9.15.0", "type": "string" },
        "sentry.message.template": {
          "value": "Modal animation performance: openTime=%sms, closeTime=%sms, fps=%s",
          "type": "string"
        },
        "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.timestamp.sequence": { "value": 0, "type": "integer" }
      }
    },
    {
      "timestamp": 1746456149.0191998,
      "level": "debug",
      "body": "Component ProductCard rendered 3 times",
      "trace_id": "624f66e93a04469f9992c7e9f1485056",
      "severity_number": 5,
      "attributes": {
        "props": { "value": "{\"productId\":\"prod_123\"}", "type": "string" },
        "renderTime": { "value": 45, "type": "integer" },
        "sentry.sdk.name": {
          "value": "sentry.javascript.browser",
          "type": "string"
        },
        "sentry.sdk.version": { "value": "9.15.0", "type": "string" },
        "sentry.message.template": {
          "value": "Component %s rendered %s times",
          "type": "string"
        },
        "sentry.message.parameter.0": {
          "value": "ProductCard",
          "type": "string"
        },
        "sentry.message.parameter.1": { "value": 3, "type": "integer" },
        "sentry.timestamp.sequence": { "value": 1, "type": "integer" }
      }
    },
    {
      "timestamp": 1746456149.0191998,
      "level": "info",
      "body": "Form checkout_form submitted successfully with 8 fields",
      "trace_id": "624f66e93a04469f9992c7e9f1485056",
      "severity_number": 9,
      "attributes": {
        "step": { "value": "payment_details", "type": "string" },
        "timeSpent": { "value": 120, "type": "integer" },
        "sentry.sdk.name": {
          "value": "sentry.javascript.browser",
          "type": "string"
        },
        "sentry.sdk.version": { "value": "9.15.0", "type": "string" },
        "sentry.message.template": {
          "value": "Form %s submitted successfully with %s fields",
          "type": "string"
        },
        "sentry.message.parameter.0": {
          "value": "checkout_form",
          "type": "string"
        },
        "sentry.message.parameter.1": { "value": 8, "type": "integer" },
        "sentry.timestamp.sequence": { "value": 2, "type": "integer" }
      }
    },
    {
      "timestamp": 1746456149.0192997,
      "level": "warn",
      "body": "API endpoint /api/products response time 2500ms exceeds threshold of 1000ms",
      "trace_id": "624f66e93a04469f9992c7e9f1485056",
      "severity_number": 13,
      "attributes": {
        "userAgent": { "value": "Mozilla/5.0...", "type": "string" },
        "connectionType": { "value": "4g", "type": "string" },
        "sentry.sdk.name": {
          "value": "sentry.javascript.browser",
          "type": "string"
        },
        "sentry.sdk.version": { "value": "9.15.0", "type": "string" },
        "sentry.message.template": {
          "value": "API endpoint %s response time %sms exceeds threshold of %sms",
          "type": "string"
        },
        "sentry.message.parameter.0": {
          "value": "/api/products",
          "type": "string"
        },
        "sentry.message.parameter.1": { "value": 2500, "type": "integer" },
        "sentry.message.parameter.2": { "value": 1000, "type": "integer" },
        "sentry.timestamp.sequence": { "value": 3, "type": "integer" }
      }
    },
    {
      "timestamp": 1746456149.0192997,
      "level": "error",
      "body": "Failed to load images for products prod_123, prod_456",
      "trace_id": "624f66e93a04469f9992c7e9f1485056",
      "severity_number": 17,
      "attributes": {
        "error": { "value": "NetworkError", "type": "string" },
        "statusCode": { "value": 404, "type": "integer" },
        "retryAttempts": { "value": 2, "type": "integer" },
        "browser": { "value": "Chrome", "type": "string" },
        "version": { "value": "120.0", "type": "string" },
        "sentry.sdk.name": {
          "value": "sentry.javascript.browser",
          "type": "string"
        },
        "sentry.sdk.version": { "value": "9.15.0", "type": "string" },
        "sentry.message.template": {
          "value": "Failed to load images for products %s",
          "type": "string"
        },
        "sentry.message.parameter.0": {
          "value": "prod_123, prod_456",
          "type": "string"
        },
        "sentry.timestamp.sequence": { "value": 4, "type": "integer" }
      }
    },
    {
      "timestamp": 1746456149.0192997,
      "level": "fatal",
      "body": "State corruption detected in ShoppingCart component during UPDATE_CART action",
      "trace_id": "624f66e93a04469f9992c7e9f1485056",
      "severity_number": 21,
      "attributes": {
        "error": { "value": "ReduxStateError", "type": "string" },
        "previousState": { "value": "valid", "type": "string" },
        "currentState": { "value": "invalid", "type": "string" },
        "sentry.sdk.name": {
          "value": "sentry.javascript.browser",
          "type": "string"
        },
        "sentry.sdk.version": { "value": "9.15.0", "type": "string" },
        "sentry.message.template": {
          "value": "State corruption detected in %s component during %s action",
          "type": "string"
        },
        "sentry.message.parameter.0": {
          "value": "ShoppingCart",
          "type": "string"
        },
        "sentry.message.parameter.1": {
          "value": "UPDATE_CART",
          "type": "string"
        },
        "sentry.timestamp.sequence": { "value": 5, "type": "integer" }
      }
    }
  ]
}
```

***

## [Changelog](https://develop.sentry.dev/sdk/telemetry/logs.md#changelog)

| Version  | Date       | Summary                                                                                                                  |
| -------- | ---------- | ------------------------------------------------------------------------------------------------------------------------ |
| `1.16.0` | 2026-03-04 | Add sentry.timestamp.sequence attribute for deterministic log ordering                                                   |
| `1.15.0` | 2026-02-03 | Clarified 100 logs per envelope hard limit, SDKs MAY use lower buffer limit                                              |
| `1.14.0` | 2025-12-16 | User attributes now optional, guarded by sendDefaultPii                                                                  |
| `1.13.0` | 2025-11-18 | Added client reports requirement (log\_item count, log\_byte size)                                                       |
| `1.12.0` | 2025-11-10 | Added buffer hard limit of 1000 queued log events                                                                        |
| `1.11.0` | 2025-10-30 | Added span\_id as top-level payload field, replaced sentry.trace.parent\_span\_id attribute                              |
| `1.10.0` | 2025-10-22 | Hub/Scope MUST offer same logger methods as static API, Client SHOULD offer generic captureLog                           |
| `1.9.0`  | 2025-10-09 | Consolidated sentry.origin rules — no origin for manual calls, auto.log.\* for libraries, auto.\*.\* for instrumentation |
| `1.8.0`  | 2025-09-10 | Added sentry.replay\_id as default attribute and replay association behavior                                             |
| `1.7.0`  | 2025-08-28 | Added message template constraint — MUST NOT send sentry.message.template without parameters                             |
| `1.6.0`  | 2025-06-10 | User attributes no longer gated behind sendDefaultPii                                                                    |
| `1.5.0`  | 2025-05-27 | Added platform-specific default attributes for browser, backend, mobile/desktop/native                                   |
| `1.4.0`  | 2025-05-08 | Added Tracing without Performance as prerequisite for logs                                                               |
| `1.3.0`  | 2025-05-07 | Added structured log processing pipeline, removed logsSampleRate init option                                             |
| `1.2.0`  | 2025-05-01 | Refined buffering requirements (100 items or 5 seconds flush)                                                            |
| `1.1.0`  | 2025-04-24 | Documented log envelope item structure (items array wrapper)                                                             |
| `1.0.0`  | 2025-04-22 | Initial spec — log protocol, severity model, logger API, init options, otel\_log format                                  |
