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.
Files changed (164) hide show
  1. package/dist/backends/local-jsonl-boolean-search.test.js +8 -8
  2. package/dist/backends/local-jsonl-boolean-search.test.js.map +1 -1
  3. package/dist/backends/local-jsonl-cache.test.d.ts +2 -0
  4. package/dist/backends/local-jsonl-cache.test.d.ts.map +1 -0
  5. package/dist/backends/local-jsonl-cache.test.js +295 -0
  6. package/dist/backends/local-jsonl-cache.test.js.map +1 -0
  7. package/dist/backends/local-jsonl-circuit-breaker.test.d.ts +2 -0
  8. package/dist/backends/local-jsonl-circuit-breaker.test.d.ts.map +1 -0
  9. package/dist/backends/local-jsonl-circuit-breaker.test.js +180 -0
  10. package/dist/backends/local-jsonl-circuit-breaker.test.js.map +1 -0
  11. package/dist/backends/local-jsonl-export.test.d.ts +2 -0
  12. package/dist/backends/local-jsonl-export.test.d.ts.map +1 -0
  13. package/dist/backends/local-jsonl-export.test.js +704 -0
  14. package/dist/backends/local-jsonl-export.test.js.map +1 -0
  15. package/dist/backends/local-jsonl-index.test.d.ts +2 -0
  16. package/dist/backends/local-jsonl-index.test.d.ts.map +1 -0
  17. package/dist/backends/local-jsonl-index.test.js +554 -0
  18. package/dist/backends/local-jsonl-index.test.js.map +1 -0
  19. package/dist/backends/local-jsonl-logs.test.js +52 -43
  20. package/dist/backends/local-jsonl-logs.test.js.map +1 -1
  21. package/dist/backends/local-jsonl-metrics.test.d.ts +2 -0
  22. package/dist/backends/local-jsonl-metrics.test.d.ts.map +1 -0
  23. package/dist/backends/local-jsonl-metrics.test.js +876 -0
  24. package/dist/backends/local-jsonl-metrics.test.js.map +1 -0
  25. package/dist/backends/local-jsonl-traces.test.js +89 -83
  26. package/dist/backends/local-jsonl-traces.test.js.map +1 -1
  27. package/dist/backends/local-jsonl.d.ts +9 -0
  28. package/dist/backends/local-jsonl.d.ts.map +1 -1
  29. package/dist/backends/local-jsonl.js +348 -227
  30. package/dist/backends/local-jsonl.js.map +1 -1
  31. package/dist/backends/signoz-api-circuit-breaker.test.d.ts +6 -0
  32. package/dist/backends/signoz-api-circuit-breaker.test.d.ts.map +1 -0
  33. package/dist/backends/signoz-api-circuit-breaker.test.js +548 -0
  34. package/dist/backends/signoz-api-circuit-breaker.test.js.map +1 -0
  35. package/dist/backends/signoz-api-rate-limiter.test.d.ts +6 -0
  36. package/dist/backends/signoz-api-rate-limiter.test.d.ts.map +1 -0
  37. package/dist/backends/signoz-api-rate-limiter.test.js +389 -0
  38. package/dist/backends/signoz-api-rate-limiter.test.js.map +1 -0
  39. package/dist/backends/signoz-api-ssrf.test.d.ts +6 -0
  40. package/dist/backends/signoz-api-ssrf.test.d.ts.map +1 -0
  41. package/dist/backends/signoz-api-ssrf.test.js +216 -0
  42. package/dist/backends/signoz-api-ssrf.test.js.map +1 -0
  43. package/dist/backends/signoz-api-test-helpers.d.ts +80 -0
  44. package/dist/backends/signoz-api-test-helpers.d.ts.map +1 -0
  45. package/dist/backends/signoz-api-test-helpers.js +79 -0
  46. package/dist/backends/signoz-api-test-helpers.js.map +1 -0
  47. package/dist/backends/signoz-api.d.ts +16 -0
  48. package/dist/backends/signoz-api.d.ts.map +1 -1
  49. package/dist/backends/signoz-api.js +71 -9
  50. package/dist/backends/signoz-api.js.map +1 -1
  51. package/dist/backends/signoz-api.test.d.ts +9 -0
  52. package/dist/backends/signoz-api.test.d.ts.map +1 -1
  53. package/dist/backends/signoz-api.test.js +14 -1027
  54. package/dist/backends/signoz-api.test.js.map +1 -1
  55. package/dist/lib/cache.d.ts +47 -1
  56. package/dist/lib/cache.d.ts.map +1 -1
  57. package/dist/lib/cache.js +40 -3
  58. package/dist/lib/cache.js.map +1 -1
  59. package/dist/lib/circuit-breaker.d.ts +83 -0
  60. package/dist/lib/circuit-breaker.d.ts.map +1 -0
  61. package/dist/lib/circuit-breaker.js +125 -0
  62. package/dist/lib/circuit-breaker.js.map +1 -0
  63. package/dist/lib/circuit-breaker.test.d.ts +2 -0
  64. package/dist/lib/circuit-breaker.test.d.ts.map +1 -0
  65. package/dist/lib/circuit-breaker.test.js +263 -0
  66. package/dist/lib/circuit-breaker.test.js.map +1 -0
  67. package/dist/lib/constants-symlink.test.d.ts +12 -0
  68. package/dist/lib/constants-symlink.test.d.ts.map +1 -0
  69. package/dist/lib/constants-symlink.test.js +357 -0
  70. package/dist/lib/constants-symlink.test.js.map +1 -0
  71. package/dist/lib/edge-cases.test.js +17 -17
  72. package/dist/lib/edge-cases.test.js.map +1 -1
  73. package/dist/lib/error-sanitizer.d.ts.map +1 -1
  74. package/dist/lib/error-sanitizer.js +29 -3
  75. package/dist/lib/error-sanitizer.js.map +1 -1
  76. package/dist/lib/error-sanitizer.test.js +159 -0
  77. package/dist/lib/error-sanitizer.test.js.map +1 -1
  78. package/dist/lib/error-types.d.ts +54 -0
  79. package/dist/lib/error-types.d.ts.map +1 -0
  80. package/dist/lib/error-types.js +154 -0
  81. package/dist/lib/error-types.js.map +1 -0
  82. package/dist/lib/error-types.test.d.ts +2 -0
  83. package/dist/lib/error-types.test.d.ts.map +1 -0
  84. package/dist/lib/error-types.test.js +196 -0
  85. package/dist/lib/error-types.test.js.map +1 -0
  86. package/dist/lib/indexer.test.js +27 -27
  87. package/dist/lib/indexer.test.js.map +1 -1
  88. package/dist/lib/input-validator.d.ts +12 -0
  89. package/dist/lib/input-validator.d.ts.map +1 -1
  90. package/dist/lib/input-validator.fuzz.test.d.ts +12 -0
  91. package/dist/lib/input-validator.fuzz.test.d.ts.map +1 -0
  92. package/dist/lib/input-validator.fuzz.test.js +290 -0
  93. package/dist/lib/input-validator.fuzz.test.js.map +1 -0
  94. package/dist/lib/input-validator.js +57 -3
  95. package/dist/lib/input-validator.js.map +1 -1
  96. package/dist/lib/input-validator.test.js +129 -1
  97. package/dist/lib/input-validator.test.js.map +1 -1
  98. package/dist/lib/logger.d.ts +46 -0
  99. package/dist/lib/logger.d.ts.map +1 -0
  100. package/dist/lib/logger.js +81 -0
  101. package/dist/lib/logger.js.map +1 -0
  102. package/dist/lib/logger.test.d.ts +2 -0
  103. package/dist/lib/logger.test.d.ts.map +1 -0
  104. package/dist/lib/logger.test.js +122 -0
  105. package/dist/lib/logger.test.js.map +1 -0
  106. package/dist/lib/server-utils.d.ts +8 -0
  107. package/dist/lib/server-utils.d.ts.map +1 -1
  108. package/dist/lib/server-utils.js +34 -2
  109. package/dist/lib/server-utils.js.map +1 -1
  110. package/dist/lib/shared-schemas.d.ts +22 -0
  111. package/dist/lib/shared-schemas.d.ts.map +1 -1
  112. package/dist/lib/shared-schemas.js +22 -0
  113. package/dist/lib/shared-schemas.js.map +1 -1
  114. package/dist/lib/toon-encoder.d.ts +7 -2
  115. package/dist/lib/toon-encoder.d.ts.map +1 -1
  116. package/dist/lib/toon-encoder.js +21 -6
  117. package/dist/lib/toon-encoder.js.map +1 -1
  118. package/dist/lib/toon-encoder.test.d.ts +5 -0
  119. package/dist/lib/toon-encoder.test.d.ts.map +1 -0
  120. package/dist/lib/toon-encoder.test.js +85 -0
  121. package/dist/lib/toon-encoder.test.js.map +1 -0
  122. package/dist/server.js +2 -0
  123. package/dist/server.js.map +1 -1
  124. package/dist/server.test.js +30 -0
  125. package/dist/server.test.js.map +1 -1
  126. package/dist/test-helpers/env-utils.d.ts +22 -0
  127. package/dist/test-helpers/env-utils.d.ts.map +1 -1
  128. package/dist/test-helpers/env-utils.js +38 -0
  129. package/dist/test-helpers/env-utils.js.map +1 -1
  130. package/dist/test-helpers/fuzz-generators.d.ts +58 -0
  131. package/dist/test-helpers/fuzz-generators.d.ts.map +1 -0
  132. package/dist/test-helpers/fuzz-generators.js +216 -0
  133. package/dist/test-helpers/fuzz-generators.js.map +1 -0
  134. package/dist/test-helpers/index.d.ts +1 -0
  135. package/dist/test-helpers/index.d.ts.map +1 -1
  136. package/dist/test-helpers/index.js +2 -0
  137. package/dist/test-helpers/index.js.map +1 -1
  138. package/dist/test-helpers/memfs-utils.d.ts +181 -0
  139. package/dist/test-helpers/memfs-utils.d.ts.map +1 -0
  140. package/dist/test-helpers/memfs-utils.js +292 -0
  141. package/dist/test-helpers/memfs-utils.js.map +1 -0
  142. package/dist/test-helpers/memfs-utils.test.d.ts +5 -0
  143. package/dist/test-helpers/memfs-utils.test.d.ts.map +1 -0
  144. package/dist/test-helpers/memfs-utils.test.js +338 -0
  145. package/dist/test-helpers/memfs-utils.test.js.map +1 -0
  146. package/dist/test-helpers/race-condition-helpers.d.ts +85 -0
  147. package/dist/test-helpers/race-condition-helpers.d.ts.map +1 -0
  148. package/dist/test-helpers/race-condition-helpers.js +279 -0
  149. package/dist/test-helpers/race-condition-helpers.js.map +1 -0
  150. package/dist/test-helpers/test-data-builders.d.ts +40 -3
  151. package/dist/test-helpers/test-data-builders.d.ts.map +1 -1
  152. package/dist/test-helpers/test-data-builders.js +54 -5
  153. package/dist/test-helpers/test-data-builders.js.map +1 -1
  154. package/dist/test-helpers/tool-validators.d.ts.map +1 -1
  155. package/dist/test-helpers/tool-validators.js +16 -1
  156. package/dist/test-helpers/tool-validators.js.map +1 -1
  157. package/dist/tools/query-evaluations.d.ts.map +1 -1
  158. package/dist/tools/query-evaluations.js +16 -2
  159. package/dist/tools/query-evaluations.js.map +1 -1
  160. package/dist/tools/query-evaluations.test.js +53 -46
  161. package/dist/tools/query-evaluations.test.js.map +1 -1
  162. package/dist/tools/query-llm-events.test.js +6 -3
  163. package/dist/tools/query-llm-events.test.js.map +1 -1
  164. 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, writeJsonlFile, getTestDate } from '../test-helpers/file-utils.js';
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
- writeJsonlFile(path.join(tempDir, `logs-${today}.jsonl`), mockLogs);
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
- writeJsonlFile(path.join(tempDir, `logs-${today}.jsonl`), mockLogs);
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
- writeJsonlFile(path.join(tempDir, `logs-${today}.jsonl`), mockLogs);
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
- writeJsonlFile(path.join(tempDir, `logs-${today}.jsonl`), mockLogs);
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
- writeJsonlFile(path.join(tempDir, `logs-${today}.jsonl`), mockLogs);
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
- writeJsonlFile(path.join(tempDir, `logs-${today}.jsonl`), mockLogs);
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
- writeJsonlFile(path.join(tempDir, `logs-${today}.jsonl`), mockLogs);
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":"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"}
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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=local-jsonl-cache.test.d.ts.map
@@ -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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=local-jsonl-circuit-breaker.test.d.ts.map
@@ -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