@sentry/effect 10.53.1 → 10.54.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/client/index.js +0 -29
- package/build/cjs/client/index.js.map +1 -1
- package/build/cjs/client/sdk.js +2 -10
- package/build/cjs/client/sdk.js.map +1 -1
- package/build/cjs/logger.js +14 -23
- package/build/cjs/logger.js.map +1 -1
- package/build/cjs/metrics.js +29 -69
- package/build/cjs/metrics.js.map +1 -1
- package/build/cjs/server/index.js +0 -29
- package/build/cjs/server/index.js.map +1 -1
- package/build/cjs/server/sdk.js +2 -10
- package/build/cjs/server/sdk.js.map +1 -1
- package/build/cjs/tracer.js +51 -115
- package/build/cjs/tracer.js.map +1 -1
- package/build/esm/client/index.js +0 -29
- package/build/esm/client/index.js.map +1 -1
- package/build/esm/client/sdk.js +2 -10
- package/build/esm/client/sdk.js.map +1 -1
- package/build/esm/logger.js +14 -23
- package/build/esm/logger.js.map +1 -1
- package/build/esm/metrics.js +29 -69
- package/build/esm/metrics.js.map +1 -1
- package/build/esm/package.json +1 -1
- package/build/esm/server/index.js +0 -29
- package/build/esm/server/index.js.map +1 -1
- package/build/esm/server/sdk.js +2 -10
- package/build/esm/server/sdk.js.map +1 -1
- package/build/esm/tracer.js +51 -115
- package/build/esm/tracer.js.map +1 -1
- package/package.json +4 -4
package/build/esm/metrics.js
CHANGED
|
@@ -5,164 +5,124 @@ import * as Layer from 'effect/Layer';
|
|
|
5
5
|
import * as Metric from 'effect/Metric';
|
|
6
6
|
import * as Schedule from 'effect/Schedule';
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
const V3_GAUGE_STATE_TYPE_ID = Symbol.for('effect/MetricState/Gauge');
|
|
14
|
-
const V3_HISTOGRAM_STATE_TYPE_ID = Symbol.for('effect/MetricState/Histogram');
|
|
15
|
-
const V3_SUMMARY_STATE_TYPE_ID = Symbol.for('effect/MetricState/Summary');
|
|
16
|
-
const V3_FREQUENCY_STATE_TYPE_ID = Symbol.for('effect/MetricState/Frequency');
|
|
17
|
-
|
|
8
|
+
const V3_COUNTER_STATE_TYPE_ID = /* @__PURE__ */ Symbol.for("effect/MetricState/Counter");
|
|
9
|
+
const V3_GAUGE_STATE_TYPE_ID = /* @__PURE__ */ Symbol.for("effect/MetricState/Gauge");
|
|
10
|
+
const V3_HISTOGRAM_STATE_TYPE_ID = /* @__PURE__ */ Symbol.for("effect/MetricState/Histogram");
|
|
11
|
+
const V3_SUMMARY_STATE_TYPE_ID = /* @__PURE__ */ Symbol.for("effect/MetricState/Summary");
|
|
12
|
+
const V3_FREQUENCY_STATE_TYPE_ID = /* @__PURE__ */ Symbol.for("effect/MetricState/Frequency");
|
|
18
13
|
function labelsToAttributes(labels) {
|
|
19
14
|
return labels.reduce((acc, label) => ({ ...acc, [label.key]: label.value }), {});
|
|
20
15
|
}
|
|
21
|
-
|
|
22
16
|
function getMetricIdV3(pair) {
|
|
23
|
-
const tags = pair.metricKey.tags.map(t => `${t.key}=${t.value}`).join(
|
|
17
|
+
const tags = pair.metricKey.tags.map((t) => `${t.key}=${t.value}`).join(",");
|
|
24
18
|
return `${pair.metricKey.name}:${tags}`;
|
|
25
19
|
}
|
|
26
|
-
|
|
27
20
|
function getMetricIdV4(snapshot) {
|
|
28
|
-
const attrs = snapshot.attributes
|
|
29
|
-
? Object.entries(snapshot.attributes)
|
|
30
|
-
.map(([k, v]) => `${k}=${v}`)
|
|
31
|
-
.join(',')
|
|
32
|
-
: '';
|
|
21
|
+
const attrs = snapshot.attributes ? Object.entries(snapshot.attributes).map(([k, v]) => `${k}=${v}`).join(",") : "";
|
|
33
22
|
return `${snapshot.id}:${attrs}`;
|
|
34
23
|
}
|
|
35
|
-
|
|
36
24
|
function sendV3MetricToSentry(pair, previousCounterValues) {
|
|
37
25
|
const { metricKey, metricState } = pair;
|
|
38
26
|
const name = metricKey.name;
|
|
39
27
|
const attributes = labelsToAttributes(metricKey.tags);
|
|
40
28
|
const metricId = getMetricIdV3(pair);
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
if (state[V3_COUNTER_STATE_TYPE_ID] !== undefined) {
|
|
29
|
+
const state = metricState;
|
|
30
|
+
if (state[V3_COUNTER_STATE_TYPE_ID] !== void 0) {
|
|
45
31
|
const currentValue = Number(metricState.count);
|
|
46
32
|
const previousValue = previousCounterValues.get(metricId) ?? 0;
|
|
47
33
|
const delta = currentValue - previousValue;
|
|
48
|
-
|
|
49
34
|
if (delta > 0) {
|
|
50
35
|
metrics.count(name, delta, { attributes });
|
|
51
36
|
}
|
|
52
|
-
|
|
53
37
|
previousCounterValues.set(metricId, currentValue);
|
|
54
|
-
} else if (state[V3_GAUGE_STATE_TYPE_ID] !==
|
|
38
|
+
} else if (state[V3_GAUGE_STATE_TYPE_ID] !== void 0) {
|
|
55
39
|
const value = Number(metricState.value);
|
|
56
40
|
metrics.gauge(name, value, { attributes });
|
|
57
|
-
} else if (state[V3_HISTOGRAM_STATE_TYPE_ID] !==
|
|
41
|
+
} else if (state[V3_HISTOGRAM_STATE_TYPE_ID] !== void 0 || state[V3_SUMMARY_STATE_TYPE_ID] !== void 0) {
|
|
58
42
|
metrics.gauge(`${name}.sum`, metricState.sum ?? 0, { attributes });
|
|
59
43
|
metrics.gauge(`${name}.count`, Number(metricState.count ?? 0), { attributes });
|
|
60
44
|
metrics.gauge(`${name}.min`, metricState.min ?? 0, { attributes });
|
|
61
45
|
metrics.gauge(`${name}.max`, metricState.max ?? 0, { attributes });
|
|
62
|
-
} else if (state[V3_FREQUENCY_STATE_TYPE_ID] !==
|
|
46
|
+
} else if (state[V3_FREQUENCY_STATE_TYPE_ID] !== void 0 && metricState.occurrences) {
|
|
63
47
|
for (const [word, count] of metricState.occurrences) {
|
|
64
48
|
metrics.count(name, count, {
|
|
65
|
-
attributes: { ...attributes, word }
|
|
49
|
+
attributes: { ...attributes, word }
|
|
66
50
|
});
|
|
67
51
|
}
|
|
68
52
|
}
|
|
69
53
|
}
|
|
70
|
-
|
|
71
54
|
function sendV4MetricToSentry(snapshot, previousCounterValues) {
|
|
72
55
|
const name = snapshot.id;
|
|
73
56
|
const attributes = snapshot.attributes ? { ...snapshot.attributes } : {};
|
|
74
57
|
const metricId = getMetricIdV4(snapshot);
|
|
75
|
-
|
|
76
58
|
switch (snapshot.type) {
|
|
77
|
-
case
|
|
59
|
+
case "Counter": {
|
|
78
60
|
const currentValue = Number(snapshot.state.count);
|
|
79
61
|
const previousValue = previousCounterValues.get(metricId) ?? 0;
|
|
80
62
|
const delta = currentValue - previousValue;
|
|
81
|
-
|
|
82
63
|
if (delta > 0) {
|
|
83
64
|
metrics.count(name, delta, { attributes });
|
|
84
65
|
}
|
|
85
|
-
|
|
86
66
|
previousCounterValues.set(metricId, currentValue);
|
|
87
67
|
break;
|
|
88
68
|
}
|
|
89
|
-
case
|
|
69
|
+
case "Gauge": {
|
|
90
70
|
const value = Number(snapshot.state.value);
|
|
91
71
|
metrics.gauge(name, value, { attributes });
|
|
92
72
|
break;
|
|
93
73
|
}
|
|
94
|
-
case
|
|
95
|
-
case
|
|
74
|
+
case "Histogram":
|
|
75
|
+
case "Summary": {
|
|
96
76
|
metrics.gauge(`${name}.sum`, snapshot.state.sum ?? 0, { attributes });
|
|
97
77
|
metrics.gauge(`${name}.count`, snapshot.state.count ?? 0, { attributes });
|
|
98
78
|
metrics.gauge(`${name}.min`, snapshot.state.min ?? 0, { attributes });
|
|
99
79
|
metrics.gauge(`${name}.max`, snapshot.state.max ?? 0, { attributes });
|
|
100
80
|
break;
|
|
101
81
|
}
|
|
102
|
-
case
|
|
82
|
+
case "Frequency": {
|
|
103
83
|
for (const [word, count] of snapshot.state.occurrences) {
|
|
104
84
|
metrics.count(name, count, {
|
|
105
|
-
attributes: { ...attributes, word }
|
|
85
|
+
attributes: { ...attributes, word }
|
|
106
86
|
});
|
|
107
87
|
}
|
|
108
88
|
break;
|
|
109
89
|
}
|
|
110
90
|
}
|
|
111
91
|
}
|
|
112
|
-
|
|
113
|
-
// =============================================================================
|
|
114
|
-
// Effect v3 snapshot function type (vendored - not exported from effect@3.x)
|
|
115
|
-
// =============================================================================
|
|
116
|
-
|
|
117
|
-
// Use bracket notation to avoid Webpack static analysis flagging missing exports
|
|
118
|
-
// This is important for Effect v3 compatibility.
|
|
119
92
|
const MetricModule = Metric;
|
|
120
|
-
const snapshotUnsafe = MetricModule[
|
|
121
|
-
|
|
122
|
-
const unsafeSnapshot = MetricModule['unsafeSnapshot'] ;
|
|
123
|
-
|
|
93
|
+
const snapshotUnsafe = MetricModule["snapshotUnsafe"];
|
|
94
|
+
const unsafeSnapshot = MetricModule["unsafeSnapshot"];
|
|
124
95
|
function flushMetricsToSentry(previousCounterValues) {
|
|
125
96
|
if (snapshotUnsafe) {
|
|
126
|
-
// Effect v4
|
|
127
97
|
const snapshots = snapshotUnsafe(Context.empty());
|
|
128
98
|
for (const snapshot of snapshots) {
|
|
129
99
|
sendV4MetricToSentry(snapshot, previousCounterValues);
|
|
130
100
|
}
|
|
131
101
|
} else if (unsafeSnapshot) {
|
|
132
|
-
// Effect v3
|
|
133
102
|
const snapshots = unsafeSnapshot();
|
|
134
103
|
for (const pair of snapshots) {
|
|
135
104
|
sendV3MetricToSentry(pair, previousCounterValues);
|
|
136
105
|
}
|
|
137
106
|
}
|
|
138
107
|
}
|
|
139
|
-
|
|
140
108
|
function createMetricsReporterEffect(previousCounterValues) {
|
|
141
|
-
const schedule = Schedule.spaced(
|
|
142
|
-
|
|
109
|
+
const schedule = Schedule.spaced("10 seconds");
|
|
143
110
|
return Effect.repeat(
|
|
144
111
|
Effect.sync(() => flushMetricsToSentry(previousCounterValues)),
|
|
145
|
-
schedule
|
|
112
|
+
schedule
|
|
146
113
|
).pipe(Effect.asVoid, Effect.interruptible);
|
|
147
114
|
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Effect Layer that periodically flushes metrics to Sentry.
|
|
151
|
-
* The layer manages its own state for delta counter calculations,
|
|
152
|
-
* which is automatically cleaned up when the layer is finalized.
|
|
153
|
-
*/
|
|
154
115
|
const SentryEffectMetricsLayer = Layer.effectDiscard(
|
|
155
116
|
Effect.gen(function* () {
|
|
156
|
-
const previousCounterValues = new Map();
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
Effect.sync(() => {
|
|
117
|
+
const previousCounterValues = /* @__PURE__ */ new Map();
|
|
118
|
+
yield* Effect.acquireRelease(
|
|
119
|
+
Effect.void,
|
|
120
|
+
() => Effect.sync(() => {
|
|
160
121
|
previousCounterValues.clear();
|
|
161
|
-
})
|
|
122
|
+
})
|
|
162
123
|
);
|
|
163
|
-
|
|
164
124
|
yield* Effect.forkScoped(createMetricsReporterEffect(previousCounterValues));
|
|
165
|
-
})
|
|
125
|
+
})
|
|
166
126
|
);
|
|
167
127
|
|
|
168
128
|
export { SentryEffectMetricsLayer };
|
package/build/esm/metrics.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics.js","sources":["../../src/metrics.ts"],"sourcesContent":["import { metrics as sentryMetrics } from '@sentry/core';\nimport * as Context from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Metric from 'effect/Metric';\nimport * as Schedule from 'effect/Schedule';\n\ntype MetricAttributes = Record<string, string>;\n\n// =============================================================================\n// Effect v3 Types (vendored - not exported from effect@3.x)\n// =============================================================================\n\ninterface V3MetricLabel {\n key: string;\n value: string;\n}\n\ninterface V3MetricPair {\n metricKey: {\n name: string;\n tags: ReadonlyArray<V3MetricLabel>;\n keyType: { _tag: string };\n };\n metricState: {\n count?: number | bigint;\n value?: number;\n sum?: number;\n min?: number;\n max?: number;\n occurrences?: Map<string, number>;\n };\n}\n\n// Effect v3 `MetricState` implementations brand themselves with a `Symbol.for(...)` TypeId\n// rather than a string `_tag`. We use these globally-registered symbols to classify state\n// instances returned by `Metric.unsafeSnapshot()` without importing `effect/MetricState`\n// (the module does not exist in Effect v4).\nconst V3_COUNTER_STATE_TYPE_ID = Symbol.for('effect/MetricState/Counter');\nconst V3_GAUGE_STATE_TYPE_ID = Symbol.for('effect/MetricState/Gauge');\nconst V3_HISTOGRAM_STATE_TYPE_ID = Symbol.for('effect/MetricState/Histogram');\nconst V3_SUMMARY_STATE_TYPE_ID = Symbol.for('effect/MetricState/Summary');\nconst V3_FREQUENCY_STATE_TYPE_ID = Symbol.for('effect/MetricState/Frequency');\n\nfunction labelsToAttributes(labels: ReadonlyArray<V3MetricLabel>): MetricAttributes {\n return labels.reduce((acc, label) => ({ ...acc, [label.key]: label.value }), {});\n}\n\nfunction getMetricIdV3(pair: V3MetricPair): string {\n const tags = pair.metricKey.tags.map(t => `${t.key}=${t.value}`).join(',');\n return `${pair.metricKey.name}:${tags}`;\n}\n\nfunction getMetricIdV4(snapshot: Metric.Metric.Snapshot): string {\n const attrs = snapshot.attributes\n ? Object.entries(snapshot.attributes)\n .map(([k, v]) => `${k}=${v}`)\n .join(',')\n : '';\n return `${snapshot.id}:${attrs}`;\n}\n\nfunction sendV3MetricToSentry(pair: V3MetricPair, previousCounterValues: Map<string, number>): void {\n const { metricKey, metricState } = pair;\n const name = metricKey.name;\n const attributes = labelsToAttributes(metricKey.tags);\n const metricId = getMetricIdV3(pair);\n\n const state = metricState as unknown as Record<symbol, unknown>;\n\n if (state[V3_COUNTER_STATE_TYPE_ID] !== undefined) {\n const currentValue = Number(metricState.count);\n const previousValue = previousCounterValues.get(metricId) ?? 0;\n const delta = currentValue - previousValue;\n\n if (delta > 0) {\n sentryMetrics.count(name, delta, { attributes });\n }\n\n previousCounterValues.set(metricId, currentValue);\n } else if (state[V3_GAUGE_STATE_TYPE_ID] !== undefined) {\n const value = Number(metricState.value);\n sentryMetrics.gauge(name, value, { attributes });\n } else if (state[V3_HISTOGRAM_STATE_TYPE_ID] !== undefined || state[V3_SUMMARY_STATE_TYPE_ID] !== undefined) {\n sentryMetrics.gauge(`${name}.sum`, metricState.sum ?? 0, { attributes });\n sentryMetrics.gauge(`${name}.count`, Number(metricState.count ?? 0), { attributes });\n sentryMetrics.gauge(`${name}.min`, metricState.min ?? 0, { attributes });\n sentryMetrics.gauge(`${name}.max`, metricState.max ?? 0, { attributes });\n } else if (state[V3_FREQUENCY_STATE_TYPE_ID] !== undefined && metricState.occurrences) {\n for (const [word, count] of metricState.occurrences) {\n sentryMetrics.count(name, count, {\n attributes: { ...attributes, word },\n });\n }\n }\n}\n\nfunction sendV4MetricToSentry(snapshot: Metric.Metric.Snapshot, previousCounterValues: Map<string, number>): void {\n const name = snapshot.id;\n const attributes: MetricAttributes = snapshot.attributes ? { ...snapshot.attributes } : {};\n const metricId = getMetricIdV4(snapshot);\n\n switch (snapshot.type) {\n case 'Counter': {\n const currentValue = Number(snapshot.state.count);\n const previousValue = previousCounterValues.get(metricId) ?? 0;\n const delta = currentValue - previousValue;\n\n if (delta > 0) {\n sentryMetrics.count(name, delta, { attributes });\n }\n\n previousCounterValues.set(metricId, currentValue);\n break;\n }\n case 'Gauge': {\n const value = Number(snapshot.state.value);\n sentryMetrics.gauge(name, value, { attributes });\n break;\n }\n case 'Histogram':\n case 'Summary': {\n sentryMetrics.gauge(`${name}.sum`, snapshot.state.sum ?? 0, { attributes });\n sentryMetrics.gauge(`${name}.count`, snapshot.state.count ?? 0, { attributes });\n sentryMetrics.gauge(`${name}.min`, snapshot.state.min ?? 0, { attributes });\n sentryMetrics.gauge(`${name}.max`, snapshot.state.max ?? 0, { attributes });\n break;\n }\n case 'Frequency': {\n for (const [word, count] of snapshot.state.occurrences) {\n sentryMetrics.count(name, count, {\n attributes: { ...attributes, word },\n });\n }\n break;\n }\n }\n}\n\n// =============================================================================\n// Effect v3 snapshot function type (vendored - not exported from effect@3.x)\n// =============================================================================\n\ntype V3UnsafeSnapshotFn = () => ReadonlyArray<V3MetricPair>;\n\n// Use bracket notation to avoid Webpack static analysis flagging missing exports\n// This is important for Effect v3 compatibility.\nconst MetricModule = Metric;\nconst snapshotUnsafe = MetricModule['snapshotUnsafe'] as typeof Metric.snapshotUnsafe | undefined;\n// @ts-expect-error - unsafeSnapshot is not exported from effect@3.x\nconst unsafeSnapshot = MetricModule['unsafeSnapshot'] as V3UnsafeSnapshotFn | undefined;\n\nfunction flushMetricsToSentry(previousCounterValues: Map<string, number>): void {\n if (snapshotUnsafe) {\n // Effect v4\n const snapshots = snapshotUnsafe(Context.empty());\n for (const snapshot of snapshots) {\n sendV4MetricToSentry(snapshot, previousCounterValues);\n }\n } else if (unsafeSnapshot) {\n // Effect v3\n const snapshots = unsafeSnapshot();\n for (const pair of snapshots) {\n sendV3MetricToSentry(pair, previousCounterValues);\n }\n }\n}\n\nfunction createMetricsReporterEffect(previousCounterValues: Map<string, number>): Effect.Effect<void, never, never> {\n const schedule = Schedule.spaced('10 seconds');\n\n return Effect.repeat(\n Effect.sync(() => flushMetricsToSentry(previousCounterValues)),\n schedule,\n ).pipe(Effect.asVoid, Effect.interruptible);\n}\n\n/**\n * Effect Layer that periodically flushes metrics to Sentry.\n * The layer manages its own state for delta counter calculations,\n * which is automatically cleaned up when the layer is finalized.\n */\nexport const SentryEffectMetricsLayer: Layer.Layer<never, never, never> = Layer.effectDiscard(\n Effect.gen(function* () {\n const previousCounterValues = new Map<string, number>();\n\n yield* Effect.acquireRelease(Effect.void, () =>\n Effect.sync(() => {\n previousCounterValues.clear();\n }),\n );\n\n yield* Effect.forkScoped(createMetricsReporterEffect(previousCounterValues));\n }),\n);\n"],"names":["sentryMetrics"],"mappings":";;;;;;;AAkCA;AACA;AACA;AACA;AACA,MAAM,2BAA2B,MAAM,CAAC,GAAG,CAAC,4BAA4B,CAAC;AACzE,MAAM,yBAAyB,MAAM,CAAC,GAAG,CAAC,0BAA0B,CAAC;AACrE,MAAM,6BAA6B,MAAM,CAAC,GAAG,CAAC,8BAA8B,CAAC;AAC7E,MAAM,2BAA2B,MAAM,CAAC,GAAG,CAAC,4BAA4B,CAAC;AACzE,MAAM,6BAA6B,MAAM,CAAC,GAAG,CAAC,8BAA8B,CAAC;;AAE7E,SAAS,kBAAkB,CAAC,MAAM,EAAkD;AACpF,EAAE,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,MAAM,EAAE,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,KAAA,EAAO,CAAC,EAAE,EAAE,CAAC;AAClF;;AAEA,SAAS,aAAa,CAAC,IAAI,EAAwB;AACnD,EAAE,MAAM,IAAA,GAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA,IAAK,CAAC,EAAA,CAAA,CAAA,GAAA,CAAA,CAAA,EAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAA,IAAA,CAAA,GAAA,CAAA;AACA,EAAA,OAAA,CAAA,EAAA,IAAA,CAAA,SAAA,CAAA,IAAA,CAAA,CAAA,EAAA,IAAA,CAAA,CAAA;AACA;;AAEA,SAAA,aAAA,CAAA,QAAA,EAAA;AACA,EAAA,MAAA,KAAA,GAAA,QAAA,CAAA;AACA,MAAA,MAAA,CAAA,OAAA,CAAA,QAAA,CAAA,UAAA;AACA,SAAA,GAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,KAAA,CAAA,EAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA;AACA,SAAA,IAAA,CAAA,GAAA;AACA,MAAA,EAAA;AACA,EAAA,OAAA,CAAA,EAAA,QAAA,CAAA,EAAA,CAAA,CAAA,EAAA,KAAA,CAAA,CAAA;AACA;;AAEA,SAAA,oBAAA,CAAA,IAAA,EAAA,qBAAA,EAAA;AACA,EAAA,MAAA,EAAA,SAAA,EAAA,WAAA,EAAA,GAAA,IAAA;AACA,EAAA,MAAA,IAAA,GAAA,SAAA,CAAA,IAAA;AACA,EAAA,MAAA,UAAA,GAAA,kBAAA,CAAA,SAAA,CAAA,IAAA,CAAA;AACA,EAAA,MAAA,QAAA,GAAA,aAAA,CAAA,IAAA,CAAA;;AAEA,EAAA,MAAA,KAAA,GAAA,WAAA;;AAEA,EAAA,IAAA,KAAA,CAAA,wBAAA,CAAA,KAAA,SAAA,EAAA;AACA,IAAA,MAAA,YAAA,GAAA,MAAA,CAAA,WAAA,CAAA,KAAA,CAAA;AACA,IAAA,MAAA,aAAA,GAAA,qBAAA,CAAA,GAAA,CAAA,QAAA,CAAA,IAAA,CAAA;AACA,IAAA,MAAA,KAAA,GAAA,YAAA,GAAA,aAAA;;AAEA,IAAA,IAAA,KAAA,GAAA,CAAA,EAAA;AACA,MAAAA,OAAA,CAAA,KAAA,CAAA,IAAA,EAAA,KAAA,EAAA,EAAA,UAAA,EAAA,CAAA;AACA,IAAA;;AAEA,IAAA,qBAAA,CAAA,GAAA,CAAA,QAAA,EAAA,YAAA,CAAA;AACA,EAAA,CAAA,MAAA,IAAA,KAAA,CAAA,sBAAA,CAAA,KAAA,SAAA,EAAA;AACA,IAAA,MAAA,KAAA,GAAA,MAAA,CAAA,WAAA,CAAA,KAAA,CAAA;AACA,IAAAA,OAAA,CAAA,KAAA,CAAA,IAAA,EAAA,KAAA,EAAA,EAAA,UAAA,EAAA,CAAA;AACA,EAAA,CAAA,MAAA,IAAA,KAAA,CAAA,0BAAA,CAAA,KAAA,SAAA,IAAA,KAAA,CAAA,wBAAA,CAAA,KAAA,SAAA,EAAA;AACA,IAAAA,OAAA,CAAA,KAAA,CAAA,CAAA,EAAA,IAAA,CAAA,IAAA,CAAA,EAAA,WAAA,CAAA,GAAA,IAAA,CAAA,EAAA,EAAA,UAAA,EAAA,CAAA;AACA,IAAAA,OAAA,CAAA,KAAA,CAAA,CAAA,EAAA,IAAA,CAAA,MAAA,CAAA,EAAA,MAAA,CAAA,WAAA,CAAA,KAAA,IAAA,CAAA,CAAA,EAAA,EAAA,UAAA,EAAA,CAAA;AACA,IAAAA,OAAA,CAAA,KAAA,CAAA,CAAA,EAAA,IAAA,CAAA,IAAA,CAAA,EAAA,WAAA,CAAA,GAAA,IAAA,CAAA,EAAA,EAAA,UAAA,EAAA,CAAA;AACA,IAAAA,OAAA,CAAA,KAAA,CAAA,CAAA,EAAA,IAAA,CAAA,IAAA,CAAA,EAAA,WAAA,CAAA,GAAA,IAAA,CAAA,EAAA,EAAA,UAAA,EAAA,CAAA;AACA,EAAA,CAAA,MAAA,IAAA,KAAA,CAAA,0BAAA,CAAA,KAAA,SAAA,IAAA,WAAA,CAAA,WAAA,EAAA;AACA,IAAA,KAAA,MAAA,CAAA,IAAA,EAAA,KAAA,CAAA,IAAA,WAAA,CAAA,WAAA,EAAA;AACA,MAAAA,OAAA,CAAA,KAAA,CAAA,IAAA,EAAA,KAAA,EAAA;AACA,QAAA,UAAA,EAAA,EAAA,GAAA,UAAA,EAAA,IAAA,EAAA;AACA,OAAA,CAAA;AACA,IAAA;AACA,EAAA;AACA;;AAEA,SAAA,oBAAA,CAAA,QAAA,EAAA,qBAAA,EAAA;AACA,EAAA,MAAA,IAAA,GAAA,QAAA,CAAA,EAAA;AACA,EAAA,MAAA,UAAA,GAAA,QAAA,CAAA,UAAA,GAAA,EAAA,GAAA,QAAA,CAAA,UAAA,EAAA,GAAA,EAAA;AACA,EAAA,MAAA,QAAA,GAAA,aAAA,CAAA,QAAA,CAAA;;AAEA,EAAA,QAAA,QAAA,CAAA,IAAA;AACA,IAAA,KAAA,SAAA,EAAA;AACA,MAAA,MAAA,YAAA,GAAA,MAAA,CAAA,QAAA,CAAA,KAAA,CAAA,KAAA,CAAA;AACA,MAAA,MAAA,aAAA,GAAA,qBAAA,CAAA,GAAA,CAAA,QAAA,CAAA,IAAA,CAAA;AACA,MAAA,MAAA,KAAA,GAAA,YAAA,GAAA,aAAA;;AAEA,MAAA,IAAA,KAAA,GAAA,CAAA,EAAA;AACA,QAAAA,OAAA,CAAA,KAAA,CAAA,IAAA,EAAA,KAAA,EAAA,EAAA,UAAA,EAAA,CAAA;AACA,MAAA;;AAEA,MAAA,qBAAA,CAAA,GAAA,CAAA,QAAA,EAAA,YAAA,CAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA,KAAA,OAAA,EAAA;AACA,MAAA,MAAA,KAAA,GAAA,MAAA,CAAA,QAAA,CAAA,KAAA,CAAA,KAAA,CAAA;AACA,MAAAA,OAAA,CAAA,KAAA,CAAA,IAAA,EAAA,KAAA,EAAA,EAAA,UAAA,EAAA,CAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA,KAAA,WAAA;AACA,IAAA,KAAA,SAAA,EAAA;AACA,MAAAA,OAAA,CAAA,KAAA,CAAA,CAAA,EAAA,IAAA,CAAA,IAAA,CAAA,EAAA,QAAA,CAAA,KAAA,CAAA,GAAA,IAAA,CAAA,EAAA,EAAA,UAAA,EAAA,CAAA;AACA,MAAAA,OAAA,CAAA,KAAA,CAAA,CAAA,EAAA,IAAA,CAAA,MAAA,CAAA,EAAA,QAAA,CAAA,KAAA,CAAA,KAAA,IAAA,CAAA,EAAA,EAAA,UAAA,EAAA,CAAA;AACA,MAAAA,OAAA,CAAA,KAAA,CAAA,CAAA,EAAA,IAAA,CAAA,IAAA,CAAA,EAAA,QAAA,CAAA,KAAA,CAAA,GAAA,IAAA,CAAA,EAAA,EAAA,UAAA,EAAA,CAAA;AACA,MAAAA,OAAA,CAAA,KAAA,CAAA,CAAA,EAAA,IAAA,CAAA,IAAA,CAAA,EAAA,QAAA,CAAA,KAAA,CAAA,GAAA,IAAA,CAAA,EAAA,EAAA,UAAA,EAAA,CAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA,KAAA,WAAA,EAAA;AACA,MAAA,KAAA,MAAA,CAAA,IAAA,EAAA,KAAA,CAAA,IAAA,QAAA,CAAA,KAAA,CAAA,WAAA,EAAA;AACA,QAAAA,OAAA,CAAA,KAAA,CAAA,IAAA,EAAA,KAAA,EAAA;AACA,UAAA,UAAA,EAAA,EAAA,GAAA,UAAA,EAAA,IAAA,EAAA;AACA,SAAA,CAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA;AACA;;AAEA;AACA;AACA;;AAIA;AACA;AACA,MAAA,YAAA,GAAA,MAAA;AACA,MAAA,cAAA,GAAA,YAAA,CAAA,gBAAA,CAAA;AACA;AACA,MAAA,cAAA,GAAA,YAAA,CAAA,gBAAA,CAAA;;AAEA,SAAA,oBAAA,CAAA,qBAAA,EAAA;AACA,EAAA,IAAA,cAAA,EAAA;AACA;AACA,IAAA,MAAA,SAAA,GAAA,cAAA,CAAA,OAAA,CAAA,KAAA,EAAA,CAAA;AACA,IAAA,KAAA,MAAA,QAAA,IAAA,SAAA,EAAA;AACA,MAAA,oBAAA,CAAA,QAAA,EAAA,qBAAA,CAAA;AACA,IAAA;AACA,EAAA,CAAA,MAAA,IAAA,cAAA,EAAA;AACA;AACA,IAAA,MAAA,SAAA,GAAA,cAAA,EAAA;AACA,IAAA,KAAA,MAAA,IAAA,IAAA,SAAA,EAAA;AACA,MAAA,oBAAA,CAAA,IAAA,EAAA,qBAAA,CAAA;AACA,IAAA;AACA,EAAA;AACA;;AAEA,SAAA,2BAAA,CAAA,qBAAA,EAAA;AACA,EAAA,MAAA,QAAA,GAAA,QAAA,CAAA,MAAA,CAAA,YAAA,CAAA;;AAEA,EAAA,OAAA,MAAA,CAAA,MAAA;AACA,IAAA,MAAA,CAAA,IAAA,CAAA,MAAA,oBAAA,CAAA,qBAAA,CAAA,CAAA;AACA,IAAA,QAAA;AACA,GAAA,CAAA,IAAA,CAAA,MAAA,CAAA,MAAA,EAAA,MAAA,CAAA,aAAA,CAAA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAA,wBAAA,GAAA,KAAA,CAAA,aAAA;AACA,EAAA,MAAA,CAAA,GAAA,CAAA,aAAA;AACA,IAAA,MAAA,qBAAA,GAAA,IAAA,GAAA,EAAA;;AAEA,IAAA,OAAA,MAAA,CAAA,cAAA,CAAA,MAAA,CAAA,IAAA,EAAA;AACA,MAAA,MAAA,CAAA,IAAA,CAAA,MAAA;AACA,QAAA,qBAAA,CAAA,KAAA,EAAA;AACA,MAAA,CAAA,CAAA;AACA,KAAA;;AAEA,IAAA,OAAA,MAAA,CAAA,UAAA,CAAA,2BAAA,CAAA,qBAAA,CAAA,CAAA;AACA,EAAA,CAAA,CAAA;AACA;;;;"}
|
|
1
|
+
{"version":3,"file":"metrics.js","sources":["../../src/metrics.ts"],"sourcesContent":["import { metrics as sentryMetrics } from '@sentry/core';\nimport * as Context from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Metric from 'effect/Metric';\nimport * as Schedule from 'effect/Schedule';\n\ntype MetricAttributes = Record<string, string>;\n\n// =============================================================================\n// Effect v3 Types (vendored - not exported from effect@3.x)\n// =============================================================================\n\ninterface V3MetricLabel {\n key: string;\n value: string;\n}\n\ninterface V3MetricPair {\n metricKey: {\n name: string;\n tags: ReadonlyArray<V3MetricLabel>;\n keyType: { _tag: string };\n };\n metricState: {\n count?: number | bigint;\n value?: number;\n sum?: number;\n min?: number;\n max?: number;\n occurrences?: Map<string, number>;\n };\n}\n\n// Effect v3 `MetricState` implementations brand themselves with a `Symbol.for(...)` TypeId\n// rather than a string `_tag`. We use these globally-registered symbols to classify state\n// instances returned by `Metric.unsafeSnapshot()` without importing `effect/MetricState`\n// (the module does not exist in Effect v4).\nconst V3_COUNTER_STATE_TYPE_ID = Symbol.for('effect/MetricState/Counter');\nconst V3_GAUGE_STATE_TYPE_ID = Symbol.for('effect/MetricState/Gauge');\nconst V3_HISTOGRAM_STATE_TYPE_ID = Symbol.for('effect/MetricState/Histogram');\nconst V3_SUMMARY_STATE_TYPE_ID = Symbol.for('effect/MetricState/Summary');\nconst V3_FREQUENCY_STATE_TYPE_ID = Symbol.for('effect/MetricState/Frequency');\n\nfunction labelsToAttributes(labels: ReadonlyArray<V3MetricLabel>): MetricAttributes {\n return labels.reduce((acc, label) => ({ ...acc, [label.key]: label.value }), {});\n}\n\nfunction getMetricIdV3(pair: V3MetricPair): string {\n const tags = pair.metricKey.tags.map(t => `${t.key}=${t.value}`).join(',');\n return `${pair.metricKey.name}:${tags}`;\n}\n\nfunction getMetricIdV4(snapshot: Metric.Metric.Snapshot): string {\n const attrs = snapshot.attributes\n ? Object.entries(snapshot.attributes)\n .map(([k, v]) => `${k}=${v}`)\n .join(',')\n : '';\n return `${snapshot.id}:${attrs}`;\n}\n\nfunction sendV3MetricToSentry(pair: V3MetricPair, previousCounterValues: Map<string, number>): void {\n const { metricKey, metricState } = pair;\n const name = metricKey.name;\n const attributes = labelsToAttributes(metricKey.tags);\n const metricId = getMetricIdV3(pair);\n\n const state = metricState as unknown as Record<symbol, unknown>;\n\n if (state[V3_COUNTER_STATE_TYPE_ID] !== undefined) {\n const currentValue = Number(metricState.count);\n const previousValue = previousCounterValues.get(metricId) ?? 0;\n const delta = currentValue - previousValue;\n\n if (delta > 0) {\n sentryMetrics.count(name, delta, { attributes });\n }\n\n previousCounterValues.set(metricId, currentValue);\n } else if (state[V3_GAUGE_STATE_TYPE_ID] !== undefined) {\n const value = Number(metricState.value);\n sentryMetrics.gauge(name, value, { attributes });\n } else if (state[V3_HISTOGRAM_STATE_TYPE_ID] !== undefined || state[V3_SUMMARY_STATE_TYPE_ID] !== undefined) {\n sentryMetrics.gauge(`${name}.sum`, metricState.sum ?? 0, { attributes });\n sentryMetrics.gauge(`${name}.count`, Number(metricState.count ?? 0), { attributes });\n sentryMetrics.gauge(`${name}.min`, metricState.min ?? 0, { attributes });\n sentryMetrics.gauge(`${name}.max`, metricState.max ?? 0, { attributes });\n } else if (state[V3_FREQUENCY_STATE_TYPE_ID] !== undefined && metricState.occurrences) {\n for (const [word, count] of metricState.occurrences) {\n sentryMetrics.count(name, count, {\n attributes: { ...attributes, word },\n });\n }\n }\n}\n\nfunction sendV4MetricToSentry(snapshot: Metric.Metric.Snapshot, previousCounterValues: Map<string, number>): void {\n const name = snapshot.id;\n const attributes: MetricAttributes = snapshot.attributes ? { ...snapshot.attributes } : {};\n const metricId = getMetricIdV4(snapshot);\n\n switch (snapshot.type) {\n case 'Counter': {\n const currentValue = Number(snapshot.state.count);\n const previousValue = previousCounterValues.get(metricId) ?? 0;\n const delta = currentValue - previousValue;\n\n if (delta > 0) {\n sentryMetrics.count(name, delta, { attributes });\n }\n\n previousCounterValues.set(metricId, currentValue);\n break;\n }\n case 'Gauge': {\n const value = Number(snapshot.state.value);\n sentryMetrics.gauge(name, value, { attributes });\n break;\n }\n case 'Histogram':\n case 'Summary': {\n sentryMetrics.gauge(`${name}.sum`, snapshot.state.sum ?? 0, { attributes });\n sentryMetrics.gauge(`${name}.count`, snapshot.state.count ?? 0, { attributes });\n sentryMetrics.gauge(`${name}.min`, snapshot.state.min ?? 0, { attributes });\n sentryMetrics.gauge(`${name}.max`, snapshot.state.max ?? 0, { attributes });\n break;\n }\n case 'Frequency': {\n for (const [word, count] of snapshot.state.occurrences) {\n sentryMetrics.count(name, count, {\n attributes: { ...attributes, word },\n });\n }\n break;\n }\n }\n}\n\n// =============================================================================\n// Effect v3 snapshot function type (vendored - not exported from effect@3.x)\n// =============================================================================\n\ntype V3UnsafeSnapshotFn = () => ReadonlyArray<V3MetricPair>;\n\n// Use bracket notation to avoid Webpack static analysis flagging missing exports\n// This is important for Effect v3 compatibility.\nconst MetricModule = Metric;\nconst snapshotUnsafe = MetricModule['snapshotUnsafe'] as typeof Metric.snapshotUnsafe | undefined;\n// @ts-expect-error - unsafeSnapshot is not exported from effect@3.x\nconst unsafeSnapshot = MetricModule['unsafeSnapshot'] as V3UnsafeSnapshotFn | undefined;\n\nfunction flushMetricsToSentry(previousCounterValues: Map<string, number>): void {\n if (snapshotUnsafe) {\n // Effect v4\n const snapshots = snapshotUnsafe(Context.empty());\n for (const snapshot of snapshots) {\n sendV4MetricToSentry(snapshot, previousCounterValues);\n }\n } else if (unsafeSnapshot) {\n // Effect v3\n const snapshots = unsafeSnapshot();\n for (const pair of snapshots) {\n sendV3MetricToSentry(pair, previousCounterValues);\n }\n }\n}\n\nfunction createMetricsReporterEffect(previousCounterValues: Map<string, number>): Effect.Effect<void, never, never> {\n const schedule = Schedule.spaced('10 seconds');\n\n return Effect.repeat(\n Effect.sync(() => flushMetricsToSentry(previousCounterValues)),\n schedule,\n ).pipe(Effect.asVoid, Effect.interruptible);\n}\n\n/**\n * Effect Layer that periodically flushes metrics to Sentry.\n * The layer manages its own state for delta counter calculations,\n * which is automatically cleaned up when the layer is finalized.\n */\nexport const SentryEffectMetricsLayer: Layer.Layer<never, never, never> = Layer.effectDiscard(\n Effect.gen(function* () {\n const previousCounterValues = new Map<string, number>();\n\n yield* Effect.acquireRelease(Effect.void, () =>\n Effect.sync(() => {\n previousCounterValues.clear();\n }),\n );\n\n yield* Effect.forkScoped(createMetricsReporterEffect(previousCounterValues));\n }),\n);\n"],"names":["sentryMetrics"],"mappings":"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"}
|
package/build/esm/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"type":"module","version":"10.
|
|
1
|
+
{"type":"module","version":"10.54.0","sideEffects":false}
|
|
@@ -1,35 +1,6 @@
|
|
|
1
1
|
import { suspend, empty } from 'effect/Layer';
|
|
2
2
|
import { init } from './sdk.js';
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* Options for the Sentry Effect server layer.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Creates an Effect Layer that initializes Sentry for Node.js servers.
|
|
10
|
-
*
|
|
11
|
-
* To enable Effect tracing, logs, or metrics, compose with the respective layers:
|
|
12
|
-
* - `Layer.setTracer(Sentry.SentryEffectTracer)` for tracing
|
|
13
|
-
* - `Logger.replace(Logger.defaultLogger, Sentry.SentryEffectLogger)` for logs
|
|
14
|
-
* - `Sentry.SentryEffectMetricsLayer` for metrics
|
|
15
|
-
*
|
|
16
|
-
* @example
|
|
17
|
-
* ```typescript
|
|
18
|
-
* import * as Sentry from '@sentry/effect/server';
|
|
19
|
-
* import { NodeRuntime } from '@effect/platform-node';
|
|
20
|
-
* import { Layer, Logger } from 'effect';
|
|
21
|
-
* import { HttpLive } from './Http.js';
|
|
22
|
-
*
|
|
23
|
-
* const SentryLive = Layer.mergeAll(
|
|
24
|
-
* Sentry.effectLayer({ dsn: '__DSN__' }),
|
|
25
|
-
* Layer.setTracer(Sentry.SentryEffectTracer),
|
|
26
|
-
* Logger.replace(Logger.defaultLogger, Sentry.SentryEffectLogger),
|
|
27
|
-
* );
|
|
28
|
-
*
|
|
29
|
-
* const MainLive = HttpLive.pipe(Layer.provide(SentryLive));
|
|
30
|
-
* MainLive.pipe(Layer.launch, NodeRuntime.runMain);
|
|
31
|
-
* ```
|
|
32
|
-
*/
|
|
33
4
|
function effectLayer(options) {
|
|
34
5
|
return suspend(() => {
|
|
35
6
|
init(options);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/server/index.ts"],"sourcesContent":["import type { NodeOptions } from '@sentry/node-core/light';\nimport type * as EffectLayer from 'effect/Layer';\nimport { empty as emptyLayer, suspend as suspendLayer } from 'effect/Layer';\nimport { init } from './sdk';\n\nexport { init } from './sdk';\n\n/**\n * Options for the Sentry Effect server layer.\n */\nexport type EffectServerLayerOptions = NodeOptions;\n\n/**\n * Creates an Effect Layer that initializes Sentry for Node.js servers.\n *\n * To enable Effect tracing, logs, or metrics, compose with the respective layers:\n * - `Layer.setTracer(Sentry.SentryEffectTracer)` for tracing\n * - `Logger.replace(Logger.defaultLogger, Sentry.SentryEffectLogger)` for logs\n * - `Sentry.SentryEffectMetricsLayer` for metrics\n *\n * @example\n * ```typescript\n * import * as Sentry from '@sentry/effect/server';\n * import { NodeRuntime } from '@effect/platform-node';\n * import { Layer, Logger } from 'effect';\n * import { HttpLive } from './Http.js';\n *\n * const SentryLive = Layer.mergeAll(\n * Sentry.effectLayer({ dsn: '__DSN__' }),\n * Layer.setTracer(Sentry.SentryEffectTracer),\n * Logger.replace(Logger.defaultLogger, Sentry.SentryEffectLogger),\n * );\n *\n * const MainLive = HttpLive.pipe(Layer.provide(SentryLive));\n * MainLive.pipe(Layer.launch, NodeRuntime.runMain);\n * ```\n */\nexport function effectLayer(options: EffectServerLayerOptions): EffectLayer.Layer<never, never, never> {\n return suspendLayer(() => {\n init(options);\n return emptyLayer;\n });\n}\n"],"names":["suspendLayer","emptyLayer"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/server/index.ts"],"sourcesContent":["import type { NodeOptions } from '@sentry/node-core/light';\nimport type * as EffectLayer from 'effect/Layer';\nimport { empty as emptyLayer, suspend as suspendLayer } from 'effect/Layer';\nimport { init } from './sdk';\n\nexport { init } from './sdk';\n\n/**\n * Options for the Sentry Effect server layer.\n */\nexport type EffectServerLayerOptions = NodeOptions;\n\n/**\n * Creates an Effect Layer that initializes Sentry for Node.js servers.\n *\n * To enable Effect tracing, logs, or metrics, compose with the respective layers:\n * - `Layer.setTracer(Sentry.SentryEffectTracer)` for tracing\n * - `Logger.replace(Logger.defaultLogger, Sentry.SentryEffectLogger)` for logs\n * - `Sentry.SentryEffectMetricsLayer` for metrics\n *\n * @example\n * ```typescript\n * import * as Sentry from '@sentry/effect/server';\n * import { NodeRuntime } from '@effect/platform-node';\n * import { Layer, Logger } from 'effect';\n * import { HttpLive } from './Http.js';\n *\n * const SentryLive = Layer.mergeAll(\n * Sentry.effectLayer({ dsn: '__DSN__' }),\n * Layer.setTracer(Sentry.SentryEffectTracer),\n * Logger.replace(Logger.defaultLogger, Sentry.SentryEffectLogger),\n * );\n *\n * const MainLive = HttpLive.pipe(Layer.provide(SentryLive));\n * MainLive.pipe(Layer.launch, NodeRuntime.runMain);\n * ```\n */\nexport function effectLayer(options: EffectServerLayerOptions): EffectLayer.Layer<never, never, never> {\n return suspendLayer(() => {\n init(options);\n return emptyLayer;\n });\n}\n"],"names":["suspendLayer","emptyLayer"],"mappings":";;;AAqCO,SAAS,YAAY,OAAA,EAA2E;AACrG,EAAA,OAAOA,QAAa,MAAM;AACxB,IAAA,IAAA,CAAK,OAAO,CAAA;AACZ,IAAA,OAAOC,KAAA;AAAA,EACT,CAAC,CAAA;AACH;;;;"}
|
package/build/esm/server/sdk.js
CHANGED
|
@@ -1,19 +1,11 @@
|
|
|
1
1
|
import { applySdkMetadata } from '@sentry/core';
|
|
2
2
|
import { init as init$1 } from '@sentry/node-core/light';
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* Initializes the Sentry Effect SDK for Node.js servers.
|
|
6
|
-
*
|
|
7
|
-
* @param options - Configuration options for the SDK
|
|
8
|
-
* @returns The initialized Sentry client, or undefined if initialization failed
|
|
9
|
-
*/
|
|
10
4
|
function init(options) {
|
|
11
5
|
const opts = {
|
|
12
|
-
...options
|
|
6
|
+
...options
|
|
13
7
|
};
|
|
14
|
-
|
|
15
|
-
applySdkMetadata(opts, 'effect', ['effect', 'node-light']);
|
|
16
|
-
|
|
8
|
+
applySdkMetadata(opts, "effect", ["effect", "node-light"]);
|
|
17
9
|
return init$1(opts);
|
|
18
10
|
}
|
|
19
11
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.js","sources":["../../../src/server/sdk.ts"],"sourcesContent":["import type { Client } from '@sentry/core';\nimport { applySdkMetadata } from '@sentry/core';\nimport type { NodeOptions } from '@sentry/node-core/light';\nimport { init as initNode } from '@sentry/node-core/light';\n\n/**\n * Initializes the Sentry Effect SDK for Node.js servers.\n *\n * @param options - Configuration options for the SDK\n * @returns The initialized Sentry client, or undefined if initialization failed\n */\nexport function init(options: NodeOptions): Client | undefined {\n const opts = {\n ...options,\n };\n\n applySdkMetadata(opts, 'effect', ['effect', 'node-light']);\n\n return initNode(opts);\n}\n"],"names":["initNode"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"sdk.js","sources":["../../../src/server/sdk.ts"],"sourcesContent":["import type { Client } from '@sentry/core';\nimport { applySdkMetadata } from '@sentry/core';\nimport type { NodeOptions } from '@sentry/node-core/light';\nimport { init as initNode } from '@sentry/node-core/light';\n\n/**\n * Initializes the Sentry Effect SDK for Node.js servers.\n *\n * @param options - Configuration options for the SDK\n * @returns The initialized Sentry client, or undefined if initialization failed\n */\nexport function init(options: NodeOptions): Client | undefined {\n const opts = {\n ...options,\n };\n\n applySdkMetadata(opts, 'effect', ['effect', 'node-light']);\n\n return initNode(opts);\n}\n"],"names":["initNode"],"mappings":";;;AAWO,SAAS,KAAK,OAAA,EAA0C;AAC7D,EAAA,MAAM,IAAA,GAAO;AAAA,IACX,GAAG;AAAA,GACL;AAEA,EAAA,gBAAA,CAAiB,IAAA,EAAM,QAAA,EAAU,CAAC,QAAA,EAAU,YAAY,CAAC,CAAA;AAEzD,EAAA,OAAOA,OAAS,IAAI,CAAA;AACtB;;;;"}
|
package/build/esm/tracer.js
CHANGED
|
@@ -4,170 +4,121 @@ import * as Option from 'effect/Option';
|
|
|
4
4
|
import * as EffectTracer from 'effect/Tracer';
|
|
5
5
|
|
|
6
6
|
function deriveOrigin(name) {
|
|
7
|
-
if (name.startsWith(
|
|
8
|
-
return
|
|
7
|
+
if (name.startsWith("http.server") || name.startsWith("http.client")) {
|
|
8
|
+
return "auto.http.effect";
|
|
9
9
|
}
|
|
10
|
-
|
|
11
|
-
return 'auto.function.effect';
|
|
10
|
+
return "auto.function.effect";
|
|
12
11
|
}
|
|
13
|
-
|
|
14
|
-
const SENTRY_SPAN_SYMBOL = Symbol.for('@sentry/effect.SentrySpan');
|
|
15
|
-
|
|
12
|
+
const SENTRY_SPAN_SYMBOL = /* @__PURE__ */ Symbol.for("@sentry/effect.SentrySpan");
|
|
16
13
|
function nanosToHrTime(nanos) {
|
|
17
|
-
const seconds = Number(nanos / BigInt(
|
|
18
|
-
const remainingNanos = Number(nanos % BigInt(
|
|
14
|
+
const seconds = Number(nanos / BigInt(1e9));
|
|
15
|
+
const remainingNanos = Number(nanos % BigInt(1e9));
|
|
19
16
|
return [seconds, remainingNanos];
|
|
20
17
|
}
|
|
21
|
-
|
|
22
18
|
function isSentrySpan(span) {
|
|
23
19
|
return SENTRY_SPAN_SYMBOL in span;
|
|
24
20
|
}
|
|
25
|
-
|
|
26
21
|
function getErrorMessage(exit) {
|
|
27
22
|
if (!Exit.isFailure(exit)) {
|
|
28
|
-
return
|
|
23
|
+
return void 0;
|
|
29
24
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
// Effect v4: cause.reasons is an array of Reason objects
|
|
34
|
-
if (
|
|
35
|
-
cause &&
|
|
36
|
-
typeof cause === 'object' &&
|
|
37
|
-
'reasons' in cause &&
|
|
38
|
-
Array.isArray((cause ).reasons)
|
|
39
|
-
) {
|
|
40
|
-
const reasons = (cause ).reasons;
|
|
25
|
+
const cause = exit.cause;
|
|
26
|
+
if (cause && typeof cause === "object" && "reasons" in cause && Array.isArray(cause.reasons)) {
|
|
27
|
+
const reasons = cause.reasons;
|
|
41
28
|
for (const reason of reasons) {
|
|
42
|
-
if (reason._tag ===
|
|
29
|
+
if (reason._tag === "Fail" && reason.error !== void 0) {
|
|
43
30
|
return String(reason.error);
|
|
44
31
|
}
|
|
45
|
-
if (reason._tag ===
|
|
32
|
+
if (reason._tag === "Die" && reason.defect !== void 0) {
|
|
46
33
|
return String(reason.defect);
|
|
47
34
|
}
|
|
48
35
|
}
|
|
49
|
-
return
|
|
36
|
+
return "internal_error";
|
|
50
37
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const v3Cause = cause ;
|
|
55
|
-
if (v3Cause._tag === 'Fail') {
|
|
38
|
+
if (cause && typeof cause === "object" && "_tag" in cause) {
|
|
39
|
+
const v3Cause = cause;
|
|
40
|
+
if (v3Cause._tag === "Fail") {
|
|
56
41
|
return String(v3Cause.error);
|
|
57
42
|
}
|
|
58
|
-
if (v3Cause._tag ===
|
|
43
|
+
if (v3Cause._tag === "Die") {
|
|
59
44
|
return String(v3Cause.defect);
|
|
60
45
|
}
|
|
61
46
|
}
|
|
62
|
-
|
|
63
|
-
return 'internal_error';
|
|
47
|
+
return "internal_error";
|
|
64
48
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
startTime,
|
|
74
|
-
kind,
|
|
75
|
-
existingSpan,
|
|
76
|
-
) {this.name = name;this.context = context;this.kind = kind;
|
|
77
|
-
this[SENTRY_SPAN_SYMBOL] = true ;
|
|
78
|
-
this._tag = 'Span' ;
|
|
79
|
-
this.attributes = new Map();
|
|
49
|
+
class SentrySpanWrapper {
|
|
50
|
+
constructor(name, parent, context, links, startTime, kind, existingSpan) {
|
|
51
|
+
this.name = name;
|
|
52
|
+
this.context = context;
|
|
53
|
+
this.kind = kind;
|
|
54
|
+
this[SENTRY_SPAN_SYMBOL] = true;
|
|
55
|
+
this._tag = "Span";
|
|
56
|
+
this.attributes = /* @__PURE__ */ new Map();
|
|
80
57
|
this.parent = parent;
|
|
81
58
|
this.links = [...links];
|
|
82
59
|
this.sentrySpan = existingSpan;
|
|
83
60
|
this.annotations = context;
|
|
84
|
-
|
|
85
61
|
const spanContext = this.sentrySpan.spanContext();
|
|
86
62
|
this.spanId = spanContext.spanId;
|
|
87
63
|
this.traceId = spanContext.traceId;
|
|
88
64
|
this.sampled = this.sentrySpan.isRecording();
|
|
89
65
|
this.status = {
|
|
90
|
-
_tag:
|
|
91
|
-
startTime
|
|
66
|
+
_tag: "Started",
|
|
67
|
+
startTime
|
|
92
68
|
};
|
|
93
69
|
}
|
|
94
|
-
|
|
95
|
-
attribute(key, value) {
|
|
70
|
+
attribute(key, value) {
|
|
96
71
|
if (!this.sentrySpan.isRecording()) {
|
|
97
72
|
return;
|
|
98
73
|
}
|
|
99
|
-
|
|
100
|
-
this.sentrySpan.setAttribute(key, value );
|
|
74
|
+
this.sentrySpan.setAttribute(key, value);
|
|
101
75
|
this.attributes.set(key, value);
|
|
102
76
|
}
|
|
103
|
-
|
|
104
|
-
addLinks(links) {
|
|
77
|
+
addLinks(links) {
|
|
105
78
|
this.links.push(...links);
|
|
106
79
|
}
|
|
107
|
-
|
|
108
|
-
end(endTime, exit) {
|
|
80
|
+
end(endTime, exit) {
|
|
109
81
|
this.status = {
|
|
110
|
-
_tag:
|
|
82
|
+
_tag: "Ended",
|
|
111
83
|
endTime,
|
|
112
84
|
exit,
|
|
113
|
-
startTime: this.status.startTime
|
|
85
|
+
startTime: this.status.startTime
|
|
114
86
|
};
|
|
115
|
-
|
|
116
87
|
if (!this.sentrySpan.isRecording()) {
|
|
117
88
|
return;
|
|
118
89
|
}
|
|
119
|
-
|
|
120
90
|
if (Exit.isFailure(exit)) {
|
|
121
|
-
const message = getErrorMessage(exit) ??
|
|
91
|
+
const message = getErrorMessage(exit) ?? "internal_error";
|
|
122
92
|
this.sentrySpan.setStatus({ code: 2, message });
|
|
123
93
|
} else {
|
|
124
94
|
this.sentrySpan.setStatus({ code: 1 });
|
|
125
95
|
}
|
|
126
|
-
|
|
127
96
|
this.sentrySpan.end(nanosToHrTime(endTime));
|
|
128
97
|
}
|
|
129
|
-
|
|
130
|
-
event(name, startTime, attributes) {
|
|
98
|
+
event(name, startTime, attributes) {
|
|
131
99
|
if (!this.sentrySpan.isRecording()) {
|
|
132
100
|
return;
|
|
133
101
|
}
|
|
134
|
-
|
|
135
|
-
this.sentrySpan.addEvent(name, attributes , nanosToHrTime(startTime));
|
|
102
|
+
this.sentrySpan.addEvent(name, attributes, nanosToHrTime(startTime));
|
|
136
103
|
}
|
|
137
104
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
name,
|
|
141
|
-
parent,
|
|
142
|
-
context,
|
|
143
|
-
links,
|
|
144
|
-
startTime,
|
|
145
|
-
kind,
|
|
146
|
-
) {
|
|
147
|
-
const parentSentrySpan =
|
|
148
|
-
Option.isSome(parent) && isSentrySpan(parent.value) ? parent.value.sentrySpan : (getActiveSpan() ?? null);
|
|
149
|
-
|
|
105
|
+
function createSentrySpan(name, parent, context, links, startTime, kind) {
|
|
106
|
+
const parentSentrySpan = Option.isSome(parent) && isSentrySpan(parent.value) ? parent.value.sentrySpan : getActiveSpan() ?? null;
|
|
150
107
|
const newSpan = startInactiveSpan({
|
|
151
108
|
name,
|
|
152
109
|
startTime: nanosToHrTime(startTime),
|
|
153
110
|
attributes: {
|
|
154
|
-
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: deriveOrigin(name)
|
|
111
|
+
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: deriveOrigin(name)
|
|
155
112
|
},
|
|
156
|
-
...
|
|
113
|
+
...parentSentrySpan ? { parentSpan: parentSentrySpan } : {}
|
|
157
114
|
});
|
|
158
|
-
|
|
159
115
|
return new SentrySpanWrapper(name, parent, context, links, startTime, kind, newSpan);
|
|
160
116
|
}
|
|
161
|
-
|
|
162
|
-
// Check if we're running Effect v4 by checking the Exit/Cause structure
|
|
163
|
-
// In v4, causes have a 'reasons' array
|
|
164
|
-
// In v3, causes have '_tag' directly on the cause object
|
|
165
117
|
const isEffectV4 = (() => {
|
|
166
118
|
try {
|
|
167
|
-
const testExit = Exit.fail(
|
|
119
|
+
const testExit = Exit.fail("test");
|
|
168
120
|
const cause = testExit.cause;
|
|
169
|
-
|
|
170
|
-
if (cause && typeof cause === 'object' && 'reasons' in cause) {
|
|
121
|
+
if (cause && typeof cause === "object" && "reasons" in cause) {
|
|
171
122
|
return true;
|
|
172
123
|
}
|
|
173
124
|
return false;
|
|
@@ -175,33 +126,22 @@ const isEffectV4 = (() => {
|
|
|
175
126
|
return false;
|
|
176
127
|
}
|
|
177
128
|
})();
|
|
178
|
-
|
|
179
129
|
const makeSentryTracerV3 = () => {
|
|
180
|
-
// Effect v3 API: span(name, parent, context, links, startTime, kind)
|
|
181
130
|
return EffectTracer.make({
|
|
182
|
-
span(
|
|
183
|
-
name,
|
|
184
|
-
parent,
|
|
185
|
-
context,
|
|
186
|
-
links,
|
|
187
|
-
startTime,
|
|
188
|
-
kind,
|
|
189
|
-
) {
|
|
131
|
+
span(name, parent, context, links, startTime, kind) {
|
|
190
132
|
return createSentrySpan(name, parent, context, links, startTime, kind);
|
|
191
133
|
},
|
|
192
134
|
context(execution, fiber) {
|
|
193
135
|
const currentSpan = fiber.currentSpan;
|
|
194
|
-
if (currentSpan ===
|
|
136
|
+
if (currentSpan === void 0 || !isSentrySpan(currentSpan)) {
|
|
195
137
|
return execution();
|
|
196
138
|
}
|
|
197
139
|
return withActiveSpan(currentSpan.sentrySpan, execution);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
140
|
+
}
|
|
141
|
+
});
|
|
200
142
|
};
|
|
201
|
-
|
|
202
143
|
const makeSentryTracerV4 = () => {
|
|
203
|
-
const EFFECT_EVALUATE =
|
|
204
|
-
|
|
144
|
+
const EFFECT_EVALUATE = "~effect/Effect/evaluate";
|
|
205
145
|
return EffectTracer.make({
|
|
206
146
|
span(options) {
|
|
207
147
|
return createSentrySpan(
|
|
@@ -210,22 +150,18 @@ const makeSentryTracerV4 = () => {
|
|
|
210
150
|
options.annotations,
|
|
211
151
|
options.links,
|
|
212
152
|
options.startTime,
|
|
213
|
-
options.kind
|
|
153
|
+
options.kind
|
|
214
154
|
);
|
|
215
155
|
},
|
|
216
156
|
context(primitive, fiber) {
|
|
217
157
|
const currentSpan = fiber.currentSpan;
|
|
218
|
-
if (currentSpan ===
|
|
158
|
+
if (currentSpan === void 0 || !isSentrySpan(currentSpan)) {
|
|
219
159
|
return primitive[EFFECT_EVALUATE](fiber);
|
|
220
160
|
}
|
|
221
161
|
return withActiveSpan(currentSpan.sentrySpan, () => primitive[EFFECT_EVALUATE](fiber));
|
|
222
|
-
}
|
|
162
|
+
}
|
|
223
163
|
});
|
|
224
164
|
};
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* Effect Layer that sets up the Sentry tracer for Effect spans.
|
|
228
|
-
*/
|
|
229
165
|
const SentryEffectTracer = isEffectV4 ? makeSentryTracerV4() : makeSentryTracerV3();
|
|
230
166
|
|
|
231
167
|
export { SentryEffectTracer };
|