Monitor Class
The Monitor class manages buffering, batching, and flushing of traces and spans to the Adaline API. It handles automatic retries, background flushing, and failure tracking.
Overview
The Monitor acts as a central coordinator for all observability operations:
Buffers traces and spans in memory
Batches multiple entries for efficient API calls
Flushes automatically based on time intervals
Retries failed requests with exponential backoff
Drops entries that fail after retries, following OpenTelemetry error handling principles (telemetry failures never propagate to your application)
Creation
Create a Monitor using the Adaline.initMonitor() method:
import { Adaline } from '@adaline/client' ;
const adaline = new Adaline ();
const monitor = adaline . initMonitor ({
projectId: 'your-project-id' ,
flushInterval: 5 ,
maxBufferSize: 100
});
Properties
buffer
In-memory array storing traces and spans waiting to be flushed.
Items are added when you call logTrace() or logSpan(), and removed after successful flush. When the buffer exceeds maxBufferSize, the oldest entries are dropped.
Example:
console . log ( `Buffer size: ${ monitor . buffer . length } ` );
monitor . buffer . forEach ( entry => {
if ( entry . category === 'trace' ) {
console . log ( 'Trace:' , entry . data . trace . trace . name );
} else {
console . log ( 'Span:' , entry . data . span . span . name );
}
});
sentCount
Number of entries successfully sent to the API.
Example:
console . log ( `Successfully sent: ${ monitor . sentCount } ` );
droppedCount
Number of entries dropped due to buffer overflow or send failure.
Example:
console . log ( `Dropped entries: ${ monitor . droppedCount } ` );
if ( monitor . droppedCount > 0 ) {
console . warn ( 'Some telemetry entries were dropped' );
}
projectId
The project ID that all traces and spans are associated with.
defaultContent
defaultContent : LogSpanContent
Default span content used when no explicit content is provided. Defaults to { type: 'Other', input: '{}', output: '{}' }.
logger
The logger instance used for SDK diagnostics.
Methods
logTrace()
Create a new trace and add it to the buffer.
logTrace ( options : LogTraceOptions ): Trace
Parameters
Human-readable name for this trace (e.g., “User Login”, “Generate Report”).
status
TraceStatus
default: "unknown"
Initial status: 'success' | 'failure' | 'aborted' | 'cancelled' | 'pending' | 'unknown'
Session identifier to group related traces (e.g., user session ID).
Custom reference ID for this trace. Auto-generated UUID if not provided.
Array of tags for categorization and filtering (e.g., ['api', 'production']).
attributes
Record<string, string | number | boolean>
Key-value metadata for additional context (e.g., { userId: '123', region: 'us-east' }).
Returns
Examples
Basic
With Session
Custom Reference ID
const trace = monitor . logTrace ({
name: 'API Request'
});
trace . end ();
flush()
Manually flush all ready entries in the buffer to the API.
async flush (): Promise < void >
This method is automatically called on a timer (based on flushInterval). Manual calls are typically only needed during shutdown (especially in serverless environments) or testing.
Behavior
Skips if a flush is already in progress (prevents concurrent flushes)
Filters for entries marked as ready (via trace.end() or span.end())
Sends each entry to the API with automatic retry
Updates traceId on traces after successful creation
Removes successfully flushed entries from buffer
Increments droppedCount for entries that fail after retries
Retry Logic
5xx errors : Retry with exponential backoff (up to 10 retries, 20s total budget)
4xx errors : Fail immediately (no retry)
Network errors : Retry with exponential backoff
Examples
Manual Flush
Graceful Shutdown
Testing
const trace = monitor . logTrace ({ name: 'Important Event' });
trace . end ();
await monitor . flush ();
stop()
Stop the background flush timer.
After calling stop(), the monitor will no longer automatically flush. You must manually call flush() to send buffered entries.
Example
const monitor = adaline . initMonitor ({ projectId: 'proj_123' });
// ... use the monitor ...
// Flush remaining entries, then stop
await monitor . flush ();
monitor . stop ();
enforceBufferLimit()
Drops the oldest entries if the buffer exceeds maxBufferSize.
enforceBufferLimit (): void
This method is called automatically by logTrace() and logSpan(). You typically don’t need to call it manually.
Complete Examples
Basic Usage
import { Adaline } from '@adaline/client' ;
const adaline = new Adaline ();
const monitor = adaline . initMonitor ({
projectId: 'my-project' ,
flushInterval: 5 ,
maxBufferSize: 100
});
async function handleRequest ( userId : string ) {
const trace = monitor . logTrace ({
name: 'User Request' ,
sessionId: userId ,
tags: [ 'api' ]
});
const span = trace . logSpan ({
name: 'Process Data' ,
tags: [ 'processing' ]
});
await processData ();
span . update ({ status: 'success' });
span . end ();
trace . update ({ status: 'success' });
trace . end ();
}
Production Setup with Health Monitoring
import { Adaline } from '@adaline/client' ;
const adaline = new Adaline ({ debug: true });
const monitor = adaline . initMonitor ({
projectId: process . env . PROJECT_ID ! ,
flushInterval: 5 ,
maxBufferSize: 200
});
setInterval (() => {
console . log ( 'Monitor Health:' , {
bufferSize: monitor . buffer . length ,
sent: monitor . sentCount ,
dropped: monitor . droppedCount
});
if ( monitor . droppedCount > 0 ) {
alertOps ( 'Monitor dropping entries' , { dropped: monitor . droppedCount });
}
}, 60000 );
process . on ( 'SIGTERM' , async () => {
try {
await monitor . flush ();
} catch ( error ) {
console . error ( 'Error during final flush:' , error );
}
monitor . stop ();
process . exit ( 0 );
});
High-Volume Application
import { Adaline } from '@adaline/client' ;
const adaline = new Adaline ();
const monitor = adaline . initMonitor ({
projectId: 'high-volume-app' ,
flushInterval: 2 ,
maxBufferSize: 500
});
async function handleRequest ( req : Request ) {
const trace = monitor . logTrace ({
name: req . url ,
sessionId: req . headers . get ( 'session-id' ) || undefined ,
tags: [ 'api' , 'high-volume' ],
attributes: {
method: req . method ,
path: req . url ,
}
});
try {
const result = await processRequest ( req );
trace . update ({ status: 'success' });
return result ;
} catch ( error ) {
trace . update ({ status: 'failure' });
throw error ;
} finally {
trace . end ();
}
}
Type Definitions
interface LogTraceOptions {
name : string ;
status ?: TraceStatus ;
sessionId ?: string ;
referenceId ?: string ;
tags ?: string [];
attributes ?: Record < string , string | number | boolean >;
}
type TraceStatus = 'success' | 'failure' | 'aborted' | 'cancelled' | 'pending' | 'unknown' ;
type BufferedEntry =
| { ready : boolean ; category : 'trace' ; data : Trace }
| { ready : boolean ; category : 'span' ; data : Span };