A log event is one structured log line, shown on the project's Logs page. Logs aren't grouped like exceptions, but consecutive repeats collapse, the way a browser console does: a log with the same level, message and environment as the project's previous log is stored as a ×N counter on that row rather than as a new row. The row keeps the newest repeat's timestamp, attributes and context. Each repeat still counts as one log towards the quota.
Where it comes from
log.log(),log.debug(),log.info(),log.warn(),log.error()— see Logs.- ConsoleIntegration, which forwards
console.*calls as logs.
Payload
json
{
"type": "log",
"timestamp": "2026-09-24T10:15:02.481Z",
"tags": {},
"contexts": { "environment": "production", "trace.id": "…", "span.id": "…" },
"payload": {
"level": "info",
"message": "Order placed",
"attributes": { "order.id": 1042, "total": 59.9 }
}
}| Field | Type | Description |
|---|---|---|
level | log | debug | info | warn | error | Severity, taken from the method you called. |
message | string | The log line itself. |
attributes | object, optional | Structured key/value data specific to this log line — searchable on the Logs page. |
attributes is for data about this line (an order id, a duration). Data that's true for everything the client sends (the current user, the release) belongs in contexts via setUser() / setContext() instead — see Tags & Context.
A log captured inside a span() carries trace.id / span.id contexts, so it shows up linked to that trace.
Sampling
The server-side log sample rate (Settings → Filters) is rolled independently for each event.
Quota
Counts as one toward the monthly logs limit — and only that one, so running out of logs never stops errors or traces.