Overview
addSpanEvent() adds a named event with optional attributes to the currently active span. Events are useful for marking significant milestones or state changes within a span.
Signature
addSpanEvent(
name: string,
attributes?: Record<string, any>
): void
Basic Usage
import { KeywordsAITelemetry } from '@keywordsai/tracing';
const keywordsAi = new KeywordsAITelemetry({
apiKey: process.env.KEYWORDSAI_API_KEY,
appName: 'my-app'
});
await keywordsAi.initialize();
await keywordsAi.withTask(
{ name: 'data_processing' },
async () => {
const client = keywordsAi.getClient();
client.addSpanEvent('processing_started');
const data = await fetchData();
client.addSpanEvent('data_fetched', {
records: data.length
});
const processed = await processData(data);
client.addSpanEvent('processing_completed', {
records_processed: processed.length,
success_rate: 0.98
});
return processed;
}
);
Batch Processing Events
await keywordsAi.withWorkflow(
{ name: 'batch_job' },
async () => {
const client = keywordsAi.getClient();
client.addSpanEvent('batch_started', {
total_batches: 10
});
for (let i = 0; i < 10; i++) {
await processBatch(i);
client.addSpanEvent('batch_completed', {
batch_number: i,
records: 100,
duration_ms: 150
});
}
client.addSpanEvent('all_batches_completed', {
total_records: 1000
});
return 'done';
}
);
API Call Events
await keywordsAi.withTask(
{ name: 'external_api_call' },
async () => {
const client = keywordsAi.getClient();
client.addSpanEvent('request_prepared', {
endpoint: '/api/users',
method: 'GET'
});
const response = await fetch('https://api.example.com/users');
client.addSpanEvent('response_received', {
status_code: response.status,
content_type: response.headers.get('content-type')
});
const data = await response.json();
client.addSpanEvent('response_parsed', {
records: data.length
});
return data;
}
);
State Transitions
await keywordsAi.withAgent(
{ name: 'workflow_agent' },
async () => {
const client = keywordsAi.getClient();
client.addSpanEvent('state_changed', {
from: 'idle',
to: 'planning'
});
const plan = await createPlan();
client.addSpanEvent('state_changed', {
from: 'planning',
to: 'executing'
});
const result = await executePlan(plan);
client.addSpanEvent('state_changed', {
from: 'executing',
to: 'completed'
});
return result;
}
);
Error Context Events
await keywordsAi.withTask(
{ name: 'retry_operation' },
async () => {
const client = keywordsAi.getClient();
let attempt = 0;
while (attempt < 3) {
try {
client.addSpanEvent('attempt_started', {
attempt_number: attempt + 1
});
const result = await unstableApiCall();
client.addSpanEvent('attempt_succeeded', {
attempt_number: attempt + 1
});
return result;
} catch (error) {
client.addSpanEvent('attempt_failed', {
attempt_number: attempt + 1,
error_message: error.message
});
attempt++;
if (attempt >= 3) throw error;
}
}
}
);
await keywordsAi.withWorkflow(
{ name: 'image_processing' },
async () => {
const client = keywordsAi.getClient();
const startTime = Date.now();
client.addSpanEvent('download_started');
const image = await downloadImage();
client.addSpanEvent('download_completed', {
duration_ms: Date.now() - startTime,
size_bytes: image.size
});
const resizeStart = Date.now();
client.addSpanEvent('resize_started');
const resized = await resizeImage(image);
client.addSpanEvent('resize_completed', {
duration_ms: Date.now() - resizeStart,
dimensions: resized.dimensions
});
const uploadStart = Date.now();
client.addSpanEvent('upload_started');
await uploadImage(resized);
client.addSpanEvent('upload_completed', {
duration_ms: Date.now() - uploadStart
});
return 'done';
}
);
Parameters
Event name for identification
Optional key-value pairs with additional event context
Best Practices
- Use events to mark significant milestones in span execution
- Include relevant attributes for context (counts, durations, status codes)
- Add events before and after critical operations
- Use consistent naming conventions for events
- Events are automatically timestamped
- Only call within an active span
- Events are visible in the Keywords AI dashboard timeline