otel-error-handling-playground
TODO
- calling another api
- async continuation of trace
Code dump for async continuation of trace
Producer
const span = trace.getSpan(context.active());
const spanContext = span?.spanContext();
Consumer
import "./tracing";
import { ScanCommand, DeleteCommand } from "@aws-sdk/lib-dynamodb";
import { tracer } from "./utils";
import { documentClient } from "./document-client";
import {
context,
propagation,
ProxyTracerProvider,
ROOT_CONTEXT,
SpanContext,
trace,
} from "@opentelemetry/api";
import { BasicTracerProvider } from "@opentelemetry/tracing";
function getBasicTracerProvider() {
let realTracerProvider = trace.getTracerProvider();
if (realTracerProvider instanceof ProxyTracerProvider) {
realTracerProvider = realTracerProvider.getDelegate();
}
return realTracerProvider instanceof BasicTracerProvider
? realTracerProvider
: undefined;
}
//https://github.com/open-telemetry/opentelemetry-js-api/blob/main/docs/context.md
// what is diff between context and span context?
const purgeOutboxItems = async () => {
const result = await documentClient.send(
new ScanCommand({
TableName: "Outbox",
})
);
if (!result.Count) return;
result.Items!.forEach(async (item: any) => {
const spanContext: SpanContext = item.spanContext;
const carrier = {
traceparent: `00-${spanContext.traceId}-${
spanContext.spanId
}-${spanContext.traceFlags.toString().padStart(2, "0")}`,
};
const ctx = propagation.extract(ROOT_CONTEXT, carrier);
const span = tracer.startSpan("purge-outbox-item", undefined, ctx);
try {
await context.with(trace.setSpan(context.active(), span), async () => {
const r = await documentClient.send(
new DeleteCommand({ TableName: "Outbox", Key: { id: item.id } })
);
});
} catch (e) {
span.recordException(e as Error);
} finally {
span.end();
getBasicTracerProvider()?.getActiveSpanProcessor().forceFlush();
}
});
};
setTimeout(() => {
purgeOutboxItems()
.then(() => console.log("purge successful"))
.catch((e) => console.error("purge failed", e));
}, 2000);