Create a PluginObservable
DTrace object
Resource context
IPluginObservable instance (unified logging and metrics backend)
Initial attributes
Optionalspan: TraceOptional Trace/Span object (if created via startSpan())
Logging methods with automatic trace context
All log methods automatically include trace context (trace ID, span ID) in the output. Logs support placeholder syntax for structured logging.
Metrics methods for creating counters, gauges, histograms, and timers
// Counter for tracking requests
const requests = obs.metrics.counter(
"requests_total",
"Total requests",
"Count of all incoming requests",
["method", "status"]
);
requests.increment(1, { method: "GET", status: "200" });
// Timer for measuring duration
const timer = obs.metrics.timer();
await processRequest();
const duration = timer.stop();
obs.log.info("Request took {ms}ms", { ms: duration });
Core trace information (W3C compatible)
Trace ID (unique identifier for the entire trace)
Span ID (unique identifier for this specific span)
Resource context (service name, version, instance ID, environment, region) Automatically populated from plugin configuration
Custom attributes attached to this observable Attributes are immutable - use setAttribute() to create new observable with additional attributes
Create a child span with inherited attributes
Creates a new Observable representing a child span for distributed tracing. All attributes from the parent are automatically inherited by the child.
Name of the span (e.g., "database-query", "api-call")
Optionalattributes: Record<string, string | number | boolean>Additional attributes to add to this span
New Observable instance representing the child span
public async processOrder(obs: Observable) {
// Create child span for database operation
const dbSpan = obs.startSpan("fetch-order", { "order.id": "123" });
try {
const order = await this.db.getOrder("123");
dbSpan.end({ "order.status": order.status });
} catch (error) {
dbSpan.error(error);
dbSpan.end();
}
}
Create a new Observable with an additional attribute
Observables are immutable - this returns a new instance with the added attribute. The attribute is propagated to all child operations (logs, spans, etc.).
New Observable instance with the added attribute
public async handleRequest(obs: Observable, userId: string) {
// Add user ID to all subsequent operations
const withUser = obs.setAttribute("user.id", userId);
withUser.log.info("Processing request"); // Log includes user.id
const span = withUser.startSpan("process"); // Span includes user.id
}
Create a new Observable with multiple attributes
Observables are immutable - this returns a new instance with the added attributes. All attributes are propagated to child operations.
Object containing attributes to add
New Observable instance with the added attributes
Record an error to both logs and traces
This method automatically records the error to both the logging system and the active span (if this Observable was created via startSpan()). This ensures errors are captured in both systems for complete observability.
Error or BSBError instance to record
Optionalattributes: Record<string, string | number | boolean>Additional attributes to attach to the error
End the span (only applies if this Observable was created via startSpan())
Completes the span and records the final state. If this Observable was not created via startSpan(), this method does nothing. Always call end() when the operation is complete to ensure proper trace completion.
Optionalattributes: Record<string, string | number | boolean>Final attributes to attach before ending the span
public async fetchData(obs: Observable) {
const span = obs.startSpan("fetch-data");
try {
const data = await this.api.fetch();
span.end({ "data.size": data.length, "status": "success" });
return data;
} catch (error) {
span.error(error as Error);
span.end({ "status": "failed" });
throw error;
}
}
Implementation of Observable interface that wraps DTrace with observability features
See
API: PluginObservable