Loading...
Loading...
Next.js/Vercel OpenTelemetry style: instrumentation.ts, @vercel/otel bootstrap, native @opentelemetry/api call sites, inline endpoint + ingest key, and no raw NodeSDK replacement.
npx skill4agent add superloglabs/skills otel-nextjs-style// instrumentation.ts
import { registerOTel } from "@vercel/otel";
export function register() {
registerOTel({
serviceName: "mugline-web",
});
}NodeSDK@vercel/otel@2.xlogRecordProcessorimport Anthropic from "@anthropic-ai/sdk";
import { AnthropicInstrumentation } from "@arizeai/openinference-instrumentation-anthropic";
import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-http";
import { BatchLogRecordProcessor } from "@opentelemetry/sdk-logs";
import { registerOTel } from "@vercel/otel";
const anthropicInstrumentation = new AnthropicInstrumentation({
traceConfig: {
hideInputs: true,
hideOutputs: true,
},
});
anthropicInstrumentation.manuallyInstrument(Anthropic);
export function register() {
registerOTel({
serviceName: "mugline-web",
instrumentations: [anthropicInstrumentation],
logRecordProcessors: [new BatchLogRecordProcessor(new OTLPLogExporter())],
});
}import { withSpan } from "@superlog/otel-helpers";
const tracer = trace.getTracer("mugline.web");
const meter = metrics.getMeter("mugline.web");
const requests = meter.createCounter("mug.copy.generated");
export async function POST(request: Request) {
const tenantId = request.headers.get("x-tenant-id") ?? "tenant_demo";
return await withSpan("mug.copy.generate", async (span) => {
span.setAttribute("tenant.id", tenantId);
requests.add(1, { "tenant.id": tenantId, outcome: "success" });
return Response.json({ ok: true });
}, { tracer });
}@superlog/otel-helperswithSpan@superlog/otel-helperspackage.jsontracer.startActiveSpan(...)trycatchfinallyclient.messages.create(...)manuallyInstrument(Anthropic)@vercel/otel@vercel/otel@1.xlogRecordProcessor@vercel/otel@2.xlogRecordProcessorsregisterOTel(...)NEXT_RUNTIMEinstrumentation.ts@vercel/otelconsole.info@opentelemetry/api-logsconsole.*logger.emit({
severityNumber: SeverityNumber.INFO,
severityText: "INFO",
body: "generated mug copy",
attributes: {
"tenant.id": tenantId,
"gen_ai.provider.name": "anthropic",
"gen_ai.request.model": model,
"app.gen_ai.use_case": "web.mug_copy",
outcome: "success",
},
});instrumentation.tsregisterOTelOTEL_EXPORTER_OTLP_*const SUPERLOG_ENDPOINT = "https://intake.superlog.sh";
const SUPERLOG_KEY = "superlog_live_…"; // set by superlog-onboard skill on pairing
registerOTel({
serviceName: "mugline-web",
traceExporter: new OTLPTraceExporter({
url: `${SUPERLOG_ENDPOINT}/v1/traces`,
headers: { authorization: `Bearer ${SUPERLOG_KEY}` },
}),
// …same shape for log + metric exporters
});npm run typechecknpm run buildts-node