Set Up Logs
Structured logs allow you to send, view and query logs sent from your applications within Sentry.
Stack traces tell you what broke. Logs tell you why. When an error fires, you get a snapshot of the failure, but the context leading up to it is often missing. Logs capture the journey — what the data looked like, which code paths executed, and what state the system was in.
Sentry Logs are high-cardinality — you can pass any attributes you want and search or filter by them later. No need to decide upfront which fields are important. Just log what might be useful and query it when you need it.
Logs for JavaScript are supported in Sentry JavaScript SDK version 9.41.0 and above.
Enable logging by adding enableLogs: true to your Sentry configuration.
Sentry.init({
dsn: "___PUBLIC_DSN___",
enableLogs: true,
});
Use Sentry.logger to send logs at different levels. A log message is required for Sentry to send the log.
| Level | When to Use |
|---|---|
trace | Fine-grained debugging |
debug | Development diagnostics |
info | Normal operations, milestones |
warn | Potential issues, degraded state |
error | Failures that need attention |
fatal | Critical failures, system down |
Sentry.logger.trace("Entering function", { fn: "processOrder" });
Sentry.logger.debug("Cache lookup", { key: "user:123" });
Sentry.logger.info("Order created", { orderId: "order_456" });
Sentry.logger.warn("Rate limit approaching", { current: 95, max: 100 });
Sentry.logger.error("Payment failed", { reason: "card_declined" });
Sentry.logger.fatal("Database unavailable", { host: "primary" });
Pass structured data as the second argument — these attributes become searchable columns in Sentry.
Use Sentry.logger.fmt for parameterized messages. Values are automatically extracted as searchable attributes.
// Pass attributes directly
Sentry.logger.info("User signed up", {
userId: user.id,
plan: "pro",
referrer: "google",
});
// Use fmt for parameterized messages
const userId = "user_123";
const productName = "Widget Pro";
Sentry.logger.info(
Sentry.logger.fmt`User ${userId} purchased ${productName}`,
);
Set attributes on a scope to automatically include them in all logs within that context. Requires SDK version 10.32.0 or above.
Use global scope for app-wide attributes, and isolation scope for request-specific context. Only string, number, and boolean attribute values are supported.
// Global scope - shared across entire app
Sentry.getGlobalScope().setAttributes({
service: "checkout",
version: "2.1.0",
});
// Isolation scope - unique per request
Sentry.getIsolationScope().setAttributes({
org_id: user.orgId,
user_tier: user.tier,
});
// Current scope - single operation
Sentry.withScope((scope) => {
scope.setAttribute("request_id", req.id);
Sentry.logger.info("Processing order");
});
Already using console.log? Capture console calls as Sentry Logs with consoleLoggingIntegration.
Multiple arguments are parsed as searchable attributes (requires SDK 10.13.0+).
For Consola users, use Sentry.createConsolaReporter() instead (requires SDK 10.12.0+).
Sentry.init({
dsn: "___PUBLIC_DSN___",
integrations: [
Sentry.consoleLoggingIntegration({ levels: ["log", "warn", "error"] }),
],
});
// Arguments become searchable attributes
console.log("Executed Action for User:", 123, true);
// -> message.parameter.0: 123
// -> message.parameter.1: true
Use beforeSendLog to filter or modify logs before they're sent. Return null to drop a log.
The log object includes: level, message, timestamp, and attributes.
Sentry.init({
dsn: "___PUBLIC_DSN___",
enableLogs: true,
beforeSendLog: (log) => {
// Drop debug logs in production
if (log.level === "debug") {
return null;
}
// Remove sensitive attributes
if (log.attributes?.password) {
delete log.attributes.password;
}
return log;
},
});
Everything in Sentry is linked by trace. When you're viewing a log, you can jump to the parent trace to see the full request context. When you're viewing a trace, you can see all logs emitted during that operation. This connection makes it easy to move between high-level performance data and detailed diagnostic logs.
- Traces — Logs emitted during an active span automatically include
sentry.trace.parent_span_id. Click through from any log to see the full trace, or filter logs by trace ID to see everything that happened during a specific request. - Errors — Logs capture the journey leading up to a failure. When an error occurs, your logs show what data was processed, which code paths executed, and what state the system was in — context that stack traces alone can't provide.
Instead of many small logs that are hard to correlate, emit one comprehensive log per operation with all relevant context.
This makes debugging dramatically faster — one query returns everything about a specific order, user, or request.
// ❌ Scattered thin logs
Sentry.logger.info("Starting checkout");
Sentry.logger.info("Validating cart");
Sentry.logger.info("Processing payment");
Sentry.logger.info("Checkout complete");
// ✅ One wide event with full context
Sentry.logger.info("Checkout completed", {
orderId: order.id,
userId: user.id,
cartValue: cart.total,
itemCount: cart.items.length,
paymentMethod: "stripe",
duration: Date.now() - startTime,
});
Add attributes that help you prioritize and debug:
- User context — tier, account age, lifetime value
- Transaction data — order value, item count
- Feature state — active feature flags
- Request metadata — endpoint, method, duration
This lets you filter logs by high-value customers or specific features.
Sentry.logger.info("API request completed", {
// User context
userId: user.id,
userTier: user.plan, // "free" | "pro" | "enterprise"
// Request data
endpoint: "/api/orders",
method: "POST",
duration: 234,
// Business context
orderValue: 149.99,
featureFlags: ["new-checkout", "discount-v2"],
});
The Node SDK automatically sets several default attributes on all log entries to provide context and improve debugging:
environment: The environment set in the SDK if defined. This is sent from the SDK assentry.environment.release: The release set in the SDK if defined. This is sent from the SDK assentry.release.sdk.name: The name of the SDK that sent the log. This is sent from the SDK assentry.sdk.name.sdk.version: The version of the SDK that sent the log. This is sent from the SDK assentry.sdk.version.
If the log was parameterized, Sentry adds the message template and parameters as log attributes.
message.template: The parameterized template string. This is sent from the SDK assentry.message.template.message.parameter.X: The parameters to fill the template string. X can either be the number that represent the parameter's position in the template string (sentry.message.parameter.0,sentry.message.parameter.1, etc) or the parameter's name (sentry.message.parameter.item_id,sentry.message.parameter.user_id, etc). This is sent from the SDK assentry.message.parameter.X.
For example, with the following log:
const user = "John";
const product = "Product 1";
Sentry.logger.info(
Sentry.logger.fmt`'${user}' added '${product}' to cart.`,
);
Sentry will add the following attributes:
message.template: "%s added %s to cart."message.parameter.0: "John"message.parameter.1: "Product 1"
server.address: The address of the server that sent the log. Equivalent toserver_namethat gets attached to Sentry errors.
If user information is available in the current scope, the following attributes are added to the log:
user.id: The user ID.user.name: The username.user.email: The email address.
If a log is generated by an SDK integration, the SDK will set additional attributes to help you identify the source of the log.
origin: The origin of the log. This is sent from the SDK assentry.origin.
- Tracing — Logs are automatically linked to traces, so you can see logs in the context of the request or operation that produced them.
- Error Monitoring — Use logs to add diagnostic context that helps you understand what led to an error.
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").