Event Fields

Send useful events.

Every event must include a message.

OneMinute Logs uses an OpenTelemetry-aligned event model. A payload has a message, a level (set by the method you call), an optional eventName, and an optional attributes map. Everything else is optional, but the right fields make searching, filtering, and alerting much easier.

Complete example

await log.error({
  message: "Payment failed",
  eventName: "payment.charge.failed",
  attributes: {
    "payment.provider": "stripe",
    "payment.amount": 49.99,
    "payment.currency": "usd",
    "payment.failure_kind": "card_declined",
    "order.id": "order_456",
    "user.id": "user_123",
  },
});

The method (log.error) sets level. projectName, serviceName, and environment come from your logger configuration and are attached automatically.

Core fields

FieldTypeRequiredPurpose
messagestringYesHuman-readable explanation of what happened
leveltrace | debug | info | warn | error | fatalSet by methodSeverity of the event. Logger methods set this for you.
eventNamestringNoStable, lowercase identifier for the kind of event, e.g. payment.charge.failed
attributesRecord<string, string | number | boolean | null | array>NoStructured key/value context using dotted OpenTelemetry-style keys
timestampDate | string | numberNoEvent time. Defaults to now; set it only for backdated events.
traceIdstringNoW3C trace id, only from a real distributed-tracing context
spanIdstringNoW3C span id, only from a real distributed-tracing context

message

Use a short sentence that someone can understand immediately. Keep the wording stable for the same kind of event so it groups cleanly.

message: "Payment failed"

Good

message: "Database connection timed out"
message: "User signed in"
message: "Invoice generation failed"

Avoid vague messages

message: "Something went wrong"
message: "Error"
message: "Failed"

Put variable data (ids, amounts, counts) in attributes, not in the message string.

level

You do not set level directly — you call the matching method and the SDK sets it.

await log.trace({ message: "Cache lookup", eventName: "cache.lookup.completed" });
await log.debug({ message: "Parsed request body" });
await log.info({ message: "User signed in", eventName: "auth.login.succeeded" });
await log.warn({ message: "Retrying upstream call", eventName: "http.client.retry" });
await log.error({ message: "Payment failed", eventName: "payment.charge.failed" });
await log.fatal({ message: "Event loop stalled", eventName: "system.process.crashed" });
ValueUse it for
traceVery fine-grained diagnostic detail
debugDebug information during development
infoNormal application events worth recording
warnUnexpected but recoverable situations
errorErrors and failed operations
fatalUnrecoverable failures that stop the process

log.warning() is accepted as an alias for log.warn().

eventName

A stable, lowercase identifier for the kind of event. OneMinute Logs uses it to group events, drive alerts, and power anomaly detection, so the same workflow should always emit the same name.

Follow the grammar <domain>[.<object>][.<qualifier>].<outcome> using snake_case segments:

auth.login.succeeded
auth.login.failed
payment.charge.failed
order.created
order.fulfillment.failed
queue.message.failed
http.server.request

Do not invent five names for one thing. Pick one and reuse it.

One name

payment.charge.failed

Not this

payment.failed
payment.failure
checkout.payment.error
billing.payment.failed
stripe.payment.failed

attributes

A flat map of structured context. Values may be strings, numbers, booleans, null, or arrays of those. Use dotted, lowercase keys that follow OpenTelemetry semantic conventions where one exists.

attributes: {
  "user.id": "user_123",
  "order.id": "order_456",
  "payment.provider": "stripe",
  "payment.amount": 49.99,
  "http.response.status_code": 500,
  "error.type": "CardError",
}

This is the place for anything you want to search, filter, or alert on: identifiers that follow one user, request, order, or workflow, plus failure detail such as error.type or a *.failure_kind qualifier.

Privacy note

Keep passwords, tokens, card numbers, and raw personal data out of attributes. Stable ids are safer than emails or names.

Set defaultAttributes in your logger config for keys that should ride along on every event.

timestamp

Defaults to the moment you call the logger. Set it only when the event actually happened earlier — for example when replaying a queue or importing history.

await log.info({
  message: "Webhook received",
  eventName: "webhook.inbound.received",
  timestamp: new Date(webhook.created_at),
});

Accepts a Date, an RFC-3339 string, or a millisecond epoch number.

traceId & spanId

Set these only when they come from a real distributed-tracing context (an active OpenTelemetry span, or an incoming traceparent header). Do not generate random values — OneMinute Logs uses them to link an event to its trace.

await log.error({
  message: "Payment failed",
  eventName: "payment.charge.failed",
  traceId: span.spanContext().traceId,
  spanId: span.spanContext().spanId,
});

Automatically added fields

You never send these — the SDK and the backend fill them in:

level

Set by the logger method you call (log.info, log.warn, log.error, …).

projectName / serviceName / environment / serviceVersion

Taken from your logger configuration.

resource

Runtime and service metadata (process runtime name and version, service version).

scope

The SDK name and version that emitted the event, e.g. @oneminutelogs/express.

observedTimestamp / ingestedAt

Set by OneMinute Logs when it receives and stores the event.

severityNumber / fingerprint / retentionDays

Derived during ingestion for normalization, grouping, and per-plan retention.

Stored event shape

When you read events back with getLogs or getStream, each event is a normalized, camelCase LogEvent:

FieldDescription
idStable event id assigned by OneMinute Logs.
timestampRFC-3339 time the event occurred.
observedTimestampRFC-3339 time OneMinute Logs received the event.
ingestedAtRFC-3339 time the event was durably stored.
leveltrace | debug | info | warn | error | fatal.
severityNumberOTel normalized numeric severity (1–24).
messageThe message you sent.
eventNameThe eventName you sent, or null.
serviceNameResolved from serviceName in your logger config.
environmentResolved from environment in your logger config, or null.
attributesYour attributes, with values best-effort restored to their original primitive type.
resourceResource attributes describing the telemetry source (runtime, service version, environment).
scope{ name, version } of the SDK that emitted the event.
traceId / spanIdTrace context, or null.
traceFlagsW3C trace flags as a number.
fingerprintNormalized event identity used for grouping, or null.
retentionDaysHow long this event is retained, based on your plan.

See Search & Filters for how to query these fields.

Recommended naming

Use lowercase, consistent values everywhere.

eventName: "payment.charge.failed"   // dotted, snake_case segments
"payment.provider": "stripe"          // dotted attribute keys
"user.id": "user_123"

Avoid mixing styles.

eventName: "PaymentFailed"
eventName: "payment-charge-failed"
"userId": "user_123"

Consistency is what makes filters, alerts, and grouping reliable across services.

Start simple

You do not need every field. A message and the right method is a valid event.

await log.error({
  message: "Payment failed",
  eventName: "payment.charge.failed",
});

Add attributes only when they help you search, investigate, or alert.

Found something unexpected? Let us know.