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

  1. Span Naming

    • Use descriptive names that reflect the operation
    • Follow a consistent naming convention
    • Include the operation type in the name
  2. Attribute Management

    • Add relevant context to spans
    • Avoid logging sensitive data
    • Use consistent attribute names
  3. Error Handling

    • Always record exceptions
    • Set appropriate error status
    • Include error details in attributes
  4. Performance

    • Keep spans focused
    • Avoid excessive attributes
    • Use sampling for high-volume applications
  5. Async Operations

    • Properly handle async/await with spans
    • Ensure spans are ended in finally blocks
    • Use Promise.all for parallel operations
  6. 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