Manual instrumentation lets you track specific business logic, add custom attributes, and capture detailed error context in SigNoz.
Prerequisites
- Finish the core Deno setup in the Deno OpenTelemetry instrumentation guide so exporters and SDK are configured.
- Deno v2.0 or later.
Step 1. Add OpenTelemetry API
Add the OpenTelemetry API package to your project:
deno add npm:@opentelemetry/api
Or import it directly in your code using npm: specifiers.
Step 2. Create manual spans
Use the API tracer to wrap important work inside custom spans:
import { trace } from "npm:@opentelemetry/api";
const tracer = trace.getTracer();
Deno.serve(async (req) => {
return await tracer.startActiveSpan("handle_request", async (span) => {
try {
span.setAttribute("http.method", req.method);
span.setAttribute("http.url", req.url);
// Simulate some work
await new Promise((resolve) => setTimeout(resolve, 50));
return new Response("Hello from SigNoz!");
} catch (err) {
span.recordException(err);
throw err;
} finally {
span.end();
}
});
});
Tips:
- Reuse tracer instances instead of creating a new one for each request.
- Start spans with descriptive names that match business steps (
checkout,fetch-user, etc.). - The
startActiveSpancallback automatically handles span context propagation.
Step 3. Add attributes and events
Attributes show up as key-value pairs in SigNoz so you can filter and aggregate spans. Events capture notable moments inside a span.
import { trace } from "npm:@opentelemetry/api";
const tracer = trace.getTracer();
async function processOrder(orderId: string, amount: number) {
return await tracer.startActiveSpan("process-order", async (span) => {
try {
span.setAttribute("order.id", orderId);
span.setAttribute("order.amount", amount);
// Validate the order
await validateOrder(orderId);
span.addEvent("order.validated");
// Charge payment
const txnId = await chargePayment(orderId, amount);
span.addEvent("payment.charged", { "transaction.id": txnId });
return txnId;
} finally {
span.end();
}
});
}
- Keep attribute keys consistent (use semantic conventions when possible).
- Use events to mark retries, cache hits/misses, queue waits, and similar milestones.
Step 4. Record errors
Flag failures on the span so they are easy to query in SigNoz.
import { trace, SpanStatusCode } from "npm:@opentelemetry/api";
const tracer = trace.getTracer();
async function riskyOperation() {
return await tracer.startActiveSpan("risky-operation", async (span) => {
try {
await doSomethingRisky();
span.setStatus({ code: SpanStatusCode.OK });
} catch (err) {
span.recordException(err);
span.setStatus({ code: SpanStatusCode.ERROR, message: err.message });
throw err;
} finally {
span.end();
}
});
}
recordExceptionattaches stack trace and message details.- Setting status to
ERRORsurfaces the span in SigNoz error views and alerts. - Continue propagating the error upstream so calling code can respond.
Validate
- Trigger the code paths that emit manual spans.
- In SigNoz Traces, filter by
service.nameor your span name. - Open a trace and verify attributes, events, and error status.
- Check the Errors view to confirm failures show up with recorded exceptions.
Troubleshooting
Why don't I see my custom spans in SigNoz?
- Confirm
OTEL_DENO=trueis set and the endpoint/ingestion key are configured correctly. - Verify traffic hits the functions where you inserted spans.
- Ensure your application runs long enough for batched exports to flush.
Why are child spans missing even though I create them?
- Use
startActiveSpanto ensure the span context is propagated correctly to child operations. - When calling external services, the instrumentation must propagate context through request headers.
Why don't attributes or events appear on the span?
- Attribute values must be strings, numbers, booleans, or arrays of these types.
- Call
setAttributeoraddEventbefore callingspan.end(). Post-end mutations are ignored.
Next steps
- Set up alerts for your Deno application
- Explore your traces in SigNoz
Get Help
If you need help with the steps in this topic, please reach out to us on SigNoz Community Slack.
If you are a SigNoz Cloud user, please use in product chat support located at the bottom right corner of your SigNoz instance or contact us at cloud-support@signoz.io.