Skip to content

Overview ​

A log is a single line of text with a level and, optionally, a set of structured attributes — the key/value data you'd otherwise interpolate into the message. Logs show up on the project's Logs page, searchable by message, level, and attribute.

There are two ways to send them:

  • Explicitly, with Buglapse.log.info() / warn() / error() / ... — the recommended way, since you choose what's worth shipping and can attach attributes.
  • Automatically, by turning on the console integration, which forwards every console.log(), console.info(), console.warn(), console.error(), and console.debug() call.

Logs are not errors: Buglapse.log.error() records a line at the error level but doesn't create an issue. To report an exception with a stack trace, use captureException() (see Errors).

Sending logs ​

The log object has one method per level — log, debug, info, warn, error — each taking a message and an optional attributes object:

ts
Buglapse.log.info('User signed in')
Buglapse.log.warn('Payment retry', { orderId: 1042, attempt: 2 })
Buglapse.log.error('Checkout failed', { orderId: 1042, reason: 'card_declined' })
ts
import { log } from '@buglapse/browser'

log.debug('Cart recalculated', { items: 3, total: 59.9 })

Calls made before init() — e.g. while the CDN script is still loading — are queued and sent once the client is ready, so it's safe to log early.

Like every other event, each log is batched by the transport (see Transports) and stamped with the current tags, context, user, environment, and release (see Context).

Attributes ​

Keep the message a fixed, human-readable string and put the variable parts in attributes:

ts
// Good — one message, searchable fields
Buglapse.log.info('Order placed', { orderId: order.id, total: order.total, currency: 'EUR' })

// Avoid — every call produces a different message, nothing to filter on
Buglapse.log.info(`Order ${order.id} placed for ${order.total} EUR`)

Attributes are stored as-is on the log and each top-level key becomes a search filter on the dashboard (orderId:1042). Prefer flat objects with string, number, or boolean values — nested objects are kept and shown on the log, but aren't offered as filters.

Attributes belong to one log line; tags and context (setTag(), setContext()) belong to everything sent after they're set. Use attributes for "what happened in this call" and tags/context for "who/where this is happening".

Capturing console calls ​

The console integration is opt-in. With the CDN script tag, turn on the Console capture toggle on the project's Settings → Loader Script tab — it takes effect on your site's next page load, with no change to the embed.

With the npm package, add the integration yourself:

ts
import { init } from '@buglapse/browser'
import { consoleIntegration } from '@buglapse/browser/integrations'

init({
    dsn: '{dsn}',
    integrations: [consoleIntegration()],
})

Once registered, it wraps console.log, console.info, console.warn, console.error, and console.debug. The original method still runs first, so output in DevTools is unchanged; the call is then forwarded as a log with the same level (console.log → log, console.warn → warn, ...).

Arguments are mapped the same way as an explicit Buglapse.log call:

  • a trailing plain object becomes the log's attributes;
  • everything before it is joined with spaces into the message — strings as-is, anything else via JSON.stringify.
ts
console.warn('Slow response', { url: '/api/cart', ms: 1840 })
// → level: warn, message: "Slow response", attributes: { url: "/api/cart", ms: 1840 }

console.log('items', [1, 2, 3], 42)
// → level: log, message: 'items [1,2,3] 42', no attributes

A few things to keep in mind:

  • JSON.stringify turns an Error into {}, so console.error(error) doesn't carry a useful message or stack. Report exceptions with captureException() instead.
  • Other console methods (table, trace, group, ...) aren't forwarded.
  • Every third-party script on the page logs through the same console, so enabling capture can send a lot of noise. Watch your log quota after turning it on, or drop what you don't need (below).

To turn it off again at runtime, disable it by name:

ts
Buglapse.disable('console')

The console integration is independent from console breadcrumbs: breadcrumbs record console calls only as context attached to a later error, while this integration sends each call as a log of its own. See Breadcrumbs.

Linking logs to traces ​

Every log is stamped with the current trace.id — the active span's trace, or the page's trace when no span is running — and with span.id when a span is active:

ts
await Buglapse.asyncSpan('checkout', async () => {
    Buglapse.log.info('Starting checkout') // linked to the "checkout" span
    await submitOrder()
})

On the dashboard, a log with a trace id links to that trace. See Correlating other events with the active span.

Dropping or scrubbing logs ​

Logs go through the same preprocessor pipeline as every other event, so you can drop or rewrite them before they leave the browser — for example, to skip debug logs in production or strip a sensitive attribute:

ts
Buglapse.addPreprocessor((event) => {
    if (event.type !== 'log') return event

    if (event.payload.level === 'debug') return null

    delete event.payload.attributes?.email

    return event
})

Filtering, sampling, and quota ​

On the server, logs go through the project's Settings → Filters tab like every other event: disabled ingestion, IP / environment / release discard lists, and the crawler filter. The Logs sample rate on that tab keeps a random share of logs, rolled independently per log.

Each stored log counts against the organization's monthly log quota, as well as the overall monthly event quota. Once either limit is reached, further logs are rejected until the next month.

Viewing on the dashboard ​

Open Logs in the project sidebar. The list shows the newest logs first, with level, message, and time; click a log to see its attributes, tags, and context, plus links to the identified user and the trace it was captured in.

The search bar matches free text against the message and supports filters (the full syntax — operators like != and ~, quoting — is on the Search page):

  • level: — the log level: log, debug, info, warn, or error;
  • environment: — the environment passed to init(), e.g. environment:production (see environment and release);
  • user: — the identified user (set via Buglapse.setUser(), see Identifying users);
  • browser: / os: / device: — the visitor's browser, operating system, and device model, e.g. browser:Safari;
  • any attribute, tag, or context key — e.g. orderId:1042, release:1.4.0.

For example: checkout level:error environment:production browser:Safari.