observability-toolkit 1.8.4 → 1.8.5
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/dist/backends/local-jsonl-boolean-search.test.js +8 -8
- package/dist/backends/local-jsonl-boolean-search.test.js.map +1 -1
- package/dist/backends/local-jsonl-cache.test.d.ts +2 -0
- package/dist/backends/local-jsonl-cache.test.d.ts.map +1 -0
- package/dist/backends/local-jsonl-cache.test.js +295 -0
- package/dist/backends/local-jsonl-cache.test.js.map +1 -0
- package/dist/backends/local-jsonl-circuit-breaker.test.d.ts +2 -0
- package/dist/backends/local-jsonl-circuit-breaker.test.d.ts.map +1 -0
- package/dist/backends/local-jsonl-circuit-breaker.test.js +180 -0
- package/dist/backends/local-jsonl-circuit-breaker.test.js.map +1 -0
- package/dist/backends/local-jsonl-export.test.d.ts +2 -0
- package/dist/backends/local-jsonl-export.test.d.ts.map +1 -0
- package/dist/backends/local-jsonl-export.test.js +704 -0
- package/dist/backends/local-jsonl-export.test.js.map +1 -0
- package/dist/backends/local-jsonl-index.test.d.ts +2 -0
- package/dist/backends/local-jsonl-index.test.d.ts.map +1 -0
- package/dist/backends/local-jsonl-index.test.js +554 -0
- package/dist/backends/local-jsonl-index.test.js.map +1 -0
- package/dist/backends/local-jsonl-logs.test.js +52 -43
- package/dist/backends/local-jsonl-logs.test.js.map +1 -1
- package/dist/backends/local-jsonl-metrics.test.d.ts +2 -0
- package/dist/backends/local-jsonl-metrics.test.d.ts.map +1 -0
- package/dist/backends/local-jsonl-metrics.test.js +876 -0
- package/dist/backends/local-jsonl-metrics.test.js.map +1 -0
- package/dist/backends/local-jsonl-traces.test.js +89 -83
- package/dist/backends/local-jsonl-traces.test.js.map +1 -1
- package/dist/backends/local-jsonl.d.ts +9 -0
- package/dist/backends/local-jsonl.d.ts.map +1 -1
- package/dist/backends/local-jsonl.js +348 -227
- package/dist/backends/local-jsonl.js.map +1 -1
- package/dist/backends/signoz-api-circuit-breaker.test.d.ts +6 -0
- package/dist/backends/signoz-api-circuit-breaker.test.d.ts.map +1 -0
- package/dist/backends/signoz-api-circuit-breaker.test.js +548 -0
- package/dist/backends/signoz-api-circuit-breaker.test.js.map +1 -0
- package/dist/backends/signoz-api-rate-limiter.test.d.ts +6 -0
- package/dist/backends/signoz-api-rate-limiter.test.d.ts.map +1 -0
- package/dist/backends/signoz-api-rate-limiter.test.js +389 -0
- package/dist/backends/signoz-api-rate-limiter.test.js.map +1 -0
- package/dist/backends/signoz-api-ssrf.test.d.ts +6 -0
- package/dist/backends/signoz-api-ssrf.test.d.ts.map +1 -0
- package/dist/backends/signoz-api-ssrf.test.js +216 -0
- package/dist/backends/signoz-api-ssrf.test.js.map +1 -0
- package/dist/backends/signoz-api-test-helpers.d.ts +80 -0
- package/dist/backends/signoz-api-test-helpers.d.ts.map +1 -0
- package/dist/backends/signoz-api-test-helpers.js +79 -0
- package/dist/backends/signoz-api-test-helpers.js.map +1 -0
- package/dist/backends/signoz-api.d.ts +16 -0
- package/dist/backends/signoz-api.d.ts.map +1 -1
- package/dist/backends/signoz-api.js +71 -9
- package/dist/backends/signoz-api.js.map +1 -1
- package/dist/backends/signoz-api.test.d.ts +9 -0
- package/dist/backends/signoz-api.test.d.ts.map +1 -1
- package/dist/backends/signoz-api.test.js +14 -1027
- package/dist/backends/signoz-api.test.js.map +1 -1
- package/dist/lib/cache.d.ts +47 -1
- package/dist/lib/cache.d.ts.map +1 -1
- package/dist/lib/cache.js +40 -3
- package/dist/lib/cache.js.map +1 -1
- package/dist/lib/circuit-breaker.d.ts +83 -0
- package/dist/lib/circuit-breaker.d.ts.map +1 -0
- package/dist/lib/circuit-breaker.js +125 -0
- package/dist/lib/circuit-breaker.js.map +1 -0
- package/dist/lib/circuit-breaker.test.d.ts +2 -0
- package/dist/lib/circuit-breaker.test.d.ts.map +1 -0
- package/dist/lib/circuit-breaker.test.js +263 -0
- package/dist/lib/circuit-breaker.test.js.map +1 -0
- package/dist/lib/constants-symlink.test.d.ts +12 -0
- package/dist/lib/constants-symlink.test.d.ts.map +1 -0
- package/dist/lib/constants-symlink.test.js +357 -0
- package/dist/lib/constants-symlink.test.js.map +1 -0
- package/dist/lib/edge-cases.test.js +17 -17
- package/dist/lib/edge-cases.test.js.map +1 -1
- package/dist/lib/error-sanitizer.d.ts.map +1 -1
- package/dist/lib/error-sanitizer.js +29 -3
- package/dist/lib/error-sanitizer.js.map +1 -1
- package/dist/lib/error-sanitizer.test.js +159 -0
- package/dist/lib/error-sanitizer.test.js.map +1 -1
- package/dist/lib/error-types.d.ts +54 -0
- package/dist/lib/error-types.d.ts.map +1 -0
- package/dist/lib/error-types.js +154 -0
- package/dist/lib/error-types.js.map +1 -0
- package/dist/lib/error-types.test.d.ts +2 -0
- package/dist/lib/error-types.test.d.ts.map +1 -0
- package/dist/lib/error-types.test.js +196 -0
- package/dist/lib/error-types.test.js.map +1 -0
- package/dist/lib/indexer.test.js +27 -27
- package/dist/lib/indexer.test.js.map +1 -1
- package/dist/lib/input-validator.d.ts +12 -0
- package/dist/lib/input-validator.d.ts.map +1 -1
- package/dist/lib/input-validator.fuzz.test.d.ts +12 -0
- package/dist/lib/input-validator.fuzz.test.d.ts.map +1 -0
- package/dist/lib/input-validator.fuzz.test.js +290 -0
- package/dist/lib/input-validator.fuzz.test.js.map +1 -0
- package/dist/lib/input-validator.js +57 -3
- package/dist/lib/input-validator.js.map +1 -1
- package/dist/lib/input-validator.test.js +129 -1
- package/dist/lib/input-validator.test.js.map +1 -1
- package/dist/lib/logger.d.ts +46 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +81 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/logger.test.d.ts +2 -0
- package/dist/lib/logger.test.d.ts.map +1 -0
- package/dist/lib/logger.test.js +122 -0
- package/dist/lib/logger.test.js.map +1 -0
- package/dist/lib/server-utils.d.ts +8 -0
- package/dist/lib/server-utils.d.ts.map +1 -1
- package/dist/lib/server-utils.js +34 -2
- package/dist/lib/server-utils.js.map +1 -1
- package/dist/lib/shared-schemas.d.ts +22 -0
- package/dist/lib/shared-schemas.d.ts.map +1 -1
- package/dist/lib/shared-schemas.js +22 -0
- package/dist/lib/shared-schemas.js.map +1 -1
- package/dist/lib/toon-encoder.d.ts +7 -2
- package/dist/lib/toon-encoder.d.ts.map +1 -1
- package/dist/lib/toon-encoder.js +21 -6
- package/dist/lib/toon-encoder.js.map +1 -1
- package/dist/lib/toon-encoder.test.d.ts +5 -0
- package/dist/lib/toon-encoder.test.d.ts.map +1 -0
- package/dist/lib/toon-encoder.test.js +85 -0
- package/dist/lib/toon-encoder.test.js.map +1 -0
- package/dist/server.js +2 -0
- package/dist/server.js.map +1 -1
- package/dist/server.test.js +30 -0
- package/dist/server.test.js.map +1 -1
- package/dist/test-helpers/env-utils.d.ts +22 -0
- package/dist/test-helpers/env-utils.d.ts.map +1 -1
- package/dist/test-helpers/env-utils.js +38 -0
- package/dist/test-helpers/env-utils.js.map +1 -1
- package/dist/test-helpers/fuzz-generators.d.ts +58 -0
- package/dist/test-helpers/fuzz-generators.d.ts.map +1 -0
- package/dist/test-helpers/fuzz-generators.js +216 -0
- package/dist/test-helpers/fuzz-generators.js.map +1 -0
- package/dist/test-helpers/index.d.ts +1 -0
- package/dist/test-helpers/index.d.ts.map +1 -1
- package/dist/test-helpers/index.js +2 -0
- package/dist/test-helpers/index.js.map +1 -1
- package/dist/test-helpers/memfs-utils.d.ts +181 -0
- package/dist/test-helpers/memfs-utils.d.ts.map +1 -0
- package/dist/test-helpers/memfs-utils.js +292 -0
- package/dist/test-helpers/memfs-utils.js.map +1 -0
- package/dist/test-helpers/memfs-utils.test.d.ts +5 -0
- package/dist/test-helpers/memfs-utils.test.d.ts.map +1 -0
- package/dist/test-helpers/memfs-utils.test.js +338 -0
- package/dist/test-helpers/memfs-utils.test.js.map +1 -0
- package/dist/test-helpers/race-condition-helpers.d.ts +85 -0
- package/dist/test-helpers/race-condition-helpers.d.ts.map +1 -0
- package/dist/test-helpers/race-condition-helpers.js +279 -0
- package/dist/test-helpers/race-condition-helpers.js.map +1 -0
- package/dist/test-helpers/test-data-builders.d.ts +40 -3
- package/dist/test-helpers/test-data-builders.d.ts.map +1 -1
- package/dist/test-helpers/test-data-builders.js +54 -5
- package/dist/test-helpers/test-data-builders.js.map +1 -1
- package/dist/test-helpers/tool-validators.d.ts.map +1 -1
- package/dist/test-helpers/tool-validators.js +16 -1
- package/dist/test-helpers/tool-validators.js.map +1 -1
- package/dist/tools/query-evaluations.d.ts.map +1 -1
- package/dist/tools/query-evaluations.js +16 -2
- package/dist/tools/query-evaluations.js.map +1 -1
- package/dist/tools/query-evaluations.test.js +53 -46
- package/dist/tools/query-evaluations.test.js.map +1 -1
- package/dist/tools/query-llm-events.test.js +6 -3
- package/dist/tools/query-llm-events.test.js.map +1 -1
- package/package.json +2 -1
|
@@ -2,7 +2,7 @@ import { describe, it, before, after, beforeEach } from 'node:test';
|
|
|
2
2
|
import * as assert from 'node:assert';
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
import { LocalJsonlBackend } from './local-jsonl.js';
|
|
5
|
-
import { getSharedTempDir, clearTempDir, removeSharedTempDir,
|
|
5
|
+
import { getSharedTempDir, clearTempDir, removeSharedTempDir, writeJsonlFileAsync, getTestDate } from '../test-helpers/file-utils.js';
|
|
6
6
|
describe('LocalJsonlBackend Boolean Search', () => {
|
|
7
7
|
let tempDir;
|
|
8
8
|
let backend;
|
|
@@ -25,7 +25,7 @@ describe('LocalJsonlBackend Boolean Search', () => {
|
|
|
25
25
|
{ timestamp: '2026-01-28T10:02:00Z', body: 'Connection reset by peer' },
|
|
26
26
|
{ timestamp: '2026-01-28T10:03:00Z', body: 'Timeout occurred during connection' },
|
|
27
27
|
];
|
|
28
|
-
|
|
28
|
+
await writeJsonlFileAsync(path.join(tempDir, `logs-${today}.jsonl`), mockLogs);
|
|
29
29
|
const results = await backend.queryLogs({
|
|
30
30
|
searchTerms: ['connection', 'timeout'],
|
|
31
31
|
searchOperator: 'AND',
|
|
@@ -42,7 +42,7 @@ describe('LocalJsonlBackend Boolean Search', () => {
|
|
|
42
42
|
{ timestamp: '2026-01-28T10:02:00Z', body: 'Authentication error' },
|
|
43
43
|
{ timestamp: '2026-01-28T10:03:00Z', body: 'Timeout occurred' },
|
|
44
44
|
];
|
|
45
|
-
|
|
45
|
+
await writeJsonlFileAsync(path.join(tempDir, `logs-${today}.jsonl`), mockLogs);
|
|
46
46
|
const results = await backend.queryLogs({
|
|
47
47
|
searchTerms: ['connection', 'timeout'],
|
|
48
48
|
searchOperator: 'OR',
|
|
@@ -59,7 +59,7 @@ describe('LocalJsonlBackend Boolean Search', () => {
|
|
|
59
59
|
{ timestamp: '2026-01-28T10:02:00Z', body: 'Database query successful' },
|
|
60
60
|
{ timestamp: '2026-01-28T10:03:00Z', body: 'Connection error in database' },
|
|
61
61
|
];
|
|
62
|
-
|
|
62
|
+
await writeJsonlFileAsync(path.join(tempDir, `logs-${today}.jsonl`), mockLogs);
|
|
63
63
|
// searchOperator defaults to 'AND'
|
|
64
64
|
const results = await backend.queryLogs({
|
|
65
65
|
searchTerms: ['error', 'database'],
|
|
@@ -75,7 +75,7 @@ describe('LocalJsonlBackend Boolean Search', () => {
|
|
|
75
75
|
{ timestamp: '2026-01-28T10:01:00Z', body: 'Warning: Process started' },
|
|
76
76
|
{ timestamp: '2026-01-28T10:02:00Z', body: 'connection failed with error' },
|
|
77
77
|
];
|
|
78
|
-
|
|
78
|
+
await writeJsonlFileAsync(path.join(tempDir, `logs-${today}.jsonl`), mockLogs);
|
|
79
79
|
const results = await backend.queryLogs({
|
|
80
80
|
searchTerms: ['ERROR', 'FAILED'],
|
|
81
81
|
searchOperator: 'AND',
|
|
@@ -88,7 +88,7 @@ describe('LocalJsonlBackend Boolean Search', () => {
|
|
|
88
88
|
{ timestamp: '2026-01-28T10:00:00Z', body: 'Log message 1' },
|
|
89
89
|
{ timestamp: '2026-01-28T10:01:00Z', body: 'Log message 2' },
|
|
90
90
|
];
|
|
91
|
-
|
|
91
|
+
await writeJsonlFileAsync(path.join(tempDir, `logs-${today}.jsonl`), mockLogs);
|
|
92
92
|
// Empty array should not filter anything
|
|
93
93
|
const results = await backend.queryLogs({
|
|
94
94
|
searchTerms: [],
|
|
@@ -103,7 +103,7 @@ describe('LocalJsonlBackend Boolean Search', () => {
|
|
|
103
103
|
{ timestamp: '2026-01-28T10:02:00Z', body: 'Database error timeout' },
|
|
104
104
|
{ timestamp: '2026-01-28T10:03:00Z', body: 'Connection established' },
|
|
105
105
|
];
|
|
106
|
-
|
|
106
|
+
await writeJsonlFileAsync(path.join(tempDir, `logs-${today}.jsonl`), mockLogs);
|
|
107
107
|
// Both single search and searchTerms should apply
|
|
108
108
|
const results = await backend.queryLogs({
|
|
109
109
|
search: 'connection',
|
|
@@ -122,7 +122,7 @@ describe('LocalJsonlBackend Boolean Search', () => {
|
|
|
122
122
|
{ timestamp: '2026-01-28T10:01:00Z', body: 'Warning: Process started' },
|
|
123
123
|
{ timestamp: '2026-01-28T10:02:00Z', body: 'Error: Connection failed' },
|
|
124
124
|
];
|
|
125
|
-
|
|
125
|
+
await writeJsonlFileAsync(path.join(tempDir, `logs-${today}.jsonl`), mockLogs);
|
|
126
126
|
const results = await backend.queryLogs({
|
|
127
127
|
searchTerms: ['error'],
|
|
128
128
|
searchOperator: 'AND',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-jsonl-boolean-search.test.js","sourceRoot":"","sources":["../../src/backends/local-jsonl-boolean-search.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACpE,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,mBAAmB,EAAE,
|
|
1
|
+
{"version":3,"file":"local-jsonl-boolean-search.test.js","sourceRoot":"","sources":["../../src/backends/local-jsonl-boolean-search.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-jsonl-cache.test.d.ts","sourceRoot":"","sources":["../../src/backends/local-jsonl-cache.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import { describe, it, before, after, beforeEach } from 'node:test';
|
|
2
|
+
import * as assert from 'node:assert';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import { LocalJsonlBackend } from './local-jsonl.js';
|
|
5
|
+
import { buildAndWriteIndex } from '../lib/indexer.js';
|
|
6
|
+
import { getSharedTempDir, clearTempDir, removeSharedTempDir, writeJsonlFileAsync, getTestDate } from '../test-helpers/file-utils.js';
|
|
7
|
+
describe('QueryCache', () => {
|
|
8
|
+
let tempDir;
|
|
9
|
+
let backend;
|
|
10
|
+
before(() => {
|
|
11
|
+
tempDir = getSharedTempDir('QueryCache');
|
|
12
|
+
});
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
clearTempDir(tempDir);
|
|
15
|
+
backend = new LocalJsonlBackend(tempDir);
|
|
16
|
+
});
|
|
17
|
+
after(() => {
|
|
18
|
+
removeSharedTempDir('QueryCache');
|
|
19
|
+
});
|
|
20
|
+
describe('caching behavior', () => {
|
|
21
|
+
it('should return cached results on second query with same options', async () => {
|
|
22
|
+
const today = getTestDate();
|
|
23
|
+
const mockSpans = [
|
|
24
|
+
{ traceId: 'cache-test-1', spanId: 'span1', name: 'test-op', startTime: [1700000000, 0] },
|
|
25
|
+
];
|
|
26
|
+
await writeJsonlFileAsync(path.join(tempDir, `traces-${today}.jsonl`), mockSpans);
|
|
27
|
+
// First query - should read from file
|
|
28
|
+
const result1 = await backend.queryTraces({ spanName: 'test-op' });
|
|
29
|
+
assert.strictEqual(result1.length, 1);
|
|
30
|
+
// Modify the file - but cache should return old result
|
|
31
|
+
const newSpans = [
|
|
32
|
+
{ traceId: 'cache-test-1', spanId: 'span1', name: 'test-op', startTime: [1700000000, 0] },
|
|
33
|
+
{ traceId: 'cache-test-2', spanId: 'span2', name: 'test-op', startTime: [1700000001, 0] },
|
|
34
|
+
];
|
|
35
|
+
await writeJsonlFileAsync(path.join(tempDir, `traces-${today}.jsonl`), newSpans);
|
|
36
|
+
// Second query with same options - should return cached result
|
|
37
|
+
const result2 = await backend.queryTraces({ spanName: 'test-op' });
|
|
38
|
+
assert.strictEqual(result2.length, 1, 'Should return cached result, not new file contents');
|
|
39
|
+
});
|
|
40
|
+
it('should return fresh results when query options differ', async () => {
|
|
41
|
+
const today = getTestDate();
|
|
42
|
+
const mockSpans = [
|
|
43
|
+
{ traceId: 'cache-test-1', spanId: 'span1', name: 'alpha-op', startTime: [1700000000, 0] },
|
|
44
|
+
{ traceId: 'cache-test-2', spanId: 'span2', name: 'beta-op', startTime: [1700000000, 0] },
|
|
45
|
+
];
|
|
46
|
+
await writeJsonlFileAsync(path.join(tempDir, `traces-${today}.jsonl`), mockSpans);
|
|
47
|
+
const result1 = await backend.queryTraces({ spanName: 'alpha' });
|
|
48
|
+
assert.strictEqual(result1.length, 1);
|
|
49
|
+
const result2 = await backend.queryTraces({ spanName: 'beta' });
|
|
50
|
+
assert.strictEqual(result2.length, 1);
|
|
51
|
+
assert.strictEqual(result2[0].name, 'beta-op');
|
|
52
|
+
});
|
|
53
|
+
it('should clear cache when clearCache is called', async () => {
|
|
54
|
+
const today = getTestDate();
|
|
55
|
+
const mockSpans = [
|
|
56
|
+
{ traceId: 'cache-test-1', spanId: 'span1', name: 'clear-test', startTime: [1700000000, 0] },
|
|
57
|
+
];
|
|
58
|
+
await writeJsonlFileAsync(path.join(tempDir, `traces-${today}.jsonl`), mockSpans);
|
|
59
|
+
// First query
|
|
60
|
+
const result1 = await backend.queryTraces({ spanName: 'clear-test' });
|
|
61
|
+
assert.strictEqual(result1.length, 1);
|
|
62
|
+
// Modify the file
|
|
63
|
+
const newSpans = [
|
|
64
|
+
{ traceId: 'cache-test-1', spanId: 'span1', name: 'clear-test', startTime: [1700000000, 0] },
|
|
65
|
+
{ traceId: 'cache-test-2', spanId: 'span2', name: 'clear-test', startTime: [1700000001, 0] },
|
|
66
|
+
];
|
|
67
|
+
await writeJsonlFileAsync(path.join(tempDir, `traces-${today}.jsonl`), newSpans);
|
|
68
|
+
// Clear cache
|
|
69
|
+
backend.clearCache();
|
|
70
|
+
// Query again - should read fresh data
|
|
71
|
+
const result2 = await backend.queryTraces({ spanName: 'clear-test' });
|
|
72
|
+
assert.strictEqual(result2.length, 2, 'Should return fresh results after cache clear');
|
|
73
|
+
});
|
|
74
|
+
it('should cache logs query results', async () => {
|
|
75
|
+
const today = getTestDate();
|
|
76
|
+
const mockLogs = [
|
|
77
|
+
{ timestamp: `${today}T10:00:00Z`, body: 'Test log message', severity: 'INFO' },
|
|
78
|
+
];
|
|
79
|
+
await writeJsonlFileAsync(path.join(tempDir, `logs-${today}.jsonl`), mockLogs);
|
|
80
|
+
const result1 = await backend.queryLogs({ search: 'Test' });
|
|
81
|
+
assert.strictEqual(result1.length, 1);
|
|
82
|
+
// Add another log to file
|
|
83
|
+
const newLogs = [
|
|
84
|
+
{ timestamp: `${today}T10:00:00Z`, body: 'Test log message', severity: 'INFO' },
|
|
85
|
+
{ timestamp: `${today}T11:00:00Z`, body: 'Another Test log', severity: 'INFO' },
|
|
86
|
+
];
|
|
87
|
+
await writeJsonlFileAsync(path.join(tempDir, `logs-${today}.jsonl`), newLogs);
|
|
88
|
+
// Should return cached result
|
|
89
|
+
const result2 = await backend.queryLogs({ search: 'Test' });
|
|
90
|
+
assert.strictEqual(result2.length, 1, 'Should return cached logs result');
|
|
91
|
+
});
|
|
92
|
+
it('should cache metrics query results', async () => {
|
|
93
|
+
const today = getTestDate();
|
|
94
|
+
const mockMetrics = [
|
|
95
|
+
{ timestamp: `${today}T10:00:00Z`, name: 'test.metric', value: 100, type: 'gauge' },
|
|
96
|
+
];
|
|
97
|
+
await writeJsonlFileAsync(path.join(tempDir, `metrics-${today}.jsonl`), mockMetrics);
|
|
98
|
+
const result1 = await backend.queryMetrics({ metricName: 'test.metric' });
|
|
99
|
+
assert.strictEqual(result1.length, 1);
|
|
100
|
+
// Add another metric to file
|
|
101
|
+
const newMetrics = [
|
|
102
|
+
{ timestamp: `${today}T10:00:00Z`, name: 'test.metric', value: 100, type: 'gauge' },
|
|
103
|
+
{ timestamp: `${today}T11:00:00Z`, name: 'test.metric', value: 200, type: 'gauge' },
|
|
104
|
+
];
|
|
105
|
+
await writeJsonlFileAsync(path.join(tempDir, `metrics-${today}.jsonl`), newMetrics);
|
|
106
|
+
// Should return cached result
|
|
107
|
+
const result2 = await backend.queryMetrics({ metricName: 'test.metric' });
|
|
108
|
+
assert.strictEqual(result2.length, 1, 'Should return cached metrics result');
|
|
109
|
+
});
|
|
110
|
+
it('should cache LLM events query results', async () => {
|
|
111
|
+
const today = getTestDate();
|
|
112
|
+
const mockEvents = [
|
|
113
|
+
{ timestamp: `${today}T10:00:00Z`, name: 'llm.call', attributes: { model: 'claude' } },
|
|
114
|
+
];
|
|
115
|
+
await writeJsonlFileAsync(path.join(tempDir, `llm-events-${today}.jsonl`), mockEvents);
|
|
116
|
+
const result1 = await backend.queryLLMEvents({ eventName: 'llm.call' });
|
|
117
|
+
assert.strictEqual(result1.length, 1);
|
|
118
|
+
// Add another event to file
|
|
119
|
+
const newEvents = [
|
|
120
|
+
{ timestamp: `${today}T10:00:00Z`, name: 'llm.call', attributes: { model: 'claude' } },
|
|
121
|
+
{ timestamp: `${today}T11:00:00Z`, name: 'llm.call', attributes: { model: 'gpt' } },
|
|
122
|
+
];
|
|
123
|
+
await writeJsonlFileAsync(path.join(tempDir, `llm-events-${today}.jsonl`), newEvents);
|
|
124
|
+
// Should return cached result
|
|
125
|
+
const result2 = await backend.queryLLMEvents({ eventName: 'llm.call' });
|
|
126
|
+
assert.strictEqual(result2.length, 1, 'Should return cached LLM events result');
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
describe('getCacheStats', () => {
|
|
130
|
+
it('should return correct cache stats structure', () => {
|
|
131
|
+
const stats = backend.getCacheStats();
|
|
132
|
+
assert.ok(stats.traces, 'Should have traces stats');
|
|
133
|
+
assert.ok(stats.logs, 'Should have logs stats');
|
|
134
|
+
assert.ok(stats.metrics, 'Should have metrics stats');
|
|
135
|
+
assert.ok(stats.llmEvents, 'Should have llmEvents stats');
|
|
136
|
+
// Check structure of each cache stat
|
|
137
|
+
for (const key of ['traces', 'logs', 'metrics', 'llmEvents']) {
|
|
138
|
+
const stat = stats[key];
|
|
139
|
+
assert.strictEqual(typeof stat.hits, 'number', `${key} should have hits`);
|
|
140
|
+
assert.strictEqual(typeof stat.misses, 'number', `${key} should have misses`);
|
|
141
|
+
assert.strictEqual(typeof stat.evictions, 'number', `${key} should have evictions`);
|
|
142
|
+
assert.strictEqual(typeof stat.size, 'number', `${key} should have size`);
|
|
143
|
+
assert.strictEqual(typeof stat.hitRate, 'number', `${key} should have hitRate`);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
it('should track cache hits and misses', async () => {
|
|
147
|
+
const today = getTestDate();
|
|
148
|
+
const mockSpans = [
|
|
149
|
+
{ traceId: 'stats-test-1', spanId: 'span1', name: 'test-op', startTime: [1700000000, 0] },
|
|
150
|
+
];
|
|
151
|
+
await writeJsonlFileAsync(path.join(tempDir, `traces-${today}.jsonl`), mockSpans);
|
|
152
|
+
// Initial stats should be zero
|
|
153
|
+
let stats = backend.getCacheStats();
|
|
154
|
+
assert.strictEqual(stats.traces.hits, 0);
|
|
155
|
+
assert.strictEqual(stats.traces.misses, 0);
|
|
156
|
+
// First query - cache miss
|
|
157
|
+
await backend.queryTraces({ spanName: 'test-op' });
|
|
158
|
+
stats = backend.getCacheStats();
|
|
159
|
+
assert.strictEqual(stats.traces.misses, 1);
|
|
160
|
+
assert.strictEqual(stats.traces.hits, 0);
|
|
161
|
+
// Second query with same options - cache hit
|
|
162
|
+
await backend.queryTraces({ spanName: 'test-op' });
|
|
163
|
+
stats = backend.getCacheStats();
|
|
164
|
+
assert.strictEqual(stats.traces.hits, 1);
|
|
165
|
+
assert.strictEqual(stats.traces.misses, 1);
|
|
166
|
+
assert.ok(stats.traces.hitRate > 0, 'Hit rate should be > 0');
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
describe('indexed queries', () => {
|
|
170
|
+
it('should use index for trace queries when available', async () => {
|
|
171
|
+
const today = getTestDate();
|
|
172
|
+
const mockSpans = [
|
|
173
|
+
{ traceId: 'trace1', spanId: 'span1', name: 'user-create', startTime: [1700000000, 0], resource: { serviceName: 'service-a' } },
|
|
174
|
+
{ traceId: 'trace2', spanId: 'span2', name: 'db-query', startTime: [1700000001, 0], resource: { serviceName: 'service-b' } },
|
|
175
|
+
{ traceId: 'trace1', spanId: 'span3', name: 'user-update', startTime: [1700000002, 0], resource: { serviceName: 'service-a' } },
|
|
176
|
+
];
|
|
177
|
+
const filePath = path.join(tempDir, `traces-${today}.jsonl`);
|
|
178
|
+
await writeJsonlFileAsync(filePath, mockSpans);
|
|
179
|
+
// Build index for the file
|
|
180
|
+
await buildAndWriteIndex(filePath, 'traces');
|
|
181
|
+
// Query should use the index
|
|
182
|
+
const results = await backend.queryTraces({ traceId: 'trace1' });
|
|
183
|
+
assert.strictEqual(results.length, 2);
|
|
184
|
+
assert.ok(results.every(s => s.traceId === 'trace1'));
|
|
185
|
+
});
|
|
186
|
+
it('should fall back to full scan when no index exists', async () => {
|
|
187
|
+
const today = getTestDate();
|
|
188
|
+
const mockSpans = [
|
|
189
|
+
{ traceId: 'trace1', spanId: 'span1', name: 'op1', startTime: [1700000000, 0] },
|
|
190
|
+
{ traceId: 'trace2', spanId: 'span2', name: 'op2', startTime: [1700000001, 0] },
|
|
191
|
+
];
|
|
192
|
+
await writeJsonlFileAsync(path.join(tempDir, `traces-${today}.jsonl`), mockSpans);
|
|
193
|
+
// No index built - should still work via full scan
|
|
194
|
+
const results = await backend.queryTraces({ traceId: 'trace1' });
|
|
195
|
+
assert.strictEqual(results.length, 1);
|
|
196
|
+
assert.strictEqual(results[0].traceId, 'trace1');
|
|
197
|
+
});
|
|
198
|
+
it('should use index for log queries when available', async () => {
|
|
199
|
+
const today = getTestDate();
|
|
200
|
+
const mockLogs = [
|
|
201
|
+
{ timestamp: `${today}T10:00:00Z`, severityText: 'ERROR', body: 'Error occurred', traceId: 'trace1' },
|
|
202
|
+
{ timestamp: `${today}T10:01:00Z`, severityText: 'INFO', body: 'Info message', traceId: 'trace2' },
|
|
203
|
+
{ timestamp: `${today}T10:02:00Z`, severityText: 'ERROR', body: 'Another error', traceId: 'trace3' },
|
|
204
|
+
];
|
|
205
|
+
const filePath = path.join(tempDir, `logs-${today}.jsonl`);
|
|
206
|
+
await writeJsonlFileAsync(filePath, mockLogs);
|
|
207
|
+
// Build index for the file
|
|
208
|
+
await buildAndWriteIndex(filePath, 'logs');
|
|
209
|
+
// Query should use the index
|
|
210
|
+
const results = await backend.queryLogs({ severity: 'ERROR' });
|
|
211
|
+
assert.strictEqual(results.length, 2);
|
|
212
|
+
assert.ok(results.every(l => l.severity === 'ERROR'));
|
|
213
|
+
});
|
|
214
|
+
it('should use index for metric queries when available', async () => {
|
|
215
|
+
const today = getTestDate();
|
|
216
|
+
const mockMetrics = [
|
|
217
|
+
{ timestamp: `${today}T10:00:00Z`, name: 'http.request.duration', value: 100 },
|
|
218
|
+
{ timestamp: `${today}T10:01:00Z`, name: 'db.query.count', value: 50 },
|
|
219
|
+
{ timestamp: `${today}T10:02:00Z`, name: 'http.request.size', value: 1024 },
|
|
220
|
+
];
|
|
221
|
+
const filePath = path.join(tempDir, `metrics-${today}.jsonl`);
|
|
222
|
+
await writeJsonlFileAsync(filePath, mockMetrics);
|
|
223
|
+
// Build index for the file
|
|
224
|
+
await buildAndWriteIndex(filePath, 'metrics');
|
|
225
|
+
// Query should use the index
|
|
226
|
+
const results = await backend.queryMetrics({ metricName: 'http' });
|
|
227
|
+
assert.strictEqual(results.length, 2);
|
|
228
|
+
assert.ok(results.every(m => m.name.includes('http')));
|
|
229
|
+
});
|
|
230
|
+
it('should apply non-indexable filters after index lookup', async () => {
|
|
231
|
+
const today = getTestDate();
|
|
232
|
+
const mockSpans = [
|
|
233
|
+
{
|
|
234
|
+
traceId: 'trace1',
|
|
235
|
+
spanId: 'span1',
|
|
236
|
+
name: 'user-create',
|
|
237
|
+
startTime: [1700000000, 0],
|
|
238
|
+
endTime: [1700000000, 500000000], // 500ms duration
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
traceId: 'trace1',
|
|
242
|
+
spanId: 'span2',
|
|
243
|
+
name: 'user-update',
|
|
244
|
+
startTime: [1700000000, 0],
|
|
245
|
+
endTime: [1700000002, 0], // 2s duration
|
|
246
|
+
},
|
|
247
|
+
];
|
|
248
|
+
const filePath = path.join(tempDir, `traces-${today}.jsonl`);
|
|
249
|
+
await writeJsonlFileAsync(filePath, mockSpans);
|
|
250
|
+
// Build index
|
|
251
|
+
await buildAndWriteIndex(filePath, 'traces');
|
|
252
|
+
// Query with both indexable (traceId) and non-indexable (minDurationMs) filters
|
|
253
|
+
const results = await backend.queryTraces({ traceId: 'trace1', minDurationMs: 1000 });
|
|
254
|
+
assert.strictEqual(results.length, 1);
|
|
255
|
+
assert.strictEqual(results[0].name, 'user-update');
|
|
256
|
+
});
|
|
257
|
+
it('should work correctly when index is stale', async () => {
|
|
258
|
+
const today = getTestDate();
|
|
259
|
+
const filePath = path.join(tempDir, `traces-${today}.jsonl`);
|
|
260
|
+
// Create initial file and index
|
|
261
|
+
const initialSpans = [
|
|
262
|
+
{ traceId: 'trace1', spanId: 'span1', name: 'op1', startTime: [1700000000, 0] },
|
|
263
|
+
];
|
|
264
|
+
await writeJsonlFileAsync(filePath, initialSpans);
|
|
265
|
+
await buildAndWriteIndex(filePath, 'traces');
|
|
266
|
+
// Modify the file to make index stale
|
|
267
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
268
|
+
const updatedSpans = [
|
|
269
|
+
{ traceId: 'trace1', spanId: 'span1', name: 'op1', startTime: [1700000000, 0] },
|
|
270
|
+
{ traceId: 'trace2', spanId: 'span2', name: 'op2', startTime: [1700000001, 0] },
|
|
271
|
+
];
|
|
272
|
+
await writeJsonlFileAsync(filePath, updatedSpans);
|
|
273
|
+
// Query should fall back to full scan and find both spans
|
|
274
|
+
const results = await backend.queryTraces({});
|
|
275
|
+
assert.strictEqual(results.length, 2);
|
|
276
|
+
});
|
|
277
|
+
it('should respect useIndexes=false constructor option', async () => {
|
|
278
|
+
const today = getTestDate();
|
|
279
|
+
const mockSpans = [
|
|
280
|
+
{ traceId: 'trace1', spanId: 'span1', name: 'op1', startTime: [1700000000, 0] },
|
|
281
|
+
{ traceId: 'trace2', spanId: 'span2', name: 'op2', startTime: [1700000001, 0] },
|
|
282
|
+
];
|
|
283
|
+
const filePath = path.join(tempDir, `traces-${today}.jsonl`);
|
|
284
|
+
await writeJsonlFileAsync(filePath, mockSpans);
|
|
285
|
+
await buildAndWriteIndex(filePath, 'traces');
|
|
286
|
+
// Create backend with indexes disabled
|
|
287
|
+
const noIndexBackend = new LocalJsonlBackend(tempDir, false);
|
|
288
|
+
// Should still work via full scan
|
|
289
|
+
const results = await noIndexBackend.queryTraces({ traceId: 'trace1' });
|
|
290
|
+
assert.strictEqual(results.length, 1);
|
|
291
|
+
assert.strictEqual(results[0].traceId, 'trace1');
|
|
292
|
+
});
|
|
293
|
+
});
|
|
294
|
+
});
|
|
295
|
+
//# sourceMappingURL=local-jsonl-cache.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-jsonl-cache.test.js","sourceRoot":"","sources":["../../src/backends/local-jsonl-cache.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-jsonl-circuit-breaker.test.d.ts","sourceRoot":"","sources":["../../src/backends/local-jsonl-circuit-breaker.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { describe, it, before, after, beforeEach } from 'node:test';
|
|
2
|
+
import * as assert from 'node:assert';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import { LocalJsonlBackend } from './local-jsonl.js';
|
|
5
|
+
import { getSharedTempDir, clearTempDir, removeSharedTempDir, writeJsonlFileAsync, getTestDate } from '../test-helpers/file-utils.js';
|
|
6
|
+
describe('LocalJsonlBackend circuit breaker', () => {
|
|
7
|
+
let tempDir;
|
|
8
|
+
let backend;
|
|
9
|
+
before(() => {
|
|
10
|
+
tempDir = getSharedTempDir('LocalJsonlBackend-CircuitBreaker');
|
|
11
|
+
});
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
clearTempDir(tempDir);
|
|
14
|
+
backend = new LocalJsonlBackend(tempDir);
|
|
15
|
+
});
|
|
16
|
+
after(() => {
|
|
17
|
+
removeSharedTempDir('LocalJsonlBackend-CircuitBreaker');
|
|
18
|
+
});
|
|
19
|
+
describe('circuit breaker state', () => {
|
|
20
|
+
it('should start with circuit breaker closed', () => {
|
|
21
|
+
assert.strictEqual(backend.getCircuitBreakerState(), 'closed');
|
|
22
|
+
});
|
|
23
|
+
it('should expose circuit breaker state getter', () => {
|
|
24
|
+
const state = backend.getCircuitBreakerState();
|
|
25
|
+
assert.ok(['closed', 'open', 'half-open'].includes(state));
|
|
26
|
+
});
|
|
27
|
+
it('should allow circuit breaker reset', () => {
|
|
28
|
+
backend.resetCircuitBreaker();
|
|
29
|
+
assert.strictEqual(backend.getCircuitBreakerState(), 'closed');
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
describe('queryTraces with circuit breaker', () => {
|
|
33
|
+
it('should return results when circuit is closed', async () => {
|
|
34
|
+
const today = getTestDate();
|
|
35
|
+
const mockSpans = [
|
|
36
|
+
{ traceId: 'trace1', spanId: 'span1', name: 'op1', startTime: [1700000000, 0] },
|
|
37
|
+
];
|
|
38
|
+
await writeJsonlFileAsync(path.join(tempDir, `traces-${today}.jsonl`), mockSpans);
|
|
39
|
+
const results = await backend.queryTraces({});
|
|
40
|
+
assert.strictEqual(results.length, 1);
|
|
41
|
+
assert.strictEqual(backend.getCircuitBreakerState(), 'closed');
|
|
42
|
+
});
|
|
43
|
+
it('should return empty array when circuit is open', async () => {
|
|
44
|
+
const today = getTestDate();
|
|
45
|
+
const mockSpans = [
|
|
46
|
+
{ traceId: 'trace1', spanId: 'span1', name: 'op1', startTime: [1700000000, 0] },
|
|
47
|
+
];
|
|
48
|
+
await writeJsonlFileAsync(path.join(tempDir, `traces-${today}.jsonl`), mockSpans);
|
|
49
|
+
// Create a new backend pointing to non-existent dir to trigger failures
|
|
50
|
+
const failingBackend = new LocalJsonlBackend('/nonexistent/dir/that/does/not/exist');
|
|
51
|
+
// Force circuit to open by simulating failures (need to access private method)
|
|
52
|
+
// Instead, we'll manually trigger failures through the interface
|
|
53
|
+
for (let i = 0; i < 3; i++) {
|
|
54
|
+
try {
|
|
55
|
+
// This will succeed (empty result) because the dir doesn't have files
|
|
56
|
+
// But we can verify the circuit opens after repeated I/O errors
|
|
57
|
+
await failingBackend.queryTraces({});
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// Expected for I/O errors
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Circuit breaker behavior: should still return empty array
|
|
64
|
+
const result = await failingBackend.queryTraces({});
|
|
65
|
+
assert.deepStrictEqual(result, []);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
describe('queryLogs with circuit breaker', () => {
|
|
69
|
+
it('should return results when circuit is closed', async () => {
|
|
70
|
+
const today = getTestDate();
|
|
71
|
+
const mockLogs = [
|
|
72
|
+
{ timestamp: '2024-01-01T00:00:00Z', severity: 'INFO', body: 'test log' },
|
|
73
|
+
];
|
|
74
|
+
await writeJsonlFileAsync(path.join(tempDir, `logs-${today}.jsonl`), mockLogs);
|
|
75
|
+
const results = await backend.queryLogs({});
|
|
76
|
+
assert.strictEqual(results.length, 1);
|
|
77
|
+
assert.strictEqual(backend.getCircuitBreakerState(), 'closed');
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
describe('queryMetrics with circuit breaker', () => {
|
|
81
|
+
it('should return results when circuit is closed', async () => {
|
|
82
|
+
const today = getTestDate();
|
|
83
|
+
const mockMetrics = [
|
|
84
|
+
{ timestamp: '2024-01-01T00:00:00Z', name: 'test.metric', value: 42, type: 'gauge' },
|
|
85
|
+
];
|
|
86
|
+
await writeJsonlFileAsync(path.join(tempDir, `metrics-${today}.jsonl`), mockMetrics);
|
|
87
|
+
const results = await backend.queryMetrics({});
|
|
88
|
+
assert.strictEqual(results.length, 1);
|
|
89
|
+
assert.strictEqual(backend.getCircuitBreakerState(), 'closed');
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
describe('queryLLMEvents with circuit breaker', () => {
|
|
93
|
+
it('should return results when circuit is closed', async () => {
|
|
94
|
+
const today = getTestDate();
|
|
95
|
+
const mockEvents = [
|
|
96
|
+
{ timestamp: '2024-01-01T00:00:00Z', name: 'llm.call', attributes: { model: 'gpt-4' } },
|
|
97
|
+
];
|
|
98
|
+
await writeJsonlFileAsync(path.join(tempDir, `llm-events-${today}.jsonl`), mockEvents);
|
|
99
|
+
const results = await backend.queryLLMEvents({});
|
|
100
|
+
assert.strictEqual(results.length, 1);
|
|
101
|
+
assert.strictEqual(backend.getCircuitBreakerState(), 'closed');
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
describe('queryEvaluations with circuit breaker', () => {
|
|
105
|
+
it('should return results when circuit is closed', async () => {
|
|
106
|
+
const today = getTestDate();
|
|
107
|
+
const mockEvals = [
|
|
108
|
+
{
|
|
109
|
+
timestamp: '2024-01-01T00:00:00Z',
|
|
110
|
+
name: 'gen_ai.evaluation.result',
|
|
111
|
+
attributes: { 'gen_ai.evaluation.name': 'test-eval', 'gen_ai.evaluation.score_value': 0.95 },
|
|
112
|
+
},
|
|
113
|
+
];
|
|
114
|
+
await writeJsonlFileAsync(path.join(tempDir, `evaluations-${today}.jsonl`), mockEvals);
|
|
115
|
+
const results = await backend.queryEvaluations({});
|
|
116
|
+
assert.strictEqual(results.length, 1);
|
|
117
|
+
assert.strictEqual(backend.getCircuitBreakerState(), 'closed');
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
describe('healthCheck with circuit breaker', () => {
|
|
121
|
+
it('should report ok when circuit is closed', async () => {
|
|
122
|
+
const today = getTestDate();
|
|
123
|
+
const mockSpans = [{ traceId: 'trace1', spanId: 'span1', name: 'op1', startTime: [1700000000, 0] }];
|
|
124
|
+
await writeJsonlFileAsync(path.join(tempDir, `traces-${today}.jsonl`), mockSpans);
|
|
125
|
+
const health = await backend.healthCheck();
|
|
126
|
+
assert.strictEqual(health.status, 'ok');
|
|
127
|
+
});
|
|
128
|
+
it('should report error when telemetry directory not found', async () => {
|
|
129
|
+
const missingBackend = new LocalJsonlBackend('/nonexistent/path');
|
|
130
|
+
const health = await missingBackend.healthCheck();
|
|
131
|
+
assert.strictEqual(health.status, 'error');
|
|
132
|
+
assert.ok(health.message?.includes('not found'));
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
describe('circuit breaker recovery', () => {
|
|
136
|
+
let originalDateNow;
|
|
137
|
+
let currentTime;
|
|
138
|
+
before(() => {
|
|
139
|
+
originalDateNow = Date.now;
|
|
140
|
+
});
|
|
141
|
+
beforeEach(() => {
|
|
142
|
+
currentTime = 1000000;
|
|
143
|
+
Date.now = () => currentTime;
|
|
144
|
+
});
|
|
145
|
+
after(() => {
|
|
146
|
+
Date.now = originalDateNow;
|
|
147
|
+
});
|
|
148
|
+
it('should record success after successful query', async () => {
|
|
149
|
+
const today = getTestDate();
|
|
150
|
+
const mockSpans = [{ traceId: 'trace1', spanId: 'span1', name: 'op1', startTime: [1700000000, 0] }];
|
|
151
|
+
await writeJsonlFileAsync(path.join(tempDir, `traces-${today}.jsonl`), mockSpans);
|
|
152
|
+
await backend.queryTraces({});
|
|
153
|
+
// After successful query, circuit should be closed
|
|
154
|
+
assert.strictEqual(backend.getCircuitBreakerState(), 'closed');
|
|
155
|
+
});
|
|
156
|
+
it('should maintain closed state after multiple successful queries', async () => {
|
|
157
|
+
const today = getTestDate();
|
|
158
|
+
const mockSpans = [{ traceId: 'trace1', spanId: 'span1', name: 'op1', startTime: [1700000000, 0] }];
|
|
159
|
+
await writeJsonlFileAsync(path.join(tempDir, `traces-${today}.jsonl`), mockSpans);
|
|
160
|
+
await backend.queryTraces({});
|
|
161
|
+
await backend.queryLogs({});
|
|
162
|
+
await backend.queryMetrics({});
|
|
163
|
+
assert.strictEqual(backend.getCircuitBreakerState(), 'closed');
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
describe('circuit breaker isolation', () => {
|
|
167
|
+
it('should not share circuit breaker state between backend instances', async () => {
|
|
168
|
+
const backend1 = new LocalJsonlBackend(tempDir);
|
|
169
|
+
const backend2 = new LocalJsonlBackend(tempDir);
|
|
170
|
+
// Each backend should have its own circuit breaker
|
|
171
|
+
assert.strictEqual(backend1.getCircuitBreakerState(), 'closed');
|
|
172
|
+
assert.strictEqual(backend2.getCircuitBreakerState(), 'closed');
|
|
173
|
+
// Resetting one should not affect the other
|
|
174
|
+
backend1.resetCircuitBreaker();
|
|
175
|
+
assert.strictEqual(backend1.getCircuitBreakerState(), 'closed');
|
|
176
|
+
assert.strictEqual(backend2.getCircuitBreakerState(), 'closed');
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
//# sourceMappingURL=local-jsonl-circuit-breaker.test.js.map
|