> ## Documentation Index
> Fetch the complete documentation index at: https://www.adaline.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Monitor

# 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 buffer management.

## 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 or buffer size
* **Retries** failed requests with exponential backoff
* **Tracks** sent and dropped entries for monitoring

## Creation

Create a Monitor using the `Adaline.initMonitor()` method:

```typescript theme={null}
import { Adaline } from '@adaline/client';

const adaline = new Adaline();

const monitor = adaline.initMonitor({
  projectId: 'your-project-id',
});
```

With custom configuration:

```typescript theme={null}
const monitor = adaline.initMonitor({
  projectId: 'your-project-id',
  flushInterval: 5,        // flush every 5 seconds (default: 1)
  maxBufferSize: 100,      // flush when 100 items buffered (default: 1000)
});
```

## Properties

### buffer

```typescript theme={null}
buffer: BufferedEntry[]
```

In-memory array of [BufferedEntry](https://www.adaline.ai/docs/reference/sdk/v2/typescript/types/BufferedEntry.md) items storing traces and spans waiting to be flushed.

> [!NOTE]
>
> Items are added when you call `logTrace()` or `logSpan()`, and removed after successful flush.

**Example:**

```typescript theme={null}
console.log(`Buffer size: ${monitor.buffer.length}`);

// Inspect buffered items
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);
  }
});
```

### projectId

```typescript theme={null}
projectId: string
```

The project ID that all traces and spans are associated with.

### sentCount

```typescript theme={null}
sentCount: number
```

Number of entries successfully sent to the API.

### droppedCount

```typescript theme={null}
droppedCount: number
```

Number of entries dropped due to buffer overflow or send failure.

### defaultContent

```typescript theme={null}
defaultContent: LogSpanContent
```

Default [LogSpanContent](https://www.adaline.ai/docs/reference/sdk/v2/typescript/types/LogSpanContent.md) used when no explicit content is provided. Defaults to `{ type: 'Other', input: '{}', output: '{}' }`.

### logger

```typescript theme={null}
readonly logger: Logger
```

[Logger](https://www.adaline.ai/docs/reference/sdk/v2/typescript/types/Logger.md) instance used for SDK diagnostics.

## Methods

### logTrace()

Create a new trace and add it to the buffer.

```typescript theme={null}
logTrace(options: LogTraceOptions): Trace
```

#### Parameters

**options** `object` *required*

**properties**

**name** `string` *required*

Human-readable name for this trace (e.g., "User Login", "Generate Report").

**status** `TraceStatus` (default: unknown)

Initial [TraceStatus](https://www.adaline.ai/docs/reference/sdk/v2/typescript/types/TraceStatus.md): `'success' | 'failure' | 'aborted' | 'cancelled' | 'pending' | 'unknown'`

**sessionId** `string`

Session identifier to group related traces (e.g., user session ID).

**referenceId** `string`

Custom reference ID for this trace. Auto-generated UUID if not provided.

**tags** `string[]`

Array of tags for categorization and filtering (e.g., `['api', 'production']`).

**attributes** `Record\<string, LogAttributesValue\>`

Key-value metadata ([LogAttributesValue](https://www.adaline.ai/docs/reference/sdk/v2/typescript/types/LogAttributesValue.md)) for additional context (e.g., `{ userId: '123', region: 'us-east' }`).

#### Returns

**trace** `Trace`

A new Trace instance. See [Trace Class](https://www.adaline.ai/docs/reference/sdk/v2/typescript/classes/trace.md) for details.

#### Examples

```typescript Basic theme={null}
const trace = monitor.logTrace({
  name: 'API Request'
});

// Do work...

trace.end();
```

```typescript With Session theme={null}
const trace = monitor.logTrace({
  name: 'Chat Turn',
  sessionId: `user-${userId}`,
  tags: ['chat', 'production'],
  attributes: {
    userId: userId,
    messageCount: 5
  }
});
```

```typescript Pending Operation theme={null}
const trace = monitor.logTrace({
  name: 'Batch Processing',
  status: 'pending',
  tags: ['batch', 'async'],
  attributes: {
    batchId: 'batch-123',
    itemCount: 1000
  }
});

try {
  // Process batch...
  trace.update({ status: 'success' });
} catch (error) {
  trace.update({ status: 'failure' });
}

trace.end();
```

```typescript Custom Reference ID theme={null}
// Use your own ID for correlation with external systems
const trace = monitor.logTrace({
  name: 'Order Processing',
  referenceId: `order-${orderId}`,
  attributes: { orderId }
});
```

### flush()

Manually flush all ready entries in the buffer to the API.

```typescript theme={null}
async flush(): Promise<void>
```

> [!NOTE]
>
> This method is automatically called on a timer (based on `flushInterval`) and when the buffer reaches `maxBufferSize`. Manual calls are typically only needed during shutdown (especially in serverless environments) or testing.

#### Behavior

1. Skips if a flush is already in progress (prevents concurrent flushes)
2. Filters for entries marked as `ready` (via `trace.end()` or `span.end()`)
3. Sends each entry to the API with automatic retry
4. Updates `traceId` on traces after successful creation
5. Removes successfully flushed entries from buffer
6. Drops entries that fail after retries and increments `droppedCount`

#### Retry Logic

* **5xx errors**: Retry with exponential backoff (up to 10 retries, 20s total)
* **4xx errors**: Fail immediately (no retry)
* **Network errors**: Retry with exponential backoff

#### Examples

```typescript Manual Flush theme={null}
const trace = monitor.logTrace({ name: 'Important Event' });
trace.end();

// Ensure it's sent immediately
await monitor.flush();
```

```typescript Graceful Shutdown theme={null}
process.on('SIGTERM', async () => {
  console.log('Shutting down...');
  
  // Flush any remaining entries
  await monitor.flush();
  
  // Stop background flush
  monitor.stop();
  
  process.exit(0);
});
```

```typescript Testing theme={null}
test('logs trace successfully', async () => {
  const trace = monitor.logTrace({ name: 'Test Trace' });
  trace.end();
  
  // Flush and wait for API call
  await monitor.flush();
  
  // Check results
  expect(trace.traceId).toBeDefined();
  expect(monitor.buffer.length).toBe(0);
});
```

### stop()

Stop the background flush timer.

```typescript theme={null}
stop(): void
```

> [!WARNING]
>
> After calling `stop()`, the monitor will no longer automatically flush. You must manually call `flush()` to send buffered entries.

#### Example

```typescript theme={null}
const monitor = adaline.initMonitor({ projectId: 'proj_123' });

// Use the monitor...

// Stop when done (e.g., during shutdown)
monitor.stop();

// Final flush
await monitor.flush();
```

### enforceBufferLimit()

Enforces the `maxBufferSize` limit by dropping the oldest entries when the buffer is full.

```typescript theme={null}
enforceBufferLimit(): void
```

> [!NOTE]
>
> This method is called automatically when entries are added to the buffer. You typically don't need to call it manually.

## Complete Examples

### Basic Usage

```typescript theme={null}
import { Adaline } from '@adaline/client';

const adaline = new Adaline();
const monitor = adaline.initMonitor({
  projectId: 'my-project',
});

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']
  });

  // Do work...
  await processData();

  span.update({ status: 'success' });
  span.end();

  trace.update({ status: 'success' });
  trace.end();

  // Automatically flushed based on timer/buffer size
}
```

### Production Setup with Health Monitoring

```typescript theme={null}
import { Adaline } from '@adaline/client';

const adaline = new Adaline({ debug: true });

const monitor = adaline.initMonitor({
  projectId: process.env.PROJECT_ID!,
  flushInterval: 5,
  maxBufferSize: 100,
});

// Health check
setInterval(() => {
  const bufferSize = monitor.buffer.length;

  console.log('Monitor Health:', {
    bufferSize,
    sentCount: monitor.sentCount,
    droppedCount: monitor.droppedCount,
  });

  if (monitor.droppedCount > 0) {
    console.warn(`${monitor.droppedCount} entries have been dropped`);
  }

  if (bufferSize > 50) {
    console.warn('Monitor buffer growing', { bufferSize });
  }
}, 60000); // Check every minute

// Graceful shutdown
process.on('SIGTERM', async () => {
  console.log('Shutting down...');
  
  try {
    await monitor.flush();
    console.log('Flushed remaining entries');
  } catch (error) {
    console.error('Error during final flush:', error);
  }
  
  monitor.stop();
  process.exit(0);
});
```

### High-Volume Application

```typescript theme={null}
import { Adaline } from '@adaline/client';

const adaline = new Adaline();

// Optimize for high volume
const monitor = adaline.initMonitor({
  projectId: 'high-volume-app',
  flushInterval: 2,
  maxBufferSize: 500,
});

// Monitor buffer usage
setInterval(() => {
  const bufferSize = monitor.buffer.length;
  
  // Warn if buffer is growing
  if (bufferSize > 300) {
    console.warn(`Buffer size: ${bufferSize} (high volume)`);
  }
  
  // Force flush if critical
  if (bufferSize > 450) {
    console.warn('Forcing flush due to high buffer size');
    monitor.flush().catch(err => {
      console.error('Forced flush failed:', err);
    });
  }
}, 1000);

// Request handler
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,
      userAgent: req.headers.get('user-agent') || 'unknown'
    }
  });

  try {
    const result = await processRequest(req);
    trace.update({ status: 'success' });
    return result;
  } catch (error) {
    trace.update({ status: 'failure' });
    throw error;
  } finally {
    trace.end();
  }
}
```

### Testing with Monitor

```typescript theme={null}
import { Adaline } from '@adaline/client';
import { describe, test, expect, beforeEach, afterEach } from '@jest/globals';

describe('Monitor Tests', () => {
  let adaline: Adaline;
  let monitor: Monitor;

  beforeEach(() => {
    adaline = new Adaline();
    monitor = adaline.initMonitor({
      projectId: 'test-project',
      flushInterval: 999999 // Don't auto-flush during tests
    });
  });

  afterEach(async () => {
    await monitor.flush();
    monitor.stop();
  });

  test('creates trace and span', async () => {
    const trace = monitor.logTrace({ name: 'Test Trace' });
    const span = trace.logSpan({ name: 'Test Span' });

    expect(monitor.buffer.length).toBe(2);

    span.end();
    trace.end();

    expect(monitor.buffer.filter(e => e.ready).length).toBe(2);

    await monitor.flush();

    expect(trace.traceId).toBeDefined();
    expect(monitor.buffer.length).toBe(0);
    expect(monitor.sentCount).toBeGreaterThan(0);
  });

  test('handles flush failures', async () => {
    const trace = monitor.logTrace({ name: 'Invalid' });
    trace.end();

    // Mock API to fail
    // ... your mocking code ...

    await monitor.flush();

    expect(monitor.droppedCount).toBeGreaterThan(0);
  });

  test('respects buffer size limit', () => {
    const smallMonitor = adaline.initMonitor({
      projectId: 'test',
      maxBufferSize: 2,
      flushInterval: 999999
    });

    const trace1 = smallMonitor.logTrace({ name: 'T1' });
    const trace2 = smallMonitor.logTrace({ name: 'T2' });
    const trace3 = smallMonitor.logTrace({ name: 'T3' });

    trace1.end();
    trace2.end();
    trace3.end();

    // Buffer should be capped at maxBufferSize
    // ... assertions ...
  });
});
```

## Type Definitions

```typescript theme={null}
interface LogTraceOptions {
  name: string;
  status?: TraceStatus;
  sessionId?: string;
  referenceId?: string;
  tags?: string[];
  attributes?: Record<string, LogAttributesValue>;
}

type LogAttributesValue = 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 };
```

> [!NOTE]
>
> The `attributes` field accepts `Record<string, LogAttributesValue>` where [LogAttributesValue](https://www.adaline.ai/docs/reference/sdk/v2/typescript/types/LogAttributesValue.md) = `string | number | boolean`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.