#Zuplo OpenTelemetry Plugin
Zuplo ships with an OpenTelemetry plugin that allows you to collect and export telemetry data from your Zuplo API. Currently, the OpenTelemetry plugin implements tracing. Metrics and logging support are planned for future releases.
Enterprise Feature
OpenTelemetry is available as an add-on as part of an enterprise plan. If you would like to purchase this feature, please contact us at sales@zuplo.com or reach out to your account manager.
Most enterprise features can be used in a trial mode for a limited time. Feel free to use enterprise features for development and testing purposes.
#Tracing
Tracing enables you to monitor performance, identify bottlenecks, and troubleshoot issues in your Zuplo API. The OpenTelemetry plugin automatically instruments your API to collect trace data. You can send trace data any OpenTelemetry service such as Honeycomb, Dynatrace, Jaeger, and many more.
With tracing enabled on your Zuplo API you will see timings for each request as well as spans for plugins, handlers, and policies. The OpenTelemetry plugin supports trace propagation (W3C headers by default) so you can trace requests all the way from the client to your backend.
#What is Traced?
By default, when the OpenTelemetry plugin is enabled, the following is traced:
- Request: The entire request lifecycle is traced, including the time taken to process the request and send the response.
- Inbound Policies: The time taken to execute all inbound policies as well as each policy is traced.
- Handler: The request handler is traced
- Outbound Policies: The time taken to execute all outbound policies as well as each policy is traced.
- Subrequests: Any use of
fetch
within your custom policies or handlers will be traced.
#Limitations
One important limitation to keep in mind is that the clock will only increment
when performing I/O operations (for example when calling fetch
, using the
Cache APIs, etc.). This is a limitation imposed as a security measure due
Zuplo's serverless, multi-tenant architecture. In practice this shouldn't impact
your ability to trace as virtually any code that isn't I/O bound is extremely
fast.
#Custom Tracing
You can add custom tracing to your Zuplo API by using the OpenTelemetry API. The example below shows how to implement tracing in a custom policy.
import { ZuploContext, ZuploRequest } from "@zuplo/runtime"; import { trace } from "@opentelemetry/api"; export default async function policy( request: ZuploRequest, context: ZuploContext, ) { const tracer = trace.getTracer("my-tracer"); return tracer.startActiveSpan("my-span", async (span) => { span.setAttribute("key", "value"); try { const results = await Promise.all([ fetch("https://api.example.com/hello"), fetch("https://api.example.com/world"), ]); // ... return request; } finally { span.end(); } }); }ts
This will result in a span that has the following spans:
|--- my-policy | | | |--- my-span | | | | | |--- GET https://api.example.com/hello | | | | | |--- GET https://api.example.com/worldtxt
#Setup
Adding OpenTelemetry tracing to your Zuplo API is done by adding the
OpenTelemetryPlugin
in the zuplo.runtime.ts
file as shown below.
For most providers you will set values for exporter.url
and
exporter.headers
. It is common for providers to use a header for
authorization.
import { OpenTelemetryPlugin } from "@zuplo/otel"; import { RuntimeExtensions, environment } from "@zuplo/runtime"; export function runtimeInit(runtime: RuntimeExtensions) { runtime.addPlugin( new OpenTelemetryPlugin({ exporter: { url: "https://otlp.example.com", headers: { Authorization: `Bearer ${environment.OTEL_API_KEY}`, }, }, service: { name: "my-api", }, }), ); }ts