Span Metrics

Learn how to add custom metrics to your spans for enhanced performance monitoring and debugging.

Span metrics allow you to track custom performance data and debugging information within your application's traces. There are two main approaches to instrumenting metrics:

  1. Adding metrics to existing spans
  2. Creating dedicated spans with custom metrics

You can enhance existing spans with custom metrics by adding attributes. This is useful when you want to augment automatic instrumentation or add contextual data to spans you've already created.

Copied
const span = Sentry.getActiveSpan();
if (span) {
  // Add individual metrics
  span.setAttribute("database.rows_affected", 42);
  span.setAttribute("cache.hit_rate", 0.85);

  // Add multiple metrics at once
  span.setAttributes({
    "memory.heap_used": 1024000,
    "queue.length": 15,
    "processing.duration_ms": 127,
  });
}

When adding metrics as span attributes:

  • Use consistent naming conventions (e.g., category.metric_name)
  • Keep attribute names concise but descriptive
  • Use appropriate data types (string, number, boolean, or arrays of these types)
  • Consider the cardinality of your metrics to avoid excessive unique combinations

For more detailed transaction tracking, you can create custom dedicated spans that focus on specific metrics or attributes that you want to track. This approach provides better discoverability and more precise span configurations, however it can also appear to create more noise in your transaction traces.

Copied
Sentry.startSpan(
  {
    name: "Database Query Metrics",
    op: "db.metrics",
    attributes: {
      "db.query_type": "SELECT",
      "db.table": "users",
      "db.execution_time_ms": 45,
      "db.rows_returned": 100,
      "db.connection_pool_size": 5,
    },
  },
  () => {
    // Your database operation here
  },
);

Here are some common patterns for creating metric-focused spans:

Copied
Sentry.startSpan(
  {
    name: "Resource Usage Metrics",
    op: "system.metrics",
    attributes: {
      "cpu.usage_percent": 75.5,
      "memory.used_mb": 1024,
      "memory.free_mb": 512,
      "disk.iops": 150,
    },
  },
  async () => {
    // System operation being monitored
  },
);

Copied
Sentry.startSpan(
  {
    name: "User Session Metrics",
    op: "app.metrics",
    attributes: {
      "session.duration_sec": 300,
      "session.interactions": 25,
      "session.errors": 0,
      "session.latency_ms": 150,
    },
  },
  () => {
    // Session-related code
  },
);

To consistently add metrics across all spans in your application, you can use the beforeSendTransaction callback:

Copied
Sentry.init({
  beforeSendTransaction(event) {
    // Add metrics to the root span
    event.contexts.trace.data = {
      ...event.contexts.trace.data,
      "app.version": "1.2.3",
      "environment.region": "us-west-2",
    };

    // Add metrics to all child spans
    event.spans.forEach((span) => {
      span.data = {
        ...span.data,
        "app.component_version": "2.0.0",
        "app.deployment_stage": "production",
      };
    });

    return event;
  },
});

  1. Metric Naming

    • Use clear, consistent naming patterns
    • Include the metric category (e.g., db, cache, http)
    • Use snake_case for metric names
    • Avoid high-cardinality values in metric names
  2. Data Types

    • Use appropriate numeric types for measurements
    • Use booleans for status flags
    • Use strings for categorical data
    • Use arrays when grouping related values
  3. Performance Considerations

    • Avoid adding too many metrics to a single span
    • Consider the overhead of metric collection
    • Use sampling when collecting high-frequency metrics
    • Balance metric granularity with system performance
  4. Debugging and Monitoring

    • Include relevant error and status information
    • Add timestamps for important events
    • Include correlation IDs for related operations
    • Add context that helps with troubleshooting

Copied
Sentry.startSpan(
  {
    name: "File Upload and Processing",
    op: "file.process",
    attributes: {
      "file.size_bytes": 15728640, // 15MB
      "file.type": "image/jpeg",
      "file.name": "user-profile.jpg",
      "processing.steps_completed": ["resize", "compress", "metadata"],
      "processing.output_size_bytes": 524288, // 512KB
      "processing.compression_ratio": 0.033,
      "upload.chunk_size": 1048576, // 1MB
      "upload.chunks_completed": 15,
      "upload.storage_provider": "s3",
      "upload.cdn_propagation_ms": 1500,
      "error.count": 0,
    },
  },
  async () => {
    // File processing and upload execution
  },
);

Copied
Sentry.startSpan(
  {
    name: "External API Call",
    op: "http.client",
    attributes: {
      "http.endpoint": "/api/users",
      "http.response_size_bytes": 2048,
      "http.retry_count": 0,
      "http.cache_status": "miss",
      "http.response_time_ms": 200,
    },
  },
  async () => {
    // API call execution
  },
);

Copied
Sentry.startSpan(
  {
    name: "LLM Generation",
    op: "ai.completion",
    attributes: {
      "llm.model": "gpt-4",
      "llm.prompt_tokens": 425,
      "llm.completion_tokens": 632,
      "llm.total_tokens": 1057,
      "llm.time_to_first_token_ms": 245,
      "llm.total_duration_ms": 3250,
      "llm.temperature": 0.7,
      "llm.max_tokens": 2000,
      "llm.stream_mode": true,
      "llm.request_status": "success",
    },
  },
  async () => {
    // LLM API call execution
  },
);

Copied
Sentry.startSpan(
  {
    name: "Purchase Transaction",
    op: "commerce.checkout",
    attributes: {
      "cart.item_count": 3,
      "cart.total_amount": 159.99,
      "cart.currency": "USD",
      "cart.items": ["SKU123", "SKU456", "SKU789"],
      "payment.provider": "stripe",
      "payment.method": "credit_card",
      "payment.status": "success",
      "transaction.id": "ord_123456789",
      "customer.type": "returning",
      "shipping.method": "express",
      "promotion.code_applied": "SUMMER23",
      "promotion.discount_amount": 20.0,
    },
  },
  async () => {
    // Checkout process execution
  },
);
Was this helpful?
Help improve this content
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").