Skip to content

OpenTelemetry Integration

Volidator integrates with OpenTelemetry (OTel) to let you seamlessly correlate security compliance logs with distributed system traces. By using the @volidator/node/otel extension, you gain deep observability into AI agent pipelines, multi-service hops, and system behaviors without manually passing tracing IDs.


To keep the core @volidator/node SDK lightweight and serverless-friendly, the OpenTelemetry integration packages are defined as optional peer dependencies. If you wish to use OTel features, ensure you have the following packages installed:

Terminal window
npm install @opentelemetry/api @opentelemetry/sdk-trace-base @opentelemetry/sdk-logs @opentelemetry/core

The simplest way to use OpenTelemetry with Volidator is automatic context correlation. Just import the subpath at the entry point of your application:

import "@volidator/node/otel";

When you import the OTel plugin, it auto-registers context resolution hooks inside the core SDK. Any subsequent compliance logging call will automatically look up the active OpenTelemetry span and map its traceId and spanId to the log entry:

import { VolidatorClient } from "@volidator/node";
import "@volidator/node/otel";
const volidator = new VolidatorClient({
apiKey: process.env.VOLIDATOR_API_KEY!,
encryptionKey: process.env.VOLIDATOR_ENCRYPTION_KEY!,
});
// Executed inside an active OpenTelemetry trace scope:
await volidator.log({
action: "user.data_exported",
actor: "usr_alice",
// traceId and spanId are fetched and correlated automatically!
});

If your infrastructure routes all telemetry (traces, metrics, and logs) through a centralized OpenTelemetry collector or agent (such as Datadog, Jaeger, or Grafana Agent), you can use Volidator’s custom exporters.

[!IMPORTANT] Local E2EE Decryption Requirement: Because Volidator relies on a Zero-Knowledge model, log data must be encrypted before leaving your application server. Both exporters require your active VolidatorClient instance in their constructors to securely encrypt log payloads locally before dispatching them.

Trace Span Exporter (VolidatorSpanExporter)

Section titled “Trace Span Exporter (VolidatorSpanExporter)”

Registers as a span exporter in your OpenTelemetry Tracer Provider. It processes span metadata and routes compliance logs to the Volidator ingestion worker:

import { BasicTracerProvider, SimpleSpanProcessor } from "@opentelemetry/sdk-trace-base";
import { VolidatorSpanExporter } from "@volidator/node/otel";
import { volidatorClient } from "./volidator";
const provider = new BasicTracerProvider();
const exporter = new VolidatorSpanExporter(volidatorClient);
// Add the exporter to your span processor pipeline
provider.addSpanProcessor(new SimpleSpanProcessor(exporter));
provider.register();

To emit audit events through standard spans, set the following attributes on your OTel spans:

const tracer = trace.getTracer("app-tracer");
tracer.startActiveSpan("user-login", (span) => {
span.setAttribute("volidator.action", "user.login");
span.setAttribute("volidator.actor", "usr_alice");
span.setAttribute("volidator.target", "workspace_123");
// The VolidatorSpanExporter automatically captures, encrypts, and forwards this!
span.end();
});

Log Record Exporter (VolidatorLogExporter)

Section titled “Log Record Exporter (VolidatorLogExporter)”

Integrates standard @opentelemetry/sdk-logs logging with Volidator’s E2EE log collection:

import { LoggerProvider, SimpleLogRecordProcessor } from "@opentelemetry/sdk-logs";
import { VolidatorLogExporter } from "@volidator/node/otel";
import { volidatorClient } from "./volidator";
const loggerProvider = new LoggerProvider();
const logExporter = new VolidatorLogExporter(volidatorClient);
loggerProvider.addLogRecordProcessor(new SimpleLogRecordProcessor(logExporter));
const logger = loggerProvider.getLogger("app-logger");
logger.emit({
body: "Audit Event",
attributes: {
"volidator.action": "file.download",
"volidator.actor": "usr_bob",
},
});

You can configure VolidatorClient to route all direct volidator.log() calls into your active OpenTelemetry span context as standard span events. This lets you gather traces first and batch them via your collector rather than firing multiple HTTP requests directly to the Volidator ingestion endpoint:

import { enableOtelDriverRedirect } from "@volidator/node/otel";
import { volidator } from "./volidator";
// Enable global log redirection to OTel
enableOtelDriverRedirect(volidator);
// Now, this call will write a span event to your active OpenTelemetry span
// instead of hitting the Volidator API endpoint directly:
await volidator.log({
action: "sensitive.action",
actor: "usr_carol",
});