Installation
npm install @autoblocks/client
Basic Example
Here’s a simple example showing how to use tracing with OpenAI:
import { traceApp, init } from '@autoblocks/client/tracer';
import OpenAI from 'openai';
// Initialize tracing
init();
// Initialize OpenAI client
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
// Create a traced application
const generateResponse = async (prompt: string) => {
const response = await openai.chat.completions.create({
model: 'gpt-4',
messages: [{ role: 'user', content: prompt }],
});
return response.choices[0].message.content;
};
// Run the application
await traceApp(
'my-app',
'production',
generateResponse,
this,
{
prompt: 'Hello, how are you?',
}
);
Advanced Usage
Creating Spans
You can create custom spans using OpenTelemetry’s tracer:
import { trace } from '@opentelemetry/api';
import { SpanKind } from '@opentelemetry/api';
const tracer = trace.getTracer('my-tracer');
async function myFunction() {
const span = tracer.startSpan('my_operation', {
kind: SpanKind.INTERNAL,
attributes: {
custom_attribute: 'value'
}
});
try {
// Your code here
span.setAttribute('result', 'success');
} catch (error) {
span.recordException(error);
span.setStatus({ code: SpanStatusCode.ERROR });
throw error;
} finally {
span.end();
}
}
Error Handling
Record exceptions in spans:
try {
// Your code here
} catch (error) {
span.recordException(error);
span.setStatus({ code: SpanStatusCode.ERROR });
throw error;
}
Adding Attributes
Add attributes to spans for better context:
span.setAttribute('model', 'gpt-4');
span.setAttribute('temperature', 0.7);
span.setAttribute('max_tokens', 100);
Nested Spans
Create nested spans to represent complex operations:
async function complexOperation() {
const parentSpan = tracer.startSpan('parent_operation');
parentSpan.setAttribute('parent_data', 'value');
try {
const childSpan = tracer.startSpan('child_operation', {
parent: parentSpan
});
childSpan.setAttribute('child_data', 'value');
try {
// Child operation code
} finally {
childSpan.end();
}
} finally {
parentSpan.end();
}
}
Best Practices
-
Span Naming
- Use descriptive names that reflect the operation
- Follow a consistent naming convention
- Include the operation type in the name
-
Attribute Management
- Add relevant context to spans
- Avoid logging sensitive data
- Use consistent attribute names
-
Error Handling
- Always record exceptions
- Set appropriate error status
- Include error details in attributes
-
Performance
- Keep spans focused
- Avoid excessive attributes
- Use sampling for high-volume applications
-
Async Operations
- Properly handle async/await with spans
- Ensure spans are ended in finally blocks
- Use Promise.all for parallel operations
-
TypeScript Integration
- Use proper types for spans and attributes
- Leverage TypeScript’s type system for safety
- Document complex types and interfaces
Additional Resources
OpenTelemetry
OpenLLMetry
Next Steps