1- import type { Event , IntegrationFn } from '@sentry/core' ;
1+ import type { IntegrationFn } from '@sentry/core' ;
22import { defineIntegration , safeSetSpanJSONAttributes } from '@sentry/core' ;
33
44const INTEGRATION_NAME = 'DenoContext' ;
@@ -22,42 +22,38 @@ async function getOSRelease(): Promise<string | undefined> {
2222 : undefined ;
2323}
2424
25- async function addDenoRuntimeContext ( event : Event ) : Promise < Event > {
26- event . contexts = {
27- ...{
28- app : {
29- app_start_time : new Date ( Date . now ( ) - performance . now ( ) ) . toISOString ( ) ,
30- } ,
31- device : {
32- arch : Deno . build . arch ,
33- // eslint-disable-next-line no-restricted-globals
34- processor_count : navigator . hardwareConcurrency ,
35- } ,
36- os : {
37- name : getOSName ( ) ,
38- version : await getOSRelease ( ) ,
39- } ,
40- v8 : {
41- name : 'v8' ,
42- version : Deno . version . v8 ,
43- } ,
44- typescript : {
45- name : 'TypeScript' ,
46- version : Deno . version . typescript ,
47- } ,
48- } ,
49- ...event . contexts ,
25+ const _denoContextIntegration = ( ( ) => {
26+ const appStartTime = new Date ( Date . now ( ) - performance . now ( ) ) . toISOString ( ) ;
27+ const osName = getOSName ( ) ;
28+ const arch = Deno . build . arch ;
29+ // eslint-disable-next-line no-restricted-globals
30+ const processorCount = navigator . hardwareConcurrency ;
31+ const v8Version = Deno . version . v8 ;
32+ const tsVersion = Deno . version . typescript ;
33+
34+ const cachedContext = {
35+ app : { app_start_time : appStartTime } ,
36+ device : { arch, processor_count : processorCount } ,
37+ os : { name : osName } as { name : string ; version ?: string } ,
38+ v8 : { name : 'v8' , version : v8Version } ,
39+ typescript : { name : 'TypeScript' , version : tsVersion } ,
5040 } ;
5141
52- return event ;
53- }
42+ const cachedSpanAttributes : Record < string , unknown > = {
43+ 'app.start_time' : appStartTime ,
44+ // Convention uses 'device.archs' (string[]), but array attributes are not yet serialized.
45+ // Once array serialization lands, this will start appearing on spans automatically.
46+ 'device.archs' : [ arch ] ,
47+ 'device.processor_count' : processorCount ,
48+ 'os.name' : osName ,
49+ 'process.runtime.engine.name' : 'v8' ,
50+ 'process.runtime.engine.version' : v8Version ,
51+ } ;
5452
55- const _denoContextIntegration = ( ( ) => {
56- // Eagerly resolve the async OS release so it's available synchronously in processSegmentSpan
57- let cachedOsRelease : string | undefined ;
5853 getOSRelease ( )
5954 . then ( release => {
60- cachedOsRelease = release ;
55+ cachedContext . os . version = release ;
56+ cachedSpanAttributes [ 'os.version' ] = release ;
6157 } )
6258 . catch ( ( ) => {
6359 // Ignore - os.version will be undefined
@@ -66,19 +62,14 @@ const _denoContextIntegration = (() => {
6662 return {
6763 name : INTEGRATION_NAME ,
6864 processEvent ( event ) {
69- return addDenoRuntimeContext ( event ) ;
65+ event . contexts = {
66+ ...cachedContext ,
67+ ...event . contexts ,
68+ } ;
69+ return event ;
7070 } ,
7171 processSegmentSpan ( span ) {
72- safeSetSpanJSONAttributes ( span , {
73- 'app.start_time' : new Date ( Date . now ( ) - performance . now ( ) ) . toISOString ( ) ,
74- 'device.archs' : [ Deno . build . arch ] ,
75- // eslint-disable-next-line no-restricted-globals
76- 'device.processor_count' : navigator . hardwareConcurrency ,
77- 'os.name' : getOSName ( ) ,
78- 'os.version' : cachedOsRelease ,
79- 'process.runtime.engine.name' : 'v8' ,
80- 'process.runtime.engine.version' : Deno . version . v8 ,
81- } ) ;
72+ safeSetSpanJSONAttributes ( span , cachedSpanAttributes ) ;
8273 } ,
8374 } ;
8475} ) satisfies IntegrationFn ;
0 commit comments