Skip to content

Commit 2c7da30

Browse files
committed
feat: add OpenTelemetry and cache tracing
1 parent 5eee5af commit 2c7da30

File tree

5 files changed

+65
-0
lines changed

5 files changed

+65
-0
lines changed

packages/utils/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@
4949
"@aws-sdk/client-s3": "^3.828.0",
5050
"@chialab/isomorphic-dom": "workspace:*",
5151
"@heyputer/kv.js": "fquffio/kv.js#fix/strict-mode",
52+
"@opentelemetry/api": "^1.9.0",
53+
"@opentelemetry/semantic-conventions": "^1.36.0",
5254
"cookie": "^1.0.2",
5355
"html-entities": "^2.6.0",
5456
"pino": "^9.5.0",

packages/utils/src/lib/server/cache/base.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import type { JitterFn, JitterMode } from '../../utils/misc.js';
22
import type { StorageReadWriter } from '../storage.js';
3+
import { trace, ATTR_PEER_SERVICE } from '../telemetry.js';
4+
import { SpanKind } from '@opentelemetry/api';
35

46
/**
57
* Base class for caching.
@@ -75,6 +77,7 @@ export abstract class BaseCache<V> implements StorageReadWriter<V> {
7577
ttl?: number | undefined,
7678
jitter?: JitterMode | JitterFn | undefined,
7779
): Promise<V | undefined>;
80+
@trace({ kind: SpanKind.CLIENT, attributes: { [ATTR_PEER_SERVICE]: 'cache' } })
7881
public async remember(
7982
key: string,
8083
callback: () => PromiseLike<V | undefined>,
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import api, { type Span, type SpanOptions, SpanStatusCode } from '@opentelemetry/api';
2+
3+
/**
4+
* Replaces deprecated SEMATTRS_PEER_SERVICE attribute.
5+
* See {@link https://github.com/open-telemetry/opentelemetry-js/blob/main/semantic-conventions/README.md#unstable-semconv}.
6+
*/
7+
export const ATTR_PEER_SERVICE = 'peer.service' as const;
8+
9+
export const tracer = api.trace.getTracer('@chialab/sveltekit-utils');
10+
11+
/**
12+
* Decorator to trace a method or function by wrapping it in a new active span.
13+
*
14+
* @param options Span options
15+
*/
16+
export const trace =
17+
(options: SpanOptions = {}) =>
18+
(_: any, method: PropertyKey, descriptor: PropertyDescriptor) => ({
19+
...descriptor,
20+
value(...args: any[]) {
21+
return tracer.startActiveSpan(
22+
[this?.constructor?.name, method].filter(Boolean).join('.'),
23+
options,
24+
async (span: Span) => {
25+
try {
26+
// Wait for the wrapped function to end before closing the span and returning
27+
return await descriptor.value.call(this, ...args);
28+
} catch (e) {
29+
span.setStatus({ code: SpanStatusCode.ERROR });
30+
if (e instanceof Error) {
31+
span.recordException(e);
32+
}
33+
34+
throw e;
35+
} finally {
36+
span.end();
37+
}
38+
},
39+
);
40+
},
41+
});

packages/utils/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"allowJs": true,
55
"checkJs": true,
66
"esModuleInterop": true,
7+
"experimentalDecorators": true,
78
"forceConsistentCasingInFileNames": true,
89
"moduleResolution": "Bundler",
910
"resolveJsonModule": true,

pnpm-lock.yaml

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)