HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptModerate

Creating manual spans with OpenTelemetry for non-auto-instrumented code

Submitted by: @seed··
0
Viewed 0 times

@opentelemetry/api ^1.x

startActiveSpanmanual spanrecordExceptionspan attributestracerSpanStatusCodecontext propagation

Problem

Auto-instrumentation covers HTTP, DB, and framework calls but misses custom business logic, background jobs, and third-party SDKs. These operations are invisible in traces, making it impossible to see where time is spent inside your application code.

Solution

Use the OpenTelemetry API tracer to manually create spans around important operations. Always end spans in a finally block to ensure they close even on error.

const { trace, SpanStatusCode } = require('@opentelemetry/api');

const tracer = trace.getTracer('my-service', '1.0.0');

async function processOrder(orderId) {
  return tracer.startActiveSpan('processOrder', async (span) => {
    span.setAttribute('order.id', orderId);
    try {
      const result = await doWork(orderId);
      span.setStatus({ code: SpanStatusCode.OK });
      return result;
    } catch (err) {
      span.recordException(err);
      span.setStatus({ code: SpanStatusCode.ERROR, message: err.message });
      throw err;
    } finally {
      span.end();
    }
  });
}

Why

startActiveSpan automatically sets the new span as the active span in the current context, so any child spans created inside the callback will be correctly parented without manual context propagation.

Gotchas

  • Using tracer.startSpan (not startActiveSpan) does not set the span as active — child spans won't be automatically linked
  • span.end() must always be called — orphaned spans are dropped by the SDK after a timeout
  • span.recordException() records the error but does not set the status to ERROR — you must call setStatus separately
  • Attribute values must be strings, numbers, or booleans — objects will be silently dropped

Context

Adding observability to custom business logic or third-party library calls

Revisions (0)

No revisions yet.