autotel 4.1.0 → 4.2.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/package.json +1 -2
- package/src/attribute-redacting-processor.test.ts +0 -763
- package/src/attribute-redacting-processor.ts +0 -621
- package/src/attributes/attachers.ts +0 -161
- package/src/attributes/builders.ts +0 -529
- package/src/attributes/domains.ts +0 -42
- package/src/attributes/index.ts +0 -81
- package/src/attributes/registry.ts +0 -323
- package/src/attributes/types.ts +0 -211
- package/src/attributes/utils.ts +0 -64
- package/src/attributes/validators.ts +0 -266
- package/src/attributes.test.ts +0 -292
- package/src/auto.ts +0 -67
- package/src/autotel-logger.test.ts +0 -548
- package/src/autotel-logger.ts +0 -364
- package/src/baggage-span-processor.test.ts +0 -202
- package/src/baggage-span-processor.ts +0 -100
- package/src/business-baggage.test.ts +0 -500
- package/src/business-baggage.ts +0 -669
- package/src/circuit-breaker.test.ts +0 -341
- package/src/circuit-breaker.ts +0 -184
- package/src/config.test.ts +0 -94
- package/src/config.ts +0 -172
- package/src/correlated-events.test.ts +0 -151
- package/src/correlated-events.ts +0 -47
- package/src/correlation-id.test.ts +0 -163
- package/src/correlation-id.ts +0 -206
- package/src/db.test.ts +0 -252
- package/src/db.ts +0 -447
- package/src/decorators.test.ts +0 -153
- package/src/decorators.ts +0 -188
- package/src/define-event.test.ts +0 -41
- package/src/define-event.ts +0 -58
- package/src/devtools.ts +0 -60
- package/src/drain-pipeline.test.ts +0 -68
- package/src/drain-pipeline.ts +0 -199
- package/src/drain-toolkit.test.ts +0 -113
- package/src/drain-toolkit.ts +0 -129
- package/src/enricher-toolkit.test.ts +0 -67
- package/src/enricher-toolkit.ts +0 -79
- package/src/enrichers.test.ts +0 -150
- package/src/enrichers.ts +0 -145
- package/src/env-config.test.ts +0 -323
- package/src/env-config.ts +0 -309
- package/src/error-catalog.test.ts +0 -133
- package/src/error-catalog.ts +0 -262
- package/src/event-queue.test.ts +0 -864
- package/src/event-queue.ts +0 -699
- package/src/event-subscriber.ts +0 -262
- package/src/event-testing.ts +0 -197
- package/src/event.test.ts +0 -1104
- package/src/event.ts +0 -988
- package/src/events-config.ts +0 -235
- package/src/exporters.ts +0 -165
- package/src/filtering-span-processor.test.ts +0 -281
- package/src/filtering-span-processor.ts +0 -111
- package/src/flatten-attributes.test.ts +0 -76
- package/src/flatten-attributes.ts +0 -80
- package/src/functional.strict-types.typecheck.ts +0 -53
- package/src/functional.test.ts +0 -1464
- package/src/functional.ts +0 -2539
- package/src/functional.types.test.ts +0 -135
- package/src/hook.mjs +0 -15
- package/src/http.test.ts +0 -485
- package/src/http.ts +0 -424
- package/src/index.ts +0 -433
- package/src/init-auto-redactor.test.ts +0 -53
- package/src/init-redactor.test.ts +0 -8
- package/src/init.customization.test.ts +0 -665
- package/src/init.integrations.test.ts +0 -399
- package/src/init.openllmetry.test.ts +0 -194
- package/src/init.protocol.test.ts +0 -215
- package/src/init.ts +0 -2439
- package/src/instrumentation.test.ts +0 -108
- package/src/instrumentation.ts +0 -319
- package/src/logger.test.ts +0 -125
- package/src/logger.ts +0 -341
- package/src/messaging-adapters.test.ts +0 -595
- package/src/messaging-adapters.ts +0 -583
- package/src/messaging-testing.test.ts +0 -573
- package/src/messaging-testing.ts +0 -935
- package/src/messaging.test.ts +0 -1646
- package/src/messaging.ts +0 -2245
- package/src/metric-helpers.ts +0 -47
- package/src/metric-testing.ts +0 -197
- package/src/metric.ts +0 -446
- package/src/metrics.test.ts +0 -241
- package/src/node-require.ts +0 -123
- package/src/operation-context.ts +0 -93
- package/src/parse-error.test.ts +0 -73
- package/src/parse-error.ts +0 -112
- package/src/posthog-logs.test.ts +0 -115
- package/src/posthog-logs.ts +0 -77
- package/src/pretty-console-exporter.test.ts +0 -545
- package/src/pretty-console-exporter.ts +0 -413
- package/src/pretty-log-formatter.test.ts +0 -123
- package/src/pretty-log-formatter.ts +0 -210
- package/src/processors/canonical-log-line-processor.test.ts +0 -523
- package/src/processors/canonical-log-line-processor.ts +0 -396
- package/src/processors.ts +0 -152
- package/src/rate-limiter.test.ts +0 -199
- package/src/rate-limiter.ts +0 -98
- package/src/redact-values.test.ts +0 -90
- package/src/redact-values.ts +0 -34
- package/src/register.ts +0 -37
- package/src/request-logger.test.ts +0 -545
- package/src/request-logger.ts +0 -342
- package/src/sampling.test.ts +0 -1060
- package/src/sampling.ts +0 -737
- package/src/security-schema.test.ts +0 -45
- package/src/security-schema.ts +0 -107
- package/src/semantic-conventions.ts +0 -15
- package/src/semantic-helpers.test.ts +0 -226
- package/src/semantic-helpers.ts +0 -438
- package/src/shutdown.test.ts +0 -364
- package/src/shutdown.ts +0 -246
- package/src/span-name-normalizer.test.ts +0 -377
- package/src/span-name-normalizer.ts +0 -213
- package/src/stable-hash.ts +0 -27
- package/src/structured-error.test.ts +0 -191
- package/src/structured-error.ts +0 -157
- package/src/stub.integration.test.ts +0 -361
- package/src/tail-sampling-processor.test.ts +0 -230
- package/src/tail-sampling-processor.ts +0 -55
- package/src/test-span-collector.test.ts +0 -234
- package/src/test-span-collector.ts +0 -150
- package/src/testing.ts +0 -705
- package/src/trace-context.test.ts +0 -73
- package/src/trace-context.ts +0 -567
- package/src/trace-helpers.new.test.ts +0 -278
- package/src/trace-helpers.test.ts +0 -290
- package/src/trace-helpers.ts +0 -710
- package/src/trace-hybrid.test.ts +0 -42
- package/src/trace-hybrid.ts +0 -37
- package/src/tracer-provider.test.ts +0 -183
- package/src/tracer-provider.ts +0 -266
- package/src/track.test.ts +0 -154
- package/src/track.ts +0 -216
- package/src/validate.test.ts +0 -287
- package/src/validate.ts +0 -307
- package/src/validation-attributes.ts +0 -43
- package/src/validation.test.ts +0 -330
- package/src/validation.ts +0 -246
- package/src/variable-name-inference.test.ts +0 -178
- package/src/variable-name-inference.ts +0 -242
- package/src/webhook.test.ts +0 -649
- package/src/webhook.ts +0 -637
- package/src/workflow-distributed.test.ts +0 -786
- package/src/workflow-distributed.ts +0 -916
- package/src/workflow.async-safety.integration.test.ts +0 -345
- package/src/workflow.test.ts +0 -647
- package/src/workflow.ts +0 -810
- package/src/yaml-config.test.ts +0 -373
- package/src/yaml-config.ts +0 -351
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import {
|
|
3
|
-
SECURITY_ATTR,
|
|
4
|
-
SECURITY_DENIED_STATUSES,
|
|
5
|
-
SECURITY_SEVERITIES,
|
|
6
|
-
SECURITY_SEVERITY_RANK,
|
|
7
|
-
escalateSecuritySeverity,
|
|
8
|
-
parseSecuritySeverity,
|
|
9
|
-
securitySeverityAtLeast,
|
|
10
|
-
} from './security-schema';
|
|
11
|
-
|
|
12
|
-
describe('security-schema', () => {
|
|
13
|
-
it('ranks severities in declaration order', () => {
|
|
14
|
-
const ranks = SECURITY_SEVERITIES.map((s) => SECURITY_SEVERITY_RANK[s]);
|
|
15
|
-
expect(ranks).toEqual([0, 1, 2, 3]);
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
it('parses valid severities and falls back on garbage', () => {
|
|
19
|
-
expect(parseSecuritySeverity('critical')).toBe('critical');
|
|
20
|
-
expect(parseSecuritySeverity('warning')).toBe('warning');
|
|
21
|
-
expect(parseSecuritySeverity('CRITICAL')).toBe('info');
|
|
22
|
-
expect(parseSecuritySeverity(42)).toBe('info');
|
|
23
|
-
expect(parseSecuritySeverity(undefined)).toBe('info');
|
|
24
|
-
expect(parseSecuritySeverity(undefined, 'warning')).toBe('warning');
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it('compares severities against a threshold', () => {
|
|
28
|
-
expect(securitySeverityAtLeast('error', 'warning')).toBe(true);
|
|
29
|
-
expect(securitySeverityAtLeast('warning', 'warning')).toBe(true);
|
|
30
|
-
expect(securitySeverityAtLeast('info', 'warning')).toBe(false);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it('escalates to the floor but never downgrades', () => {
|
|
34
|
-
expect(escalateSecuritySeverity('info', 'error')).toBe('error');
|
|
35
|
-
expect(escalateSecuritySeverity('error', 'error')).toBe('error');
|
|
36
|
-
expect(escalateSecuritySeverity('critical', 'error')).toBe('critical');
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it('keeps the attribute contract stable', () => {
|
|
40
|
-
expect(SECURITY_ATTR.event).toBe('security.event');
|
|
41
|
-
expect(SECURITY_ATTR.severity).toBe('security.severity');
|
|
42
|
-
expect(SECURITY_ATTR.suspiciousRequest).toBe('security.suspicious_request');
|
|
43
|
-
expect(SECURITY_DENIED_STATUSES).toEqual([401, 403, 429]);
|
|
44
|
-
});
|
|
45
|
-
});
|
package/src/security-schema.ts
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Security telemetry wire schema — the single source of truth for the
|
|
3
|
-
* `security.*` span-attribute contract emitted by `autotel-audit`
|
|
4
|
-
* (`securityEvent()`, `withSecurity()`, `createSecuritySignalProcessor()`)
|
|
5
|
-
* and consumed by `autotel-subscribers`, `autotel-devtools`, and the
|
|
6
|
-
* `autotel security` CLI commands.
|
|
7
|
-
*
|
|
8
|
-
* Dependency-free and side-effect-free by design: safe to import from
|
|
9
|
-
* browser bundles (devtools widget) and anything else that only needs
|
|
10
|
-
* the constants, without pulling in the OpenTelemetry SDK.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
export type SecuritySeverity = 'info' | 'warning' | 'error' | 'critical';
|
|
14
|
-
|
|
15
|
-
/** All severities, lowest first. */
|
|
16
|
-
export const SECURITY_SEVERITIES: readonly SecuritySeverity[] = [
|
|
17
|
-
'info',
|
|
18
|
-
'warning',
|
|
19
|
-
'error',
|
|
20
|
-
'critical',
|
|
21
|
-
];
|
|
22
|
-
|
|
23
|
-
/** Numeric rank per severity for threshold comparisons. */
|
|
24
|
-
export const SECURITY_SEVERITY_RANK: Record<SecuritySeverity, number> = {
|
|
25
|
-
info: 0,
|
|
26
|
-
warning: 1,
|
|
27
|
-
error: 2,
|
|
28
|
-
critical: 3,
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Parse an untrusted value (span attribute, event payload field) into a
|
|
33
|
-
* severity, falling back when it is missing or malformed.
|
|
34
|
-
*/
|
|
35
|
-
export function parseSecuritySeverity(
|
|
36
|
-
value: unknown,
|
|
37
|
-
fallback: SecuritySeverity = 'info',
|
|
38
|
-
): SecuritySeverity {
|
|
39
|
-
return typeof value === 'string' && value in SECURITY_SEVERITY_RANK
|
|
40
|
-
? (value as SecuritySeverity)
|
|
41
|
-
: fallback;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/** `true` when `severity` meets or exceeds `min`. */
|
|
45
|
-
export function securitySeverityAtLeast(
|
|
46
|
-
severity: SecuritySeverity,
|
|
47
|
-
min: SecuritySeverity,
|
|
48
|
-
): boolean {
|
|
49
|
-
return SECURITY_SEVERITY_RANK[severity] >= SECURITY_SEVERITY_RANK[min];
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/** The higher-ranked of two severities (e.g. escalate failures to ≥ error). */
|
|
53
|
-
export function escalateSecuritySeverity(
|
|
54
|
-
severity: SecuritySeverity,
|
|
55
|
-
floor: SecuritySeverity,
|
|
56
|
-
): SecuritySeverity {
|
|
57
|
-
return SECURITY_SEVERITY_RANK[severity] >= SECURITY_SEVERITY_RANK[floor]
|
|
58
|
-
? severity
|
|
59
|
-
: floor;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Span attribute keys of the security schema. Emitters and consumers must
|
|
64
|
-
* reference these instead of re-typing the strings.
|
|
65
|
-
*/
|
|
66
|
-
export const SECURITY_ATTR = {
|
|
67
|
-
/** Marker set on every span carrying a security event. */
|
|
68
|
-
marker: 'autotel.security',
|
|
69
|
-
/** Set when the event was force-kept through tail sampling. */
|
|
70
|
-
forceKeep: 'autotel.security.force_keep',
|
|
71
|
-
event: 'security.event',
|
|
72
|
-
category: 'security.category',
|
|
73
|
-
outcome: 'security.outcome',
|
|
74
|
-
severity: 'security.severity',
|
|
75
|
-
actorId: 'security.actor_id',
|
|
76
|
-
targetType: 'security.target_type',
|
|
77
|
-
targetId: 'security.target_id',
|
|
78
|
-
tenantId: 'security.tenant_id',
|
|
79
|
-
reason: 'security.reason',
|
|
80
|
-
/** Custom metadata keys dropped because they looked credential-shaped. */
|
|
81
|
-
droppedKeys: 'security.dropped_keys',
|
|
82
|
-
/** Set by the signal processor on suspicious request paths. */
|
|
83
|
-
suspiciousRequest: 'security.suspicious_request',
|
|
84
|
-
/** Pattern name that flagged a suspicious request, e.g. `path_traversal`. */
|
|
85
|
-
signal: 'security.signal',
|
|
86
|
-
} as const;
|
|
87
|
-
|
|
88
|
-
/** Metric names emitted by the security instrumentation. */
|
|
89
|
-
export const SECURITY_METRICS = {
|
|
90
|
-
events: 'autotel.security.events',
|
|
91
|
-
httpSuspicious: 'autotel.security.http.suspicious',
|
|
92
|
-
httpDenied: 'autotel.security.http.denied',
|
|
93
|
-
anomaly: 'autotel.security.anomaly',
|
|
94
|
-
heartbeat: 'autotel.security.heartbeat',
|
|
95
|
-
} as const;
|
|
96
|
-
|
|
97
|
-
/** HTTP statuses counted as denied responses by default. */
|
|
98
|
-
export const SECURITY_DENIED_STATUSES: readonly number[] = [401, 403, 429];
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Span attributes carrying the HTTP response status, current semconv
|
|
102
|
-
* first, legacy fallback second.
|
|
103
|
-
*/
|
|
104
|
-
export const HTTP_STATUS_ATTRIBUTES: readonly string[] = [
|
|
105
|
-
'http.response.status_code',
|
|
106
|
-
'http.status_code',
|
|
107
|
-
];
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
HTTPAttributes,
|
|
3
|
-
ServiceAttributes,
|
|
4
|
-
URLAttributes,
|
|
5
|
-
} from './attributes/registry';
|
|
6
|
-
|
|
7
|
-
export { HTTPAttributes, ServiceAttributes, URLAttributes };
|
|
8
|
-
|
|
9
|
-
export function httpRequestHeaderAttribute(name: string): string {
|
|
10
|
-
return `http.request.header.${name.toLowerCase()}`;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function httpResponseHeaderAttribute(name: string): string {
|
|
14
|
-
return `http.response.header.${name.toLowerCase()}`;
|
|
15
|
-
}
|
|
@@ -1,226 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for semantic convention helpers
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { describe, it, expect, beforeEach } from 'vitest';
|
|
6
|
-
import { traceDB, traceHTTP, traceMessaging } from './semantic-helpers';
|
|
7
|
-
import { createTraceCollector } from './testing';
|
|
8
|
-
|
|
9
|
-
describe('Semantic Helpers', () => {
|
|
10
|
-
let collector: ReturnType<typeof createTraceCollector>;
|
|
11
|
-
|
|
12
|
-
beforeEach(() => {
|
|
13
|
-
collector = createTraceCollector();
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
// GenAI/LLM helpers (`traceLLM`) moved to the `autotel-genai` package.
|
|
17
|
-
|
|
18
|
-
describe('traceDB', () => {
|
|
19
|
-
it('should add DB semantic convention attributes', async () => {
|
|
20
|
-
const getUser = traceDB({
|
|
21
|
-
system: 'postgresql',
|
|
22
|
-
operation: 'SELECT',
|
|
23
|
-
database: 'app_db',
|
|
24
|
-
collection: 'users',
|
|
25
|
-
})((_ctx) => async (userId: string) => {
|
|
26
|
-
return { id: userId, name: 'John' };
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
await getUser('123');
|
|
30
|
-
|
|
31
|
-
const spans = collector.getSpans();
|
|
32
|
-
expect(spans).toHaveLength(1);
|
|
33
|
-
|
|
34
|
-
const span = spans[0];
|
|
35
|
-
expect(span.attributes['db.system']).toBe('postgresql');
|
|
36
|
-
expect(span.attributes['db.operation']).toBe('SELECT');
|
|
37
|
-
expect(span.attributes['db.name']).toBe('app_db');
|
|
38
|
-
expect(span.attributes['db.collection.name']).toBe('users');
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it('should work without optional attributes', async () => {
|
|
42
|
-
const query = traceDB({
|
|
43
|
-
system: 'mongodb',
|
|
44
|
-
})((_ctx) => async () => ({ results: [] }));
|
|
45
|
-
|
|
46
|
-
await query();
|
|
47
|
-
|
|
48
|
-
const spans = collector.getSpans();
|
|
49
|
-
const span = spans[0];
|
|
50
|
-
expect(span.attributes['db.system']).toBe('mongodb');
|
|
51
|
-
expect(span.attributes['db.operation']).toBeUndefined();
|
|
52
|
-
expect(span.attributes['db.name']).toBeUndefined();
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it('should support custom attributes', async () => {
|
|
56
|
-
const query = traceDB({
|
|
57
|
-
system: 'redis',
|
|
58
|
-
operation: 'GET',
|
|
59
|
-
attributes: {
|
|
60
|
-
'db.redis.ttl': 3600,
|
|
61
|
-
},
|
|
62
|
-
})((_ctx) => async (key: string) => `value-${key}`);
|
|
63
|
-
|
|
64
|
-
await query('test-key');
|
|
65
|
-
|
|
66
|
-
const spans = collector.getSpans();
|
|
67
|
-
const span = spans[0];
|
|
68
|
-
expect(span.attributes['db.system']).toBe('redis');
|
|
69
|
-
expect(span.attributes['db.redis.ttl']).toBe(3600);
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
describe('traceHTTP', () => {
|
|
74
|
-
it('should add HTTP semantic convention attributes', async () => {
|
|
75
|
-
const fetchUser = traceHTTP({
|
|
76
|
-
method: 'GET',
|
|
77
|
-
url: 'https://api.example.com/users/:id',
|
|
78
|
-
})((_ctx) => async (userId: string) => {
|
|
79
|
-
return { id: userId };
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
await fetchUser('123');
|
|
83
|
-
|
|
84
|
-
const spans = collector.getSpans();
|
|
85
|
-
expect(spans).toHaveLength(1);
|
|
86
|
-
|
|
87
|
-
const span = spans[0];
|
|
88
|
-
expect(span.attributes['http.request.method']).toBe('GET');
|
|
89
|
-
expect(span.attributes['url.full']).toBe(
|
|
90
|
-
'https://api.example.com/users/:id',
|
|
91
|
-
);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it('should work with only method', async () => {
|
|
95
|
-
const request = traceHTTP({
|
|
96
|
-
method: 'POST',
|
|
97
|
-
})((_ctx) => async (_data: object) => ({ success: true }));
|
|
98
|
-
|
|
99
|
-
await request({ test: 'data' });
|
|
100
|
-
|
|
101
|
-
const spans = collector.getSpans();
|
|
102
|
-
const span = spans[0];
|
|
103
|
-
expect(span.attributes['http.request.method']).toBe('POST');
|
|
104
|
-
expect(span.attributes['url.full']).toBeUndefined();
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
it('should work with only URL', async () => {
|
|
108
|
-
const request = traceHTTP({
|
|
109
|
-
url: 'https://api.example.com',
|
|
110
|
-
})((_ctx) => async () => ({ success: true }));
|
|
111
|
-
|
|
112
|
-
await request();
|
|
113
|
-
|
|
114
|
-
const spans = collector.getSpans();
|
|
115
|
-
const span = spans[0];
|
|
116
|
-
expect(span.attributes['url.full']).toBe('https://api.example.com');
|
|
117
|
-
expect(span.attributes['http.request.method']).toBeUndefined();
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
it('should support custom attributes', async () => {
|
|
121
|
-
const request = traceHTTP({
|
|
122
|
-
method: 'POST',
|
|
123
|
-
url: 'https://webhook.example.com',
|
|
124
|
-
attributes: {
|
|
125
|
-
'http.request.retry_count': 3,
|
|
126
|
-
'http.request.timeout': 5000,
|
|
127
|
-
},
|
|
128
|
-
})((_ctx) => async () => ({ success: true }));
|
|
129
|
-
|
|
130
|
-
await request();
|
|
131
|
-
|
|
132
|
-
const spans = collector.getSpans();
|
|
133
|
-
const span = spans[0];
|
|
134
|
-
expect(span.attributes['http.request.retry_count']).toBe(3);
|
|
135
|
-
expect(span.attributes['http.request.timeout']).toBe(5000);
|
|
136
|
-
});
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
describe('traceMessaging', () => {
|
|
140
|
-
it('should add Messaging semantic convention attributes', async () => {
|
|
141
|
-
const publishEvent = traceMessaging({
|
|
142
|
-
system: 'kafka',
|
|
143
|
-
operation: 'publish',
|
|
144
|
-
destination: 'user-events',
|
|
145
|
-
})((_ctx) => async (_event: object) => {
|
|
146
|
-
return { messageId: '123' };
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
await publishEvent({ type: 'user.created' });
|
|
150
|
-
|
|
151
|
-
const spans = collector.getSpans();
|
|
152
|
-
expect(spans).toHaveLength(1);
|
|
153
|
-
|
|
154
|
-
const span = spans[0];
|
|
155
|
-
expect(span.attributes['messaging.system']).toBe('kafka');
|
|
156
|
-
expect(span.attributes['messaging.operation']).toBe('publish');
|
|
157
|
-
expect(span.attributes['messaging.destination.name']).toBe('user-events');
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
it('should work with minimal config', async () => {
|
|
161
|
-
const sendMessage = traceMessaging({
|
|
162
|
-
system: 'rabbitmq',
|
|
163
|
-
})((_ctx) => async () => ({ sent: true }));
|
|
164
|
-
|
|
165
|
-
await sendMessage();
|
|
166
|
-
|
|
167
|
-
const spans = collector.getSpans();
|
|
168
|
-
const span = spans[0];
|
|
169
|
-
expect(span.attributes['messaging.system']).toBe('rabbitmq');
|
|
170
|
-
expect(span.attributes['messaging.operation']).toBeUndefined();
|
|
171
|
-
expect(span.attributes['messaging.destination.name']).toBeUndefined();
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
it('should support receive operation', async () => {
|
|
175
|
-
const consumeMessage = traceMessaging({
|
|
176
|
-
system: 'sqs',
|
|
177
|
-
operation: 'receive',
|
|
178
|
-
destination: 'notifications',
|
|
179
|
-
})((_ctx) => async () => ({ messages: [] }));
|
|
180
|
-
|
|
181
|
-
await consumeMessage();
|
|
182
|
-
|
|
183
|
-
const spans = collector.getSpans();
|
|
184
|
-
const span = spans[0];
|
|
185
|
-
expect(span.attributes['messaging.operation']).toBe('receive');
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
it('should support custom attributes', async () => {
|
|
189
|
-
const publishBatch = traceMessaging({
|
|
190
|
-
system: 'aws_sqs',
|
|
191
|
-
operation: 'publish',
|
|
192
|
-
destination: 'orders',
|
|
193
|
-
attributes: {
|
|
194
|
-
'messaging.batch.message_count': 10,
|
|
195
|
-
'messaging.kafka.partition': 0,
|
|
196
|
-
},
|
|
197
|
-
})((_ctx) => async () => ({ success: true }));
|
|
198
|
-
|
|
199
|
-
await publishBatch();
|
|
200
|
-
|
|
201
|
-
const spans = collector.getSpans();
|
|
202
|
-
const span = spans[0];
|
|
203
|
-
expect(span.attributes['messaging.batch.message_count']).toBe(10);
|
|
204
|
-
expect(span.attributes['messaging.kafka.partition']).toBe(0);
|
|
205
|
-
});
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
describe('Attribute merging', () => {
|
|
209
|
-
it('should allow custom attributes to override semantic defaults', async () => {
|
|
210
|
-
const fn = traceDB({
|
|
211
|
-
system: 'postgresql',
|
|
212
|
-
operation: 'SELECT',
|
|
213
|
-
attributes: {
|
|
214
|
-
'db.operation': 'CUSTOM_OPERATION', // Override default
|
|
215
|
-
},
|
|
216
|
-
})((_ctx) => async () => ({ rows: [] }));
|
|
217
|
-
|
|
218
|
-
await fn();
|
|
219
|
-
|
|
220
|
-
const spans = collector.getSpans();
|
|
221
|
-
const span = spans[0];
|
|
222
|
-
// Custom attribute should win
|
|
223
|
-
expect(span.attributes['db.operation']).toBe('CUSTOM_OPERATION');
|
|
224
|
-
});
|
|
225
|
-
});
|
|
226
|
-
});
|