Skip to content

Spans

A span represents a unit of work with defined start and end logs. Spans are useful when instrumenting blocks of time, e.g., "How long was a loading spinner displayed?"

Kotlin
val span = Logger.startSpan(
  "loading_spinner",
  LogLevel.INFO
  mapOf(),
)

// ...

span?.end(SpanResult.SUCCESS, mapOf())

// or:

Logger.trackSpan("operation", LogLevel.INFO) {
  operation()
}
Java
Optional<Span> span = Logger.startSpan(
  "loading_spinner",
  LogLevel.INFO,
  new HashMap(),
)

// ...

span.ifPresent(s -> s.end(SpanResult.SUCCESS, new HashMap()))
Swift
let span = Logger.startSpan(
  name: "loading_spinner",
  level: .info,
  fields: [:]
)

// ...

span?.end(.success, fields: [:])

The SDK calculates and attaches information about the span duration each time a span ends.

Info

See the Timeline Waterfalls section for seeing how this information is displayed in the product.

Spans Hierarchy

Spans can be nested hierarchically by providing a parentID to the start call. The parent span ID is the ID of the span that started the child span.

graph TD
  A[Span A] --> B[Span B]
  A --> C[Span C]
  B --> D[Span D]
  C --> E[Span E]

In the example above, Span A is the parent of Spans B and C. Span B is the parent of Span D, and Span C is the parent of Span E.

This is specially useful when spans are rendered in the waterfall chart of the Timeline view.

Custom start & end time (advanced)

The SDK allows you to provide custom start and end times for spans. This is useful when you have a specific time source or timing heuristic that you want to use for your spans. These custom times are also used to display the logs in the correct position in the Timeline view. When providing custom times, you need to provide both the start and end times, failing to provide one of them will result in the span being tracked using system time.

Kotlin
val span = Logger.startSpan(
  "loading_spinner",
  LogLevel.INFO,
  mapOf(),
  startTimeMs = 1234567890000L,
)

// ...

span?.end(
  SpanResult.SUCCESS,
  mapOf(),
  endTimeMs = 1234567900000L,
)
Swift
let span = Logger.startSpan(
  name: "loading_spinner",
  level: .info,
  fields: [:],
  startTimeInterval: 1234567890.0
)
// ...
span?.end(.success, fields: [:], endTimeInterval: 1234567900.0)

Warning

Please note that this is an advanced feature and should be used with caution, as workflows match in the order logs are received, regardless of the provided time.

Fields

Span logs contain multiple out-of-the-box fields outlined below.

Span Start Fields

Field Name Field Key Example Values Notes
Span Parent _span_parent_id foobar-7b3a-44c7-8c8e-47c5c15f2412 Spans can be nested hirarchically. The parent span ID is the ID of the span that started the child span.
Span ID _span_id 8bcbbef6-7b3a-44c7-8c8e-47c5c15f2412 Each span start-end logs pair shares the same span ID value.
Span Name _span_name spinner_loading
Span Type _span_type start

Span Start End

Field Name Field Key Example Values Notes
Duration _duration_ms 123
Result _result success, failure, canceled, unknown The span result
Span Parent _span_parent_id foobar-7b3a-44c7-8c8e-47c5c15f2412 Spans can be nested hirarchically. The parent span ID is the ID of the span that started the child span.
Span ID _span_id 8bcbbef6-7b3a-44c7-8c8e-47c5c15f2412 Each span start-end logs pair shares the same span ID value.
Span Name _span_name spinner_loading
Span Type _span_type end