@@ -20,22 +20,17 @@ By attaching attributes directly to spans, you create a unified view of both the
2020// Simple database query with dynamic attributes
2121Sentry .startSpan (
2222 {
23- name: ' Database Query' ,
24- op: ' db.query'
23+ name: " Database Query" ,
24+ op: " db.query" ,
2525 },
26- () => {
27- // Get active span to set attributes as data becomes available
28- const span = Sentry .getActiveSpan ();
29-
26+ (span ) => {
3027 // Execute query and add results to span
31- const result = executeQuery (' SELECT * FROM users WHERE active = true' );
32-
28+ const result = executeQuery (" SELECT * FROM users WHERE active = true" );
29+
3330 // Set attributes with the results data
34- if (span) {
35- span .setAttribute (' db.rows_returned' , result .length );
36- span .setAttribute (' db.execution_time_ms' , result .executionTime );
37- }
38-
31+ span .setAttribute (" db.rows_returned" , result .length );
32+ span .setAttribute (" db.execution_time_ms" , result .executionTime );
33+
3934 return result;
4035 }
4136);
@@ -55,14 +50,14 @@ By integrating these attributes into tracing, you can maintain a single telemetr
5550// Adding business context to a payment processing span
5651Sentry .startSpan (
5752 {
58- name: ' Process Payment' ,
59- op: ' payment.process' ,
53+ name: " Process Payment" ,
54+ op: " payment.process" ,
6055 attributes: {
61- ' payment.amount' : 99.99 ,
62- ' payment.currency' : ' USD' ,
63- ' payment.method' : ' credit_card' ,
64- ' customer.type' : ' returning'
65- }
56+ " payment.amount" : 99.99 ,
57+ " payment.currency" : " USD" ,
58+ " payment.method" : " credit_card" ,
59+ " customer.type" : " returning" ,
60+ },
6661 },
6762 async () => {
6863 // Payment processing implementation
@@ -91,12 +86,12 @@ Augment automatically-created or manually-defined spans with additional attribut
9186const span = Sentry .getActiveSpan ();
9287if (span) {
9388 // User context
94- span .setAttribute (' user.subscription_tier' , ' premium' );
95-
89+ span .setAttribute (" user.subscription_tier" , " premium" );
90+
9691 // Multiple metrics in a single operation
9792 span .setAttributes ({
98- ' memory.heap_used' : 1024000 ,
99- ' processing.total_steps' : 5
93+ " memory.heap_used" : 1024000 ,
94+ " processing.total_steps" : 5 ,
10095 });
10196}
10297```
@@ -109,16 +104,16 @@ Create spans specifically for grouping related attributes or metrics, particular
109104// Creating a span for monitoring external API usage
110105Sentry .startSpan (
111106 {
112- name: ' Third-Party API Usage' ,
113- op: ' external.api' ,
107+ name: " Third-Party API Usage" ,
108+ op: " external.api" ,
114109 attributes: {
115110 // Performance metrics
116- ' api.response_time_ms' : 245 ,
117-
111+ " api.response_time_ms" : 245 ,
112+
118113 // Context data
119- ' feature.using_api' : ' image_recognition' ,
120- ' user.plan' : ' enterprise'
121- }
114+ " feature.using_api" : " image_recognition" ,
115+ " user.plan" : " enterprise" ,
116+ },
122117 },
123118 async () => {
124119 // API call implementation
@@ -138,15 +133,15 @@ Monitor client-side performance metrics related to user experience:
138133// UI performance monitoring
139134Sentry .startSpan (
140135 {
141- name: ' Page Interaction' ,
142- op: ' ui.interaction' ,
136+ name: " Page Interaction" ,
137+ op: " ui.interaction" ,
143138 attributes: {
144- ' ui.first_input_delay_ms' : 24 ,
145- ' ui.time_to_interactive_ms' : 320 ,
146- ' ui.frames_dropped' : 0 ,
147- ' user.device_type' : ' mobile' ,
148- ' feature.being_used' : ' image_carousel'
149- }
139+ " ui.first_input_delay_ms" : 24 ,
140+ " ui.time_to_interactive_ms" : 320 ,
141+ " ui.frames_dropped" : 0 ,
142+ " user.device_type" : " mobile" ,
143+ " feature.being_used" : " image_carousel" ,
144+ },
150145 },
151146 async () => {
152147 // UI interaction handling
@@ -162,17 +157,17 @@ Track database performance characteristics and their impact on application behav
162157// Database query monitoring
163158Sentry .startSpan (
164159 {
165- name: ' Product Search Query' ,
166- op: ' db.query' ,
160+ name: " Product Search Query" ,
161+ op: " db.query" ,
167162 attributes: {
168- ' db.query_type' : ' SELECT' ,
169- ' db.table' : ' products' ,
170- ' db.execution_time_ms' : 145 ,
171- ' db.rows_returned' : 87 ,
172- ' db.index_used' : ' product_category_idx' ,
173- ' business.search_term' : ' winter jacket' ,
174- ' business.search_filters_applied' : 3
175- }
163+ " db.query_type" : " SELECT" ,
164+ " db.table" : " products" ,
165+ " db.execution_time_ms" : 145 ,
166+ " db.rows_returned" : 87 ,
167+ " db.index_used" : " product_category_idx" ,
168+ " business.search_term" : " winter jacket" ,
169+ " business.search_filters_applied" : 3 ,
170+ },
176171 },
177172 async () => {
178173 // Database query execution
@@ -188,21 +183,21 @@ Monitor file handling operations across your application stack:
188183// File processing monitoring
189184Sentry .startSpan (
190185 {
191- name: ' Process Uploaded Image' ,
192- op: ' file.process' ,
186+ name: " Process Uploaded Image" ,
187+ op: " file.process" ,
193188 attributes: {
194189 // Technical metrics
195- ' file.size_bytes' : 2500000 ,
196- ' file.type' : ' image/jpeg' ,
197-
190+ " file.size_bytes" : 2500000 ,
191+ " file.type" : " image/jpeg" ,
192+
198193 // Processing metrics
199- ' processing.steps_completed' : [' virus_scan' , ' resize' , ' compress' ],
200- ' processing.total_time_ms' : 850 ,
201-
194+ " processing.steps_completed" : [" virus_scan" , " resize" , " compress" ],
195+ " processing.total_time_ms" : 850 ,
196+
202197 // Context data
203- ' feature.using_upload' : ' user_avatar' ,
204- ' subscription.allows_hd' : true
205- }
198+ " feature.using_upload" : " user_avatar" ,
199+ " subscription.allows_hd" : true ,
200+ },
206201 },
207202 async () => {
208203 // Image processing implementation
@@ -218,21 +213,21 @@ Monitor performance and reliability of third-party service interactions:
218213// Payment gateway monitoring
219214Sentry .startSpan (
220215 {
221- name: ' Payment Gateway' ,
222- op: ' payment.gateway' ,
216+ name: " Payment Gateway" ,
217+ op: " payment.gateway" ,
223218 attributes: {
224219 // Performance metrics
225- ' gateway.response_time_ms' : 980 ,
226- ' gateway.retry_count' : 0 ,
227-
220+ " gateway.response_time_ms" : 980 ,
221+ " gateway.retry_count" : 0 ,
222+
228223 // Transaction data
229- ' order.total_amount' : 159.99 ,
230- ' order.items_count' : 3 ,
231-
224+ " order.total_amount" : 159.99 ,
225+ " order.items_count" : 3 ,
226+
232227 // Service metrics
233- ' gateway.fee_amount' : 4.50 ,
234- ' gateway.fee_percent' : 0.029
235- }
228+ " gateway.fee_amount" : 4.5 ,
229+ " gateway.fee_percent" : 0.029 ,
230+ },
236231 },
237232 async () => {
238233 // Payment gateway integration
@@ -255,6 +250,7 @@ Maintain consistent naming patterns following the format `category.metric_name`
255250#### Data Type Selection
256251
257252Choose appropriate data types for your metrics:
253+
258254- Numeric values for measurements (` response_time_ms ` : 250)
259255- Boolean values for state indicators (` cache.hit ` : true)
260256- String values for categorical data (` user.subscription ` : 'premium')
@@ -263,6 +259,7 @@ Choose appropriate data types for your metrics:
263259#### Performance Considerations
264260
265261Be mindful of the performance impact of collecting metrics, especially for high-volume operations:
262+
266263- Consider implementing sampling for high-frequency operations
267264- Prioritize metrics with the highest analytical value
268265- Avoid redundant or closely correlated metrics
@@ -276,6 +273,7 @@ If you're currently using Sentry's standalone Metrics product, migrating to span
276273- ** Improved correlation** : Direct association between attributes, traces, and errors
277274
278275Migration process:
276+
2792771 . Identify your current metric instrumentation points
2802782 . Locate corresponding spans in your application
2812793 . Transfer your metrics to span attributes
0 commit comments