Skip to content

Commit bf253b0

Browse files
test(cloudflare): use conventions in KV instrumentation
1 parent 1a91897 commit bf253b0

3 files changed

Lines changed: 84 additions & 52 deletions

File tree

‎dev-packages/cloudflare-integration-tests/suites/kv/test.ts‎

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,35 @@
1+
import {
2+
CACHE_HIT,
3+
CACHE_KEY,
4+
CACHE_OPERATION,
5+
DB_COLLECTION_NAME,
6+
DB_OPERATION_NAME,
7+
DB_SYSTEM_NAME,
8+
SENTRY_OP,
9+
SENTRY_ORIGIN,
10+
} from '@sentry/conventions/attributes';
11+
import { CACHE_GET, CACHE_PUT, CACHE_REMOVE } from '@sentry/conventions/op';
12+
import { CACHE_OPERATION_NAMES } from '@sentry/core';
113
import { expect, it } from 'vitest';
214
import { createRunner } from '../../runner';
315
import { getSpansFromEnvelope } from '../../spanUtils';
416

517
it('emits cache.get for a KV read with key and hit attributes', async ({ signal }) => {
618
const runner = createRunner(__dirname)
719
.expect(envelope => {
8-
const spans = getSpansFromEnvelope(envelope).filter(span => span.name === 'cache.get');
20+
const spans = getSpansFromEnvelope(envelope).filter(span => span.name === CACHE_GET);
921
expect(spans).toEqual(
1022
expect.arrayContaining([
1123
expect.objectContaining({
1224
attributes: expect.objectContaining({
13-
'sentry.op': { type: 'string', value: 'cache.get' },
14-
'sentry.origin': { type: 'string', value: 'auto.cache.cloudflare.kv' },
15-
'cache.operation': { type: 'string', value: 'get' },
16-
'cache.key': { type: 'string', value: 'get-key' },
17-
'cache.hit': { type: 'boolean', value: true },
18-
'db.operation.name': { type: 'string', value: 'get' },
19-
'db.collection.name': { type: 'string', value: 'MY_KV' },
20-
'db.system.name': { type: 'string', value: 'cloudflare-kv' },
25+
[SENTRY_OP]: { type: 'string', value: CACHE_GET },
26+
[SENTRY_ORIGIN]: { type: 'string', value: 'auto.cache.cloudflare.kv' },
27+
[CACHE_OPERATION]: { type: 'string', value: CACHE_OPERATION_NAMES[CACHE_GET] },
28+
[CACHE_KEY]: { type: 'string', value: 'get-key' },
29+
[CACHE_HIT]: { type: 'boolean', value: true },
30+
[DB_OPERATION_NAME]: { type: 'string', value: 'get' },
31+
[DB_COLLECTION_NAME]: { type: 'string', value: 'MY_KV' },
32+
[DB_SYSTEM_NAME]: { type: 'string', value: 'cloudflare-kv' },
2133
}),
2234
}),
2335
]),
@@ -33,15 +45,15 @@ it('emits cache.get for a bulk KV read with all keys in cache.key', async ({ sig
3345
const runner = createRunner(__dirname)
3446
.expect(envelope => {
3547
const spans = getSpansFromEnvelope(envelope).filter(
36-
span => span.name === 'cache.get' && span.attributes['db.operation.name']?.value === 'get',
48+
span => span.name === CACHE_GET && span.attributes[DB_OPERATION_NAME]?.value === 'get',
3749
);
3850

3951
expect(spans).toEqual(
4052
expect.arrayContaining([
4153
expect.objectContaining({
4254
attributes: expect.objectContaining({
43-
'cache.key': expect.objectContaining({ type: 'array' }),
44-
'cache.hit': { type: 'boolean', value: true },
55+
[CACHE_KEY]: expect.objectContaining({ type: 'array', value: expect.arrayContaining(['bulk-a', 'bulk-b']) }),
56+
[CACHE_HIT]: { type: 'boolean', value: true },
4557
}),
4658
}),
4759
]),
@@ -57,14 +69,14 @@ it('emits cache.get for getWithMetadata', async ({ signal }) => {
5769
const runner = createRunner(__dirname)
5870
.expect(envelope => {
5971
const spans = getSpansFromEnvelope(envelope).filter(
60-
span => span.name === 'cache.get' && span.attributes['db.operation.name']?.value === 'getWithMetadata',
72+
span => span.name === CACHE_GET && span.attributes[DB_OPERATION_NAME]?.value === 'getWithMetadata',
6173
);
6274

6375
expect(spans).toEqual([
6476
expect.objectContaining({
6577
attributes: expect.objectContaining({
66-
'cache.key': { type: 'string', value: 'metadata-key' },
67-
'cache.hit': { type: 'boolean', value: true },
78+
[CACHE_KEY]: { type: 'string', value: 'metadata-key' },
79+
[CACHE_HIT]: { type: 'boolean', value: true },
6880
}),
6981
}),
7082
]);
@@ -78,15 +90,15 @@ it('emits cache.get for getWithMetadata', async ({ signal }) => {
7890
it('emits cache.put for KV writes', async ({ signal }) => {
7991
const runner = createRunner(__dirname)
8092
.expect(envelope => {
81-
const spans = getSpansFromEnvelope(envelope).filter(span => span.name === 'cache.put');
93+
const spans = getSpansFromEnvelope(envelope).filter(span => span.name === CACHE_PUT);
8294
expect(spans).toEqual(
8395
expect.arrayContaining([
8496
expect.objectContaining({
8597
attributes: expect.objectContaining({
86-
'sentry.op': { type: 'string', value: 'cache.put' },
87-
'cache.operation': { type: 'string', value: 'put' },
88-
'cache.key': { type: 'string', value: 'put-key' },
89-
'db.operation.name': { type: 'string', value: 'put' },
98+
[SENTRY_OP]: { type: 'string', value: CACHE_PUT },
99+
[CACHE_OPERATION]: { type: 'string', value: CACHE_OPERATION_NAMES[CACHE_PUT] },
100+
[CACHE_KEY]: { type: 'string', value: 'put-key' },
101+
[DB_OPERATION_NAME]: { type: 'string', value: 'put' },
90102
}),
91103
}),
92104
]),
@@ -101,15 +113,15 @@ it('emits cache.put for KV writes', async ({ signal }) => {
101113
it('emits cache.remove for KV deletes', async ({ signal }) => {
102114
const runner = createRunner(__dirname)
103115
.expect(envelope => {
104-
const spans = getSpansFromEnvelope(envelope).filter(span => span.name === 'cache.remove');
116+
const spans = getSpansFromEnvelope(envelope).filter(span => span.name === CACHE_REMOVE);
105117
expect(spans).toEqual(
106118
expect.arrayContaining([
107119
expect.objectContaining({
108120
attributes: expect.objectContaining({
109-
'sentry.op': { type: 'string', value: 'cache.remove' },
110-
'cache.operation': { type: 'string', value: 'remove' },
111-
'cache.key': { type: 'string', value: 'delete-key' },
112-
'db.operation.name': { type: 'string', value: 'delete' },
121+
[SENTRY_OP]: { type: 'string', value: CACHE_REMOVE },
122+
[CACHE_OPERATION]: { type: 'string', value: CACHE_OPERATION_NAMES[CACHE_REMOVE] },
123+
[CACHE_KEY]: { type: 'string', value: 'delete-key' },
124+
[DB_OPERATION_NAME]: { type: 'string', value: 'delete' },
113125
}),
114126
}),
115127
]),
@@ -125,16 +137,16 @@ it('emits cache.get for KV list operations', async ({ signal }) => {
125137
const runner = createRunner(__dirname)
126138
.expect(envelope => {
127139
const spans = getSpansFromEnvelope(envelope).filter(
128-
span => span.name === 'cache.get' && span.attributes['db.operation.name']?.value === 'list',
140+
span => span.name === CACHE_GET && span.attributes[DB_OPERATION_NAME]?.value === 'list',
129141
);
130142

131143
expect(spans).toEqual(
132144
expect.arrayContaining([
133145
expect.objectContaining({
134146
attributes: expect.objectContaining({
135-
'sentry.op': { type: 'string', value: 'cache.get' },
136-
'cache.operation': { type: 'string', value: 'get' },
137-
'db.operation.name': { type: 'string', value: 'list' },
147+
[SENTRY_OP]: { type: 'string', value: CACHE_GET },
148+
[CACHE_OPERATION]: { type: 'string', value: CACHE_OPERATION_NAMES[CACHE_GET] },
149+
[DB_OPERATION_NAME]: { type: 'string', value: 'list' },
138150
}),
139151
}),
140152
]),

‎packages/cloudflare/src/instrumentations/worker/instrumentKV.ts‎

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
import type { KVNamespace } from '@cloudflare/workers-types';
2-
import { CACHE_HIT, CACHE_KEY, CACHE_OPERATION, SENTRY_OP, SENTRY_ORIGIN } from '@sentry/conventions/attributes';
2+
import {
3+
CACHE_HIT,
4+
CACHE_KEY,
5+
CACHE_OPERATION,
6+
DB_COLLECTION_NAME,
7+
DB_OPERATION_NAME,
8+
DB_SYSTEM_NAME,
9+
SENTRY_OP,
10+
SENTRY_ORIGIN,
11+
} from '@sentry/conventions/attributes';
312
import { CACHE_GET, CACHE_PUT, CACHE_REMOVE } from '@sentry/conventions/op';
413
import { CACHE_OPERATION_NAMES, getClient, hasSpanStreamingEnabled, isObjectLike, startSpan } from '@sentry/core';
514

@@ -42,9 +51,9 @@ function createSpanOptions(bindingName: string, operation: KVOperation, args: un
4251
[CACHE_OPERATION]: cacheOperationName,
4352
[SENTRY_ORIGIN]: ORIGIN,
4453
...(keys && keys.length > 0 && { [CACHE_KEY]: keys.length > 1 ? keys : keys[0] }),
45-
'db.operation.name': operation,
46-
'db.collection.name': bindingName,
47-
'db.system.name': 'cloudflare-kv',
54+
[DB_OPERATION_NAME]: operation,
55+
[DB_COLLECTION_NAME]: bindingName,
56+
[DB_SYSTEM_NAME]: 'cloudflare-kv',
4857
},
4958
};
5059
}

‎packages/cloudflare/test/instrumentations/worker/instrumentKV.test.ts‎

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
import type { KVNamespace } from '@cloudflare/workers-types';
2+
import {
3+
CACHE_KEY,
4+
CACHE_OPERATION,
5+
DB_COLLECTION_NAME,
6+
DB_OPERATION_NAME,
7+
DB_SYSTEM_NAME,
8+
SENTRY_OP,
9+
SENTRY_ORIGIN,
10+
} from '@sentry/conventions/attributes';
11+
import { CACHE_GET, CACHE_PUT, CACHE_REMOVE } from '@sentry/conventions/op';
212
import * as SentryCore from '@sentry/core';
13+
import { CACHE_OPERATION_NAMES } from '@sentry/core';
314
import { beforeEach, describe, expect, test, vi } from 'vitest';
415
import { instrumentKV } from '../../../src/instrumentations/worker/instrumentKV';
516

@@ -39,13 +50,13 @@ describe('instrumentKV', () => {
3950
expect(startSpanSpy).toHaveBeenCalledWith(
4051
expect.objectContaining({
4152
attributes: expect.objectContaining({
42-
'sentry.op': 'cache.get',
43-
'sentry.origin': 'auto.cache.cloudflare.kv',
44-
'cache.operation': 'get',
45-
'cache.key': 'test-key',
46-
'db.operation.name': 'get',
47-
'db.collection.name': 'MY_KV',
48-
'db.system.name': 'cloudflare-kv',
53+
[SENTRY_OP]: CACHE_GET,
54+
[SENTRY_ORIGIN]: 'auto.cache.cloudflare.kv',
55+
[CACHE_OPERATION]: CACHE_OPERATION_NAMES[CACHE_GET],
56+
[CACHE_KEY]: 'test-key',
57+
[DB_OPERATION_NAME]: 'get',
58+
[DB_COLLECTION_NAME]: 'MY_KV',
59+
[DB_SYSTEM_NAME]: 'cloudflare-kv',
4960
}),
5061
}),
5162
expect.any(Function),
@@ -66,7 +77,7 @@ describe('instrumentKV', () => {
6677
expect(startSpanSpy.mock.calls[0]?.[0]).toEqual(
6778
expect.objectContaining({
6879
attributes: expect.objectContaining({
69-
'cache.key': ['first', 'second'],
80+
[CACHE_KEY]: ['first', 'second'],
7081
}),
7182
}),
7283
);
@@ -82,9 +93,9 @@ describe('instrumentKV', () => {
8293
expect(startSpanSpy.mock.calls[0]?.[0]).toEqual(
8394
expect.objectContaining({
8495
attributes: expect.objectContaining({
85-
'sentry.op': 'cache.get',
86-
'cache.key': 'test-key',
87-
'db.operation.name': 'getWithMetadata',
96+
[SENTRY_OP]: CACHE_GET,
97+
[CACHE_KEY]: 'test-key',
98+
[DB_OPERATION_NAME]: 'getWithMetadata',
8899
}),
89100
}),
90101
);
@@ -102,26 +113,26 @@ describe('instrumentKV', () => {
102113
expect(startSpanSpy.mock.calls[0]?.[0]).toEqual(
103114
expect.objectContaining({
104115
attributes: expect.objectContaining({
105-
'sentry.op': 'cache.put',
106-
'cache.key': 'put-key',
107-
'db.operation.name': 'put',
116+
[SENTRY_OP]: CACHE_PUT,
117+
[CACHE_KEY]: 'put-key',
118+
[DB_OPERATION_NAME]: 'put',
108119
}),
109120
}),
110121
);
111122
expect(startSpanSpy.mock.calls[1]?.[0]).toEqual(
112123
expect.objectContaining({
113124
attributes: expect.objectContaining({
114-
'sentry.op': 'cache.remove',
115-
'cache.key': 'delete-key',
116-
'db.operation.name': 'delete',
125+
[SENTRY_OP]: CACHE_REMOVE,
126+
[CACHE_KEY]: 'delete-key',
127+
[DB_OPERATION_NAME]: 'delete',
117128
}),
118129
}),
119130
);
120131
expect(startSpanSpy.mock.calls[2]?.[0]).toEqual(
121132
expect.objectContaining({
122133
attributes: expect.objectContaining({
123-
'sentry.op': 'cache.get',
124-
'db.operation.name': 'list',
134+
[SENTRY_OP]: CACHE_GET,
135+
[DB_OPERATION_NAME]: 'list',
125136
}),
126137
}),
127138
);

0 commit comments

Comments
 (0)