@upyo/opentelemetry 0.5.0-dev.86 → 0.5.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/README.md +3 -3
- package/dist/index.cjs +21 -17
- package/dist/index.d.cts +12 -9
- package/dist/index.d.ts +12 -9
- package/dist/index.js +21 -17
- package/package.json +3 -8
package/README.md
CHANGED
|
@@ -264,11 +264,11 @@ The transport automatically classifies errors into standard categories:
|
|
|
264
264
|
| Category | Description | Example Errors |
|
|
265
265
|
| --------------------- | ----------------------- | --------------------------------------- |
|
|
266
266
|
| `auth` | Authentication failures | Invalid API key, unauthorized |
|
|
267
|
-
| `
|
|
267
|
+
| `rate-limit` | Rate limiting | Quota exceeded, too many requests |
|
|
268
268
|
| `network` | Network connectivity | Timeout, DNS resolution, abort |
|
|
269
269
|
| `validation` | Input validation | Invalid email format, malformed request |
|
|
270
|
-
| `
|
|
271
|
-
| `
|
|
270
|
+
| `service-unavailable` | Service outages | HTTP 503, temporarily unavailable |
|
|
271
|
+
| `server-error` | Server errors | HTTP 500, internal server error |
|
|
272
272
|
| `unknown` | Unclassified errors | Any other errors |
|
|
273
273
|
|
|
274
274
|
### Custom Error Classification
|
package/dist/index.cjs
CHANGED
|
@@ -87,16 +87,17 @@ function createOpenTelemetryConfig(config = {}) {
|
|
|
87
87
|
* import { defaultErrorClassifier } from "@upyo/opentelemetry";
|
|
88
88
|
*
|
|
89
89
|
* console.log(defaultErrorClassifier(new Error("401 Unauthorized"))); // "auth"
|
|
90
|
-
* console.log(defaultErrorClassifier(new Error("Rate limit exceeded"))); // "
|
|
90
|
+
* console.log(defaultErrorClassifier(new Error("Rate limit exceeded"))); // "rate-limit"
|
|
91
91
|
* console.log(defaultErrorClassifier(new Error("Connection timeout"))); // "network"
|
|
92
92
|
* console.log(defaultErrorClassifier(new Error("Invalid email format"))); // "validation"
|
|
93
|
-
* console.log(defaultErrorClassifier(new Error("500 Internal Server Error"))); // "
|
|
93
|
+
* console.log(defaultErrorClassifier(new Error("500 Internal Server Error"))); // "server-error"
|
|
94
94
|
* console.log(defaultErrorClassifier(new Error("Something else"))); // "unknown"
|
|
95
95
|
* ```
|
|
96
96
|
*
|
|
97
97
|
* @param error The error to classify.
|
|
98
|
-
* @returns A string category such as `"auth"`, `"
|
|
99
|
-
* `"validation"`, `"
|
|
98
|
+
* @returns A string category such as `"auth"`, `"rate-limit"`, `"network"`,
|
|
99
|
+
* `"validation"`, `"service-unavailable"`, `"server-error"`, or
|
|
100
|
+
* `"unknown"`.
|
|
100
101
|
* @since 0.2.0
|
|
101
102
|
*/
|
|
102
103
|
function defaultErrorClassifier(error) {
|
|
@@ -104,11 +105,11 @@ function defaultErrorClassifier(error) {
|
|
|
104
105
|
const message = error.message.toLowerCase();
|
|
105
106
|
const name$1 = error.name.toLowerCase();
|
|
106
107
|
if (message.includes("auth") || message.includes("unauthorized") || message.includes("invalid api key") || message.includes("403")) return "auth";
|
|
107
|
-
if (message.includes("rate limit") || message.includes("429") || message.includes("quota exceeded") || message.includes("throttle")) return "
|
|
108
|
-
if (message.includes("500") || message.includes("502") || message.includes("504") || message.includes("internal server error")) return "
|
|
108
|
+
if (message.includes("rate limit") || message.includes("429") || message.includes("quota exceeded") || message.includes("throttle")) return "rate-limit";
|
|
109
|
+
if (message.includes("500") || message.includes("502") || message.includes("504") || message.includes("internal server error")) return "server-error";
|
|
109
110
|
if (name$1.includes("network") || message.includes("connect") || message.includes("timeout") || message.includes("dns") || name$1 === "aborterror") return "network";
|
|
110
111
|
if (message.includes("invalid") || message.includes("malformed") || message.includes("validation") || message.includes("400")) return "validation";
|
|
111
|
-
if (message.includes("503") || message.includes("service unavailable") || message.includes("temporarily unavailable")) return "
|
|
112
|
+
if (message.includes("503") || message.includes("service unavailable") || message.includes("temporarily unavailable")) return "service-unavailable";
|
|
112
113
|
}
|
|
113
114
|
return "unknown";
|
|
114
115
|
}
|
|
@@ -116,7 +117,7 @@ function defaultErrorClassifier(error) {
|
|
|
116
117
|
//#endregion
|
|
117
118
|
//#region package.json
|
|
118
119
|
var name = "@upyo/opentelemetry";
|
|
119
|
-
var version = "0.5.0
|
|
120
|
+
var version = "0.5.0";
|
|
120
121
|
var description = "OpenTelemetry observability transport for Upyo email library";
|
|
121
122
|
var keywords = [
|
|
122
123
|
"email",
|
|
@@ -173,7 +174,6 @@ var peerDependencies = {
|
|
|
173
174
|
"@upyo/core": "workspace:*"
|
|
174
175
|
};
|
|
175
176
|
var devDependencies = {
|
|
176
|
-
"@dotenvx/dotenvx": "catalog:",
|
|
177
177
|
"@opentelemetry/api": "catalog:",
|
|
178
178
|
"@opentelemetry/context-async-hooks": "^1.25.1",
|
|
179
179
|
"@opentelemetry/resources": "catalog:",
|
|
@@ -184,12 +184,8 @@ var devDependencies = {
|
|
|
184
184
|
"typescript": "catalog:"
|
|
185
185
|
};
|
|
186
186
|
var scripts = {
|
|
187
|
-
"
|
|
188
|
-
"
|
|
189
|
-
"prepublish": "tsdown",
|
|
190
|
-
"test": "tsdown && dotenvx run --ignore=MISSING_ENV_FILE -- node --experimental-transform-types --test",
|
|
191
|
-
"test:bun": "tsdown && bun test --timeout=30000 --env-file=.env",
|
|
192
|
-
"test:deno": "deno test --allow-env --allow-net --env-file=.env"
|
|
187
|
+
"prepack": "mise run --no-deps :build",
|
|
188
|
+
"prepublish": "mise run --no-deps :build"
|
|
193
189
|
};
|
|
194
190
|
var package_default = {
|
|
195
191
|
name,
|
|
@@ -673,6 +669,7 @@ var NoOpEmailSpan = class {
|
|
|
673
669
|
* @since 0.2.0
|
|
674
670
|
*/
|
|
675
671
|
var OpenTelemetryTransport = class {
|
|
672
|
+
id;
|
|
676
673
|
/**
|
|
677
674
|
* The resolved OpenTelemetry configuration.
|
|
678
675
|
*/
|
|
@@ -690,6 +687,7 @@ var OpenTelemetryTransport = class {
|
|
|
690
687
|
*/
|
|
691
688
|
constructor(transport, config = {}) {
|
|
692
689
|
this.wrappedTransport = transport;
|
|
690
|
+
this.id = transport.id;
|
|
693
691
|
this.config = createOpenTelemetryConfig(config);
|
|
694
692
|
this.transportName = this.extractTransportName(transport);
|
|
695
693
|
this.transportVersion = this.extractTransportVersion(transport);
|
|
@@ -719,7 +717,7 @@ var OpenTelemetryTransport = class {
|
|
|
719
717
|
span?.recordSuccess(receipt.messageId);
|
|
720
718
|
this.metricsCollector?.recordSendComplete(this.transportName, duration, true);
|
|
721
719
|
} else {
|
|
722
|
-
const errorCategory = this.
|
|
720
|
+
const errorCategory = this.classifyReceipt(receipt);
|
|
723
721
|
span?.recordFailure(receipt.errorMessages);
|
|
724
722
|
this.metricsCollector?.recordSendComplete(this.transportName, duration, false, errorCategory);
|
|
725
723
|
}
|
|
@@ -796,7 +794,8 @@ var OpenTelemetryTransport = class {
|
|
|
796
794
|
if (typeof this.wrappedTransport[Symbol.dispose] === "function") this.wrappedTransport[Symbol.dispose]();
|
|
797
795
|
}
|
|
798
796
|
extractTransportName(transport) {
|
|
799
|
-
|
|
797
|
+
if (typeof transport.id === "string" && transport.id !== "") return transport.id;
|
|
798
|
+
const constructorName = transport.constructor?.name;
|
|
800
799
|
if (constructorName && constructorName !== "Object") return constructorName.toLowerCase().replace("transport", "");
|
|
801
800
|
if ("config" in transport && transport.config && typeof transport.config === "object") {
|
|
802
801
|
if ("domain" in transport.config) return "mailgun";
|
|
@@ -839,6 +838,11 @@ var OpenTelemetryTransport = class {
|
|
|
839
838
|
const classifier = this.config.errorClassifier || defaultErrorClassifier;
|
|
840
839
|
return classifier(error);
|
|
841
840
|
}
|
|
841
|
+
classifyReceipt(receipt) {
|
|
842
|
+
const structuredCategory = receipt.errors?.[0]?.category;
|
|
843
|
+
if (structuredCategory != null) return structuredCategory;
|
|
844
|
+
return this.classifyErrors(receipt.errorMessages);
|
|
845
|
+
}
|
|
842
846
|
classifyErrors(errorMessages) {
|
|
843
847
|
if (errorMessages.length === 0) return "unknown";
|
|
844
848
|
const syntheticError = new Error(errorMessages[0]);
|
package/dist/index.d.cts
CHANGED
|
@@ -162,16 +162,17 @@ interface ResolvedOpenTelemetryConfig {
|
|
|
162
162
|
* import { defaultErrorClassifier } from "@upyo/opentelemetry";
|
|
163
163
|
*
|
|
164
164
|
* console.log(defaultErrorClassifier(new Error("401 Unauthorized"))); // "auth"
|
|
165
|
-
* console.log(defaultErrorClassifier(new Error("Rate limit exceeded"))); // "
|
|
165
|
+
* console.log(defaultErrorClassifier(new Error("Rate limit exceeded"))); // "rate-limit"
|
|
166
166
|
* console.log(defaultErrorClassifier(new Error("Connection timeout"))); // "network"
|
|
167
167
|
* console.log(defaultErrorClassifier(new Error("Invalid email format"))); // "validation"
|
|
168
|
-
* console.log(defaultErrorClassifier(new Error("500 Internal Server Error"))); // "
|
|
168
|
+
* console.log(defaultErrorClassifier(new Error("500 Internal Server Error"))); // "server-error"
|
|
169
169
|
* console.log(defaultErrorClassifier(new Error("Something else"))); // "unknown"
|
|
170
170
|
* ```
|
|
171
171
|
*
|
|
172
172
|
* @param error The error to classify.
|
|
173
|
-
* @returns A string category such as `"auth"`, `"
|
|
174
|
-
* `"validation"`, `"
|
|
173
|
+
* @returns A string category such as `"auth"`, `"rate-limit"`, `"network"`,
|
|
174
|
+
* `"validation"`, `"service-unavailable"`, `"server-error"`, or
|
|
175
|
+
* `"unknown"`.
|
|
175
176
|
* @since 0.2.0
|
|
176
177
|
*/
|
|
177
178
|
declare function defaultErrorClassifier(error: unknown): string;
|
|
@@ -237,7 +238,8 @@ declare function defaultErrorClassifier(error: unknown): string;
|
|
|
237
238
|
*
|
|
238
239
|
* @since 0.2.0
|
|
239
240
|
*/
|
|
240
|
-
declare class OpenTelemetryTransport implements Transport
|
|
241
|
+
declare class OpenTelemetryTransport<TProviderId extends string = string> implements Transport<TProviderId>, AsyncDisposable {
|
|
242
|
+
readonly id: TProviderId;
|
|
241
243
|
/**
|
|
242
244
|
* The resolved OpenTelemetry configuration.
|
|
243
245
|
*/
|
|
@@ -253,7 +255,7 @@ declare class OpenTelemetryTransport implements Transport, AsyncDisposable {
|
|
|
253
255
|
* @param transport The base transport to wrap with observability.
|
|
254
256
|
* @param config OpenTelemetry configuration options.
|
|
255
257
|
*/
|
|
256
|
-
constructor(transport: Transport
|
|
258
|
+
constructor(transport: Transport<TProviderId>, config?: OpenTelemetryConfig);
|
|
257
259
|
/**
|
|
258
260
|
* Sends a single email message with OpenTelemetry observability.
|
|
259
261
|
*
|
|
@@ -261,7 +263,7 @@ declare class OpenTelemetryTransport implements Transport, AsyncDisposable {
|
|
|
261
263
|
* @param options Optional transport options including abort signal.
|
|
262
264
|
* @returns A promise that resolves to a receipt indicating success or failure.
|
|
263
265
|
*/
|
|
264
|
-
send(message: Message, options?: TransportOptions): Promise<Receipt
|
|
266
|
+
send(message: Message, options?: TransportOptions): Promise<Receipt<TProviderId>>;
|
|
265
267
|
/**
|
|
266
268
|
* Sends multiple email messages with OpenTelemetry observability.
|
|
267
269
|
*
|
|
@@ -269,7 +271,7 @@ declare class OpenTelemetryTransport implements Transport, AsyncDisposable {
|
|
|
269
271
|
* @param options Optional transport options including abort signal.
|
|
270
272
|
* @returns An async iterable that yields receipts for each sent message.
|
|
271
273
|
*/
|
|
272
|
-
sendMany(messages: Iterable<Message> | AsyncIterable<Message>, options?: TransportOptions): AsyncIterable<Receipt
|
|
274
|
+
sendMany(messages: Iterable<Message> | AsyncIterable<Message>, options?: TransportOptions): AsyncIterable<Receipt<TProviderId>>;
|
|
273
275
|
/**
|
|
274
276
|
* Cleanup resources if the wrapped transport supports Disposable or AsyncDisposable.
|
|
275
277
|
*/
|
|
@@ -278,6 +280,7 @@ declare class OpenTelemetryTransport implements Transport, AsyncDisposable {
|
|
|
278
280
|
private extractTransportVersion;
|
|
279
281
|
private extractNetworkAttributes;
|
|
280
282
|
private classifyError;
|
|
283
|
+
private classifyReceipt;
|
|
281
284
|
private classifyErrors;
|
|
282
285
|
private estimateMessageSize;
|
|
283
286
|
}
|
|
@@ -424,7 +427,7 @@ interface CreateOpenTelemetryTransportConfig extends Omit<OpenTelemetryConfig, "
|
|
|
424
427
|
*
|
|
425
428
|
* @since 0.2.0
|
|
426
429
|
*/
|
|
427
|
-
declare function createOpenTelemetryTransport(baseTransport: Transport
|
|
430
|
+
declare function createOpenTelemetryTransport<TProviderId extends string = string>(baseTransport: Transport<TProviderId>, config?: CreateOpenTelemetryTransportConfig): OpenTelemetryTransport<TProviderId>;
|
|
428
431
|
/**
|
|
429
432
|
* Creates a custom email attribute extractor function for OpenTelemetry
|
|
430
433
|
* spans and metrics.
|
package/dist/index.d.ts
CHANGED
|
@@ -162,16 +162,17 @@ interface ResolvedOpenTelemetryConfig {
|
|
|
162
162
|
* import { defaultErrorClassifier } from "@upyo/opentelemetry";
|
|
163
163
|
*
|
|
164
164
|
* console.log(defaultErrorClassifier(new Error("401 Unauthorized"))); // "auth"
|
|
165
|
-
* console.log(defaultErrorClassifier(new Error("Rate limit exceeded"))); // "
|
|
165
|
+
* console.log(defaultErrorClassifier(new Error("Rate limit exceeded"))); // "rate-limit"
|
|
166
166
|
* console.log(defaultErrorClassifier(new Error("Connection timeout"))); // "network"
|
|
167
167
|
* console.log(defaultErrorClassifier(new Error("Invalid email format"))); // "validation"
|
|
168
|
-
* console.log(defaultErrorClassifier(new Error("500 Internal Server Error"))); // "
|
|
168
|
+
* console.log(defaultErrorClassifier(new Error("500 Internal Server Error"))); // "server-error"
|
|
169
169
|
* console.log(defaultErrorClassifier(new Error("Something else"))); // "unknown"
|
|
170
170
|
* ```
|
|
171
171
|
*
|
|
172
172
|
* @param error The error to classify.
|
|
173
|
-
* @returns A string category such as `"auth"`, `"
|
|
174
|
-
* `"validation"`, `"
|
|
173
|
+
* @returns A string category such as `"auth"`, `"rate-limit"`, `"network"`,
|
|
174
|
+
* `"validation"`, `"service-unavailable"`, `"server-error"`, or
|
|
175
|
+
* `"unknown"`.
|
|
175
176
|
* @since 0.2.0
|
|
176
177
|
*/
|
|
177
178
|
declare function defaultErrorClassifier(error: unknown): string;
|
|
@@ -237,7 +238,8 @@ declare function defaultErrorClassifier(error: unknown): string;
|
|
|
237
238
|
*
|
|
238
239
|
* @since 0.2.0
|
|
239
240
|
*/
|
|
240
|
-
declare class OpenTelemetryTransport implements Transport
|
|
241
|
+
declare class OpenTelemetryTransport<TProviderId extends string = string> implements Transport<TProviderId>, AsyncDisposable {
|
|
242
|
+
readonly id: TProviderId;
|
|
241
243
|
/**
|
|
242
244
|
* The resolved OpenTelemetry configuration.
|
|
243
245
|
*/
|
|
@@ -253,7 +255,7 @@ declare class OpenTelemetryTransport implements Transport, AsyncDisposable {
|
|
|
253
255
|
* @param transport The base transport to wrap with observability.
|
|
254
256
|
* @param config OpenTelemetry configuration options.
|
|
255
257
|
*/
|
|
256
|
-
constructor(transport: Transport
|
|
258
|
+
constructor(transport: Transport<TProviderId>, config?: OpenTelemetryConfig);
|
|
257
259
|
/**
|
|
258
260
|
* Sends a single email message with OpenTelemetry observability.
|
|
259
261
|
*
|
|
@@ -261,7 +263,7 @@ declare class OpenTelemetryTransport implements Transport, AsyncDisposable {
|
|
|
261
263
|
* @param options Optional transport options including abort signal.
|
|
262
264
|
* @returns A promise that resolves to a receipt indicating success or failure.
|
|
263
265
|
*/
|
|
264
|
-
send(message: Message, options?: TransportOptions): Promise<Receipt
|
|
266
|
+
send(message: Message, options?: TransportOptions): Promise<Receipt<TProviderId>>;
|
|
265
267
|
/**
|
|
266
268
|
* Sends multiple email messages with OpenTelemetry observability.
|
|
267
269
|
*
|
|
@@ -269,7 +271,7 @@ declare class OpenTelemetryTransport implements Transport, AsyncDisposable {
|
|
|
269
271
|
* @param options Optional transport options including abort signal.
|
|
270
272
|
* @returns An async iterable that yields receipts for each sent message.
|
|
271
273
|
*/
|
|
272
|
-
sendMany(messages: Iterable<Message> | AsyncIterable<Message>, options?: TransportOptions): AsyncIterable<Receipt
|
|
274
|
+
sendMany(messages: Iterable<Message> | AsyncIterable<Message>, options?: TransportOptions): AsyncIterable<Receipt<TProviderId>>;
|
|
273
275
|
/**
|
|
274
276
|
* Cleanup resources if the wrapped transport supports Disposable or AsyncDisposable.
|
|
275
277
|
*/
|
|
@@ -278,6 +280,7 @@ declare class OpenTelemetryTransport implements Transport, AsyncDisposable {
|
|
|
278
280
|
private extractTransportVersion;
|
|
279
281
|
private extractNetworkAttributes;
|
|
280
282
|
private classifyError;
|
|
283
|
+
private classifyReceipt;
|
|
281
284
|
private classifyErrors;
|
|
282
285
|
private estimateMessageSize;
|
|
283
286
|
}
|
|
@@ -424,7 +427,7 @@ interface CreateOpenTelemetryTransportConfig extends Omit<OpenTelemetryConfig, "
|
|
|
424
427
|
*
|
|
425
428
|
* @since 0.2.0
|
|
426
429
|
*/
|
|
427
|
-
declare function createOpenTelemetryTransport(baseTransport: Transport
|
|
430
|
+
declare function createOpenTelemetryTransport<TProviderId extends string = string>(baseTransport: Transport<TProviderId>, config?: CreateOpenTelemetryTransportConfig): OpenTelemetryTransport<TProviderId>;
|
|
428
431
|
/**
|
|
429
432
|
* Creates a custom email attribute extractor function for OpenTelemetry
|
|
430
433
|
* spans and metrics.
|
package/dist/index.js
CHANGED
|
@@ -64,16 +64,17 @@ function createOpenTelemetryConfig(config = {}) {
|
|
|
64
64
|
* import { defaultErrorClassifier } from "@upyo/opentelemetry";
|
|
65
65
|
*
|
|
66
66
|
* console.log(defaultErrorClassifier(new Error("401 Unauthorized"))); // "auth"
|
|
67
|
-
* console.log(defaultErrorClassifier(new Error("Rate limit exceeded"))); // "
|
|
67
|
+
* console.log(defaultErrorClassifier(new Error("Rate limit exceeded"))); // "rate-limit"
|
|
68
68
|
* console.log(defaultErrorClassifier(new Error("Connection timeout"))); // "network"
|
|
69
69
|
* console.log(defaultErrorClassifier(new Error("Invalid email format"))); // "validation"
|
|
70
|
-
* console.log(defaultErrorClassifier(new Error("500 Internal Server Error"))); // "
|
|
70
|
+
* console.log(defaultErrorClassifier(new Error("500 Internal Server Error"))); // "server-error"
|
|
71
71
|
* console.log(defaultErrorClassifier(new Error("Something else"))); // "unknown"
|
|
72
72
|
* ```
|
|
73
73
|
*
|
|
74
74
|
* @param error The error to classify.
|
|
75
|
-
* @returns A string category such as `"auth"`, `"
|
|
76
|
-
* `"validation"`, `"
|
|
75
|
+
* @returns A string category such as `"auth"`, `"rate-limit"`, `"network"`,
|
|
76
|
+
* `"validation"`, `"service-unavailable"`, `"server-error"`, or
|
|
77
|
+
* `"unknown"`.
|
|
77
78
|
* @since 0.2.0
|
|
78
79
|
*/
|
|
79
80
|
function defaultErrorClassifier(error) {
|
|
@@ -81,11 +82,11 @@ function defaultErrorClassifier(error) {
|
|
|
81
82
|
const message = error.message.toLowerCase();
|
|
82
83
|
const name$1 = error.name.toLowerCase();
|
|
83
84
|
if (message.includes("auth") || message.includes("unauthorized") || message.includes("invalid api key") || message.includes("403")) return "auth";
|
|
84
|
-
if (message.includes("rate limit") || message.includes("429") || message.includes("quota exceeded") || message.includes("throttle")) return "
|
|
85
|
-
if (message.includes("500") || message.includes("502") || message.includes("504") || message.includes("internal server error")) return "
|
|
85
|
+
if (message.includes("rate limit") || message.includes("429") || message.includes("quota exceeded") || message.includes("throttle")) return "rate-limit";
|
|
86
|
+
if (message.includes("500") || message.includes("502") || message.includes("504") || message.includes("internal server error")) return "server-error";
|
|
86
87
|
if (name$1.includes("network") || message.includes("connect") || message.includes("timeout") || message.includes("dns") || name$1 === "aborterror") return "network";
|
|
87
88
|
if (message.includes("invalid") || message.includes("malformed") || message.includes("validation") || message.includes("400")) return "validation";
|
|
88
|
-
if (message.includes("503") || message.includes("service unavailable") || message.includes("temporarily unavailable")) return "
|
|
89
|
+
if (message.includes("503") || message.includes("service unavailable") || message.includes("temporarily unavailable")) return "service-unavailable";
|
|
89
90
|
}
|
|
90
91
|
return "unknown";
|
|
91
92
|
}
|
|
@@ -93,7 +94,7 @@ function defaultErrorClassifier(error) {
|
|
|
93
94
|
//#endregion
|
|
94
95
|
//#region package.json
|
|
95
96
|
var name = "@upyo/opentelemetry";
|
|
96
|
-
var version = "0.5.0
|
|
97
|
+
var version = "0.5.0";
|
|
97
98
|
var description = "OpenTelemetry observability transport for Upyo email library";
|
|
98
99
|
var keywords = [
|
|
99
100
|
"email",
|
|
@@ -150,7 +151,6 @@ var peerDependencies = {
|
|
|
150
151
|
"@upyo/core": "workspace:*"
|
|
151
152
|
};
|
|
152
153
|
var devDependencies = {
|
|
153
|
-
"@dotenvx/dotenvx": "catalog:",
|
|
154
154
|
"@opentelemetry/api": "catalog:",
|
|
155
155
|
"@opentelemetry/context-async-hooks": "^1.25.1",
|
|
156
156
|
"@opentelemetry/resources": "catalog:",
|
|
@@ -161,12 +161,8 @@ var devDependencies = {
|
|
|
161
161
|
"typescript": "catalog:"
|
|
162
162
|
};
|
|
163
163
|
var scripts = {
|
|
164
|
-
"
|
|
165
|
-
"
|
|
166
|
-
"prepublish": "tsdown",
|
|
167
|
-
"test": "tsdown && dotenvx run --ignore=MISSING_ENV_FILE -- node --experimental-transform-types --test",
|
|
168
|
-
"test:bun": "tsdown && bun test --timeout=30000 --env-file=.env",
|
|
169
|
-
"test:deno": "deno test --allow-env --allow-net --env-file=.env"
|
|
164
|
+
"prepack": "mise run --no-deps :build",
|
|
165
|
+
"prepublish": "mise run --no-deps :build"
|
|
170
166
|
};
|
|
171
167
|
var package_default = {
|
|
172
168
|
name,
|
|
@@ -650,6 +646,7 @@ var NoOpEmailSpan = class {
|
|
|
650
646
|
* @since 0.2.0
|
|
651
647
|
*/
|
|
652
648
|
var OpenTelemetryTransport = class {
|
|
649
|
+
id;
|
|
653
650
|
/**
|
|
654
651
|
* The resolved OpenTelemetry configuration.
|
|
655
652
|
*/
|
|
@@ -667,6 +664,7 @@ var OpenTelemetryTransport = class {
|
|
|
667
664
|
*/
|
|
668
665
|
constructor(transport, config = {}) {
|
|
669
666
|
this.wrappedTransport = transport;
|
|
667
|
+
this.id = transport.id;
|
|
670
668
|
this.config = createOpenTelemetryConfig(config);
|
|
671
669
|
this.transportName = this.extractTransportName(transport);
|
|
672
670
|
this.transportVersion = this.extractTransportVersion(transport);
|
|
@@ -696,7 +694,7 @@ var OpenTelemetryTransport = class {
|
|
|
696
694
|
span?.recordSuccess(receipt.messageId);
|
|
697
695
|
this.metricsCollector?.recordSendComplete(this.transportName, duration, true);
|
|
698
696
|
} else {
|
|
699
|
-
const errorCategory = this.
|
|
697
|
+
const errorCategory = this.classifyReceipt(receipt);
|
|
700
698
|
span?.recordFailure(receipt.errorMessages);
|
|
701
699
|
this.metricsCollector?.recordSendComplete(this.transportName, duration, false, errorCategory);
|
|
702
700
|
}
|
|
@@ -773,7 +771,8 @@ var OpenTelemetryTransport = class {
|
|
|
773
771
|
if (typeof this.wrappedTransport[Symbol.dispose] === "function") this.wrappedTransport[Symbol.dispose]();
|
|
774
772
|
}
|
|
775
773
|
extractTransportName(transport) {
|
|
776
|
-
|
|
774
|
+
if (typeof transport.id === "string" && transport.id !== "") return transport.id;
|
|
775
|
+
const constructorName = transport.constructor?.name;
|
|
777
776
|
if (constructorName && constructorName !== "Object") return constructorName.toLowerCase().replace("transport", "");
|
|
778
777
|
if ("config" in transport && transport.config && typeof transport.config === "object") {
|
|
779
778
|
if ("domain" in transport.config) return "mailgun";
|
|
@@ -816,6 +815,11 @@ var OpenTelemetryTransport = class {
|
|
|
816
815
|
const classifier = this.config.errorClassifier || defaultErrorClassifier;
|
|
817
816
|
return classifier(error);
|
|
818
817
|
}
|
|
818
|
+
classifyReceipt(receipt) {
|
|
819
|
+
const structuredCategory = receipt.errors?.[0]?.category;
|
|
820
|
+
if (structuredCategory != null) return structuredCategory;
|
|
821
|
+
return this.classifyErrors(receipt.errorMessages);
|
|
822
|
+
}
|
|
819
823
|
classifyErrors(errorMessages) {
|
|
820
824
|
if (errorMessages.length === 0) return "unknown";
|
|
821
825
|
const syntheticError = new Error(errorMessages[0]);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@upyo/opentelemetry",
|
|
3
|
-
"version": "0.5.0
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "OpenTelemetry observability transport for Upyo email library",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"email",
|
|
@@ -58,10 +58,9 @@
|
|
|
58
58
|
"sideEffects": false,
|
|
59
59
|
"peerDependencies": {
|
|
60
60
|
"@opentelemetry/api": "^1.9.0",
|
|
61
|
-
"@upyo/core": "0.5.0
|
|
61
|
+
"@upyo/core": "0.5.0"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
|
-
"@dotenvx/dotenvx": "^1.47.3",
|
|
65
64
|
"@opentelemetry/api": "^1.9.0",
|
|
66
65
|
"@opentelemetry/context-async-hooks": "^1.25.1",
|
|
67
66
|
"@opentelemetry/resources": "^1.25.1",
|
|
@@ -72,10 +71,6 @@
|
|
|
72
71
|
"typescript": "5.8.3"
|
|
73
72
|
},
|
|
74
73
|
"scripts": {
|
|
75
|
-
"
|
|
76
|
-
"prepublish": "tsdown",
|
|
77
|
-
"test": "tsdown && dotenvx run --ignore=MISSING_ENV_FILE -- node --experimental-transform-types --test",
|
|
78
|
-
"test:bun": "tsdown && bun test --timeout=30000 --env-file=.env",
|
|
79
|
-
"test:deno": "deno test --allow-env --allow-net --env-file=.env"
|
|
74
|
+
"prepublish": "mise run --no-deps :build"
|
|
80
75
|
}
|
|
81
76
|
}
|