-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
/
envelope.ts
114 lines (101 loc) · 3.61 KB
/
envelope.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import {
DsnComponents,
Event,
EventEnvelope,
EventEnvelopeHeaders,
EventItem,
SdkInfo,
SdkMetadata,
Session,
SessionAggregates,
SessionEnvelope,
SessionItem,
} from '@sentry/types';
import { createEnvelope, dropUndefinedKeys, dsnToString } from '@sentry/utils';
/** Extract sdk info from from the API metadata */
function getSdkMetadataForEnvelopeHeader(metadata?: SdkMetadata): SdkInfo | undefined {
if (!metadata || !metadata.sdk) {
return;
}
const { name, version } = metadata.sdk;
return { name, version };
}
/**
* Apply SdkInfo (name, version, packages, integrations) to the corresponding event key.
* Merge with existing data if any.
**/
function enhanceEventWithSdkInfo(event: Event, sdkInfo?: SdkInfo): Event {
if (!sdkInfo) {
return event;
}
event.sdk = event.sdk || {};
event.sdk.name = event.sdk.name || sdkInfo.name;
event.sdk.version = event.sdk.version || sdkInfo.version;
event.sdk.integrations = [...(event.sdk.integrations || []), ...(sdkInfo.integrations || [])];
event.sdk.packages = [...(event.sdk.packages || []), ...(sdkInfo.packages || [])];
return event;
}
/** Creates an envelope from a Session */
export function createSessionEnvelope(
session: Session | SessionAggregates,
dsn: DsnComponents,
metadata?: SdkMetadata,
tunnel?: string,
): SessionEnvelope {
const sdkInfo = getSdkMetadataForEnvelopeHeader(metadata);
const envelopeHeaders = {
sent_at: new Date().toISOString(),
...(sdkInfo && { sdk: sdkInfo }),
...(!!tunnel && { dsn: dsnToString(dsn) }),
};
const envelopeItem: SessionItem =
'aggregates' in session ? [{ type: 'sessions' }, session] : [{ type: 'session' }, session];
return createEnvelope<SessionEnvelope>(envelopeHeaders, [envelopeItem]);
}
/**
* Create an Envelope from an event.
*/
export function createEventEnvelope(
event: Event,
dsn: DsnComponents,
metadata?: SdkMetadata,
tunnel?: string,
): EventEnvelope {
const sdkInfo = getSdkMetadataForEnvelopeHeader(metadata);
const eventType = event.type || 'event';
const { transactionSampling } = event.sdkProcessingMetadata || {};
const { method: samplingMethod, rate: sampleRate } = transactionSampling || {};
enhanceEventWithSdkInfo(event, metadata && metadata.sdk);
const envelopeHeaders = createEventEnvelopeHeaders(event, sdkInfo, tunnel, dsn);
// Prevent this data (which, if it exists, was used in earlier steps in the processing pipeline) from being sent to
// sentry. (Note: Our use of this property comes and goes with whatever we might be debugging, whatever hacks we may
// have temporarily added, etc. Even if we don't happen to be using it at some point in the future, let's not get rid
// of this `delete`, lest we miss putting it back in the next time the property is in use.)
delete event.sdkProcessingMetadata;
const eventItem: EventItem = [
{
type: eventType,
sample_rates: [{ id: samplingMethod, rate: sampleRate }],
},
event,
];
return createEnvelope<EventEnvelope>(envelopeHeaders, [eventItem]);
}
function createEventEnvelopeHeaders(
event: Event,
sdkInfo: SdkInfo | undefined,
tunnel: string | undefined,
dsn: DsnComponents,
): EventEnvelopeHeaders {
const dynamicSamplingContext = event.sdkProcessingMetadata && event.sdkProcessingMetadata.dynamicSamplingContext;
return {
event_id: event.event_id as string,
sent_at: new Date().toISOString(),
...(sdkInfo && { sdk: sdkInfo }),
...(!!tunnel && { dsn: dsnToString(dsn) }),
...(event.type === 'transaction' &&
dynamicSamplingContext && {
trace: dropUndefinedKeys({ ...dynamicSamplingContext }),
}),
};
}