Span Metrics
Learn how attaching attributes to spans provides enhanced application performance monitoring and improved debugging.
Span metrics enable you to attach user defined attributes to spans, which might include application metrics or important debugging context within your application's traces. This approach provides context-rich performance monitoring by connecting attributes directly to the operations that generate them.
These attributes allow you to enrich trace spans with attributes that represent various types of measurement data:
- Performance attributes (memory usage, processing time, latency)
- Business metrics (transaction value, user engagement rates)
- Technical indicators (queue depth, cache hit ratios)
- Debugging context (input parameters, process states)
By attaching attributes directly to spans, you create a unified view of both the execution path and its associated performance data.
// Adding performance metrics to a database span
// Simple database query with dynamic attributes
Sentry.startSpan(
{
name: "Database Query",
op: "db.query",
},
() => {
// Get active span to set attributes as data becomes available
const span = Sentry.getActiveSpan();
// Execute query and add results to span
const result = executeQuery("SELECT * FROM users WHERE active = true");
// Set attributes with the results data
if (span) {
span.setAttribute("db.rows_returned", result.length);
span.setAttribute("db.execution_time_ms", result.executionTime);
}
return result;
},
);
Span attributes provide contextual data that connects execution flow with specific metrics that developers care about, or performance measurements. When investigating an issue, you can view both what occurred (the trace) and the performance characteristics in a single view.
By integrating these attributes into tracing, you can maintain a single telemetry pipeline rather than managing separate systems for traces and metrics, resulting in simplified instrumentation and more efficient monitoring.
// Adding business context to a payment processing span
Sentry.startSpan(
{
name: "Process Payment",
op: "payment.process",
attributes: {
"payment.amount": 99.99,
"payment.currency": "USD",
"payment.method": "credit_card",
"customer.type": "returning",
},
},
async () => {
// Payment processing implementation
},
);
When performance issues arise, these attributes provide the necessary context to quickly identify bottlenecks. For example, when investigating slow checkout processes, you can immediately see which specific component (payment gateway, database query, third-party API) is causing the delay.
Span attributes enable correlation between technical performance data and business outcomes by connecting metrics like response time or error rates directly to business metrics such as conversion rates or revenue.
There are two primary methods for implementing attributes on spans:
Augment automatically-created or manually-defined spans with additional attributes:
// Adding metrics to an existing file upload span
const span = Sentry.getActiveSpan();
if (span) {
// User context
span.setAttribute("user.subscription_tier", "premium");
// Multiple metrics in a single operation
span.setAttributes({
"memory.heap_used": 1024000,
"processing.total_steps": 5,
});
}
Create spans specifically for grouping related attributes or metrics, particularly useful for complex operations:
// Creating a span for monitoring external API usage
Sentry.startSpan(
{
name: "Third-Party API Usage",
op: "external.api",
attributes: {
// Performance metrics
"api.response_time_ms": 245,
// Context data
"feature.using_api": "image_recognition",
"user.plan": "enterprise",
},
},
async () => {
// API call implementation
},
);
The following examples demonstrate how attributes can be applied to common application scenarios:
Monitor client-side performance metrics related to user experience:
// UI performance monitoring
Sentry.startSpan(
{
name: "Page Interaction",
op: "ui.interaction",
attributes: {
"ui.first_input_delay_ms": 24,
"ui.time_to_interactive_ms": 320,
"ui.frames_dropped": 0,
"user.device_type": "mobile",
"feature.being_used": "image_carousel",
},
},
async () => {
// UI interaction handling
},
);
Track database performance characteristics and their impact on application behavior:
// Database query monitoring
Sentry.startSpan(
{
name: "Product Search Query",
op: "db.query",
attributes: {
"db.query_type": "SELECT",
"db.table": "products",
"db.execution_time_ms": 145,
"db.rows_returned": 87,
"db.index_used": "product_category_idx",
"business.search_term": "winter jacket",
"business.search_filters_applied": 3,
},
},
async () => {
// Database query execution
},
);
Monitor file handling operations across your application stack:
// File processing monitoring
Sentry.startSpan(
{
name: "Process Uploaded Image",
op: "file.process",
attributes: {
// Technical metrics
"file.size_bytes": 2500000,
"file.type": "image/jpeg",
// Processing metrics
"processing.steps_completed": ["virus_scan", "resize", "compress"],
"processing.total_time_ms": 850,
// Context data
"feature.using_upload": "user_avatar",
"subscription.allows_hd": true,
},
},
async () => {
// Image processing implementation
},
);
Monitor performance and reliability of third-party service interactions:
// Payment gateway monitoring
Sentry.startSpan(
{
name: "Payment Gateway",
op: "payment.gateway",
attributes: {
// Performance metrics
"gateway.response_time_ms": 980,
"gateway.retry_count": 0,
// Transaction data
"order.total_amount": 159.99,
"order.items_count": 3,
// Service metrics
"gateway.fee_amount": 4.5,
"gateway.fee_percent": 0.029,
},
},
async () => {
// Payment gateway integration
},
);
Select metrics that provide actionable insights for debugging or performance monitoring. Consider which data points would help diagnose issues or make informed decisions about your application.
Maintain consistent naming patterns following the format category.metric_name
to ensure metrics are discoverable and understandable across your organization.
Choose appropriate data types for your metrics:
- Numeric values for measurements (
response_time_ms
: 250) - Boolean values for state indicators (
cache.hit
: true) - String values for categorical data (
user.subscription
: 'premium') - Arrays for multi-value data (
processing.steps_completed
: ['download', 'process', 'upload'])
Be mindful of the performance impact of collecting metrics, especially for high-volume operations:
- Consider implementing sampling for high-frequency operations
- Prioritize metrics with the highest analytical value
- Avoid redundant or closely correlated metrics
If you're currently using Sentry's standalone Metrics product, migrating to span attributes offers several advantages:
- Enhanced context: Attributes are connected directly to the operations that generate them
- Implementation efficiency: A single consistent API for both traces and metrics
- Improved correlation: Direct association between attributes, traces, and errors
Migration process:
- Identify your current metric instrumentation points
- Locate corresponding spans in your application
- Transfer your metrics to span attributes
- Update any dashboards or alerts to reference the new metric sources
For more detailed implementation examples, refer to these guides:
- E-Commerce use case
- LLM integration monitoring
- File upload and processing
- Job scheduling and processing
These examples demonstrate how to implement comprehensive attribute tracking across distributed systems, providing end-to-end visibility into application performance and behavior.
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").