@smoothbricks/lmao 0.2.2 → 0.2.3
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/allocator.wasm +0 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/lib/JsBufferStrategy.d.ts +4 -3
- package/dist/lib/JsBufferStrategy.d.ts.map +1 -1
- package/dist/lib/JsBufferStrategy.js +18 -11
- package/dist/lib/arrow/lease.d.ts +10 -0
- package/dist/lib/arrow/lease.d.ts.map +1 -0
- package/dist/lib/arrow/lease.js +33 -0
- package/dist/lib/arrow/utils.d.ts +3 -4
- package/dist/lib/arrow/utils.d.ts.map +1 -1
- package/dist/lib/arrow/utils.js +12 -13
- package/dist/lib/arrow/vocabularyDictionary.d.ts +21 -0
- package/dist/lib/arrow/vocabularyDictionary.d.ts.map +1 -0
- package/dist/lib/arrow/vocabularyDictionary.js +95 -0
- package/dist/lib/bufferStrategy.d.ts +3 -2
- package/dist/lib/bufferStrategy.d.ts.map +1 -1
- package/dist/lib/cloudflare/traceRows.d.ts.map +1 -1
- package/dist/lib/cloudflare/traceRows.js +3 -2
- package/dist/lib/codegen/evaluatorGenerator.d.ts.map +1 -1
- package/dist/lib/codegen/evaluatorGenerator.js +12 -11
- package/dist/lib/codegen/fixedPositionWriterGenerator.d.ts +44 -82
- package/dist/lib/codegen/fixedPositionWriterGenerator.d.ts.map +1 -1
- package/dist/lib/codegen/fixedPositionWriterGenerator.js +223 -162
- package/dist/lib/codegen/spanLoggerClosureMaterializer.d.ts +63 -0
- package/dist/lib/codegen/spanLoggerClosureMaterializer.d.ts.map +1 -0
- package/dist/lib/codegen/spanLoggerClosureMaterializer.js +447 -0
- package/dist/lib/codegen/spanLoggerGenerator.d.ts +36 -19
- package/dist/lib/codegen/spanLoggerGenerator.d.ts.map +1 -1
- package/dist/lib/codegen/spanLoggerGenerator.js +164 -158
- package/dist/lib/convertToArrow.d.ts +7 -2
- package/dist/lib/convertToArrow.d.ts.map +1 -1
- package/dist/lib/convertToArrow.js +499 -285
- package/dist/lib/defineOpContext.js +1 -1
- package/dist/lib/enumMetadata.d.ts +19 -0
- package/dist/lib/enumMetadata.d.ts.map +1 -0
- package/dist/lib/enumMetadata.js +86 -0
- package/dist/lib/flushScheduler.d.ts.map +1 -1
- package/dist/lib/flushScheduler.js +13 -4
- package/dist/lib/library.d.ts +16 -98
- package/dist/lib/library.d.ts.map +1 -1
- package/dist/lib/library.js +32 -525
- package/dist/lib/logBinding.d.ts +21 -27
- package/dist/lib/logBinding.d.ts.map +1 -1
- package/dist/lib/op.d.ts +30 -30
- package/dist/lib/op.d.ts.map +1 -1
- package/dist/lib/op.js +15 -22
- package/dist/lib/opContext/createOpGroup.d.ts +1 -1
- package/dist/lib/opContext/createOpGroup.d.ts.map +1 -1
- package/dist/lib/opContext/createOpGroup.js +22 -29
- package/dist/lib/opContext/defineOp.d.ts +4 -4
- package/dist/lib/opContext/defineOp.d.ts.map +1 -1
- package/dist/lib/opContext/defineOp.js +53 -10
- package/dist/lib/opContext/opGroupTypes.d.ts +2 -2
- package/dist/lib/opContext/opTypes.d.ts +1 -1
- package/dist/lib/opContext/opTypes.d.ts.map +1 -1
- package/dist/lib/opContext/spanContextTypes.d.ts +29 -14
- package/dist/lib/opContext/spanContextTypes.d.ts.map +1 -1
- package/dist/lib/opContext/types.d.ts +4 -4
- package/dist/lib/opContext/types.d.ts.map +1 -1
- package/dist/lib/physicalLayoutPlan.d.ts +89 -0
- package/dist/lib/physicalLayoutPlan.d.ts.map +1 -0
- package/dist/lib/physicalLayoutPlan.js +442 -0
- package/dist/lib/resolveMessage.d.ts +9 -0
- package/dist/lib/resolveMessage.d.ts.map +1 -0
- package/dist/lib/resolveMessage.js +63 -0
- package/dist/lib/result.d.ts +5 -7
- package/dist/lib/result.d.ts.map +1 -1
- package/dist/lib/result.js +19 -26
- package/dist/lib/runtimeHint.d.ts +35 -0
- package/dist/lib/runtimeHint.d.ts.map +1 -0
- package/dist/lib/runtimeHint.js +79 -0
- package/dist/lib/schema/types.d.ts +1 -1
- package/dist/lib/schema/types.d.ts.map +1 -1
- package/dist/lib/span-buffer/aot/v1.d.ts +2 -0
- package/dist/lib/span-buffer/aot/v1.d.ts.map +1 -0
- package/dist/lib/span-buffer/aot/v1.js +24 -0
- package/dist/lib/spanBuffer.d.ts +33 -4
- package/dist/lib/spanBuffer.d.ts.map +1 -1
- package/dist/lib/spanBuffer.js +583 -91
- package/dist/lib/spanBufferStats.d.ts +1 -1
- package/dist/lib/spanBufferStats.d.ts.map +1 -1
- package/dist/lib/spanContext.d.ts +27 -51
- package/dist/lib/spanContext.d.ts.map +1 -1
- package/dist/lib/spanContext.js +822 -344
- package/dist/lib/sqlite/sqlite-common.d.ts.map +1 -1
- package/dist/lib/sqlite/sqlite-common.js +20 -21
- package/dist/lib/testing/bun-harness.d.ts +8 -3
- package/dist/lib/testing/bun-harness.d.ts.map +1 -1
- package/dist/lib/testing/bun-harness.js +30 -18
- package/dist/lib/testing/extractFacts.d.ts +1 -1
- package/dist/lib/testing/extractFacts.d.ts.map +1 -1
- package/dist/lib/testing/extractFacts.js +55 -63
- package/dist/lib/testing/facts.d.ts +1 -1
- package/dist/lib/testing/facts.d.ts.map +1 -1
- package/dist/lib/testing/queryable-span.d.ts +1 -1
- package/dist/lib/testing/queryable-span.d.ts.map +1 -1
- package/dist/lib/testing/queryable-span.js +26 -28
- package/dist/lib/testing/span-query.d.ts.map +1 -1
- package/dist/lib/testing/span-query.js +19 -22
- package/dist/lib/testing/stdio-replay.d.ts.map +1 -1
- package/dist/lib/testing/stdio-replay.js +19 -8
- package/dist/lib/threadId.d.ts.map +1 -1
- package/dist/lib/threadId.js +6 -3
- package/dist/lib/traceRoot.d.ts +30 -8
- package/dist/lib/traceRoot.d.ts.map +1 -1
- package/dist/lib/traceRoot.es.d.ts +17 -15
- package/dist/lib/traceRoot.es.d.ts.map +1 -1
- package/dist/lib/traceRoot.es.js +68 -34
- package/dist/lib/traceRoot.js +11 -0
- package/dist/lib/traceRoot.node.d.ts +17 -19
- package/dist/lib/traceRoot.node.d.ts.map +1 -1
- package/dist/lib/traceRoot.node.js +66 -38
- package/dist/lib/traceTopology.d.ts +42 -0
- package/dist/lib/traceTopology.d.ts.map +1 -0
- package/dist/lib/traceTopology.js +260 -0
- package/dist/lib/tracer.d.ts +9 -5
- package/dist/lib/tracer.d.ts.map +1 -1
- package/dist/lib/tracer.js +65 -71
- package/dist/lib/tracers/ArrayQueueTracer.d.ts +1 -1
- package/dist/lib/tracers/ArrayQueueTracer.js +1 -1
- package/dist/lib/tracers/StdioTracer.d.ts.map +1 -1
- package/dist/lib/tracers/StdioTracer.js +15 -13
- package/dist/lib/tracers/TestTracer.d.ts +4 -6
- package/dist/lib/tracers/TestTracer.d.ts.map +1 -1
- package/dist/lib/tracers/TestTracer.js +6 -8
- package/dist/lib/types.d.ts +49 -32
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/vocabularyRegistry.d.ts +25 -0
- package/dist/lib/vocabularyRegistry.d.ts.map +1 -0
- package/dist/lib/vocabularyRegistry.js +372 -0
- package/dist/lib/wasm/WasmBufferStrategy.d.ts +6 -10
- package/dist/lib/wasm/WasmBufferStrategy.d.ts.map +1 -1
- package/dist/lib/wasm/WasmBufferStrategy.js +44 -37
- package/dist/lib/wasm/wasmAllocator.d.ts +27 -22
- package/dist/lib/wasm/wasmAllocator.d.ts.map +1 -1
- package/dist/lib/wasm/wasmAllocator.js +66 -44
- package/dist/lib/wasm/wasmPhysicalLayout.d.ts +67 -0
- package/dist/lib/wasm/wasmPhysicalLayout.d.ts.map +1 -0
- package/dist/lib/wasm/wasmPhysicalLayout.js +179 -0
- package/dist/lib/wasm/wasmSpanBuffer.d.ts +79 -31
- package/dist/lib/wasm/wasmSpanBuffer.d.ts.map +1 -1
- package/dist/lib/wasm/wasmSpanBuffer.js +442 -272
- package/dist/lib/wasm/wasmTraceRoot.d.ts +24 -22
- package/dist/lib/wasm/wasmTraceRoot.d.ts.map +1 -1
- package/dist/lib/wasm/wasmTraceRoot.js +110 -71
- package/dist/vocabulary/register/v1.d.ts +2 -0
- package/dist/vocabulary/register/v1.d.ts.map +1 -0
- package/dist/vocabulary/register/v1.js +1 -0
- package/dist/wasm.d.ts +5 -0
- package/dist/wasm.d.ts.map +1 -0
- package/dist/wasm.js +4 -0
- package/package.json +54 -6
- package/src/index.ts +1 -0
- package/src/lib/JsBufferStrategy.ts +27 -9
- package/src/lib/__tests__/arrow-builder-integration/arrow-conversion.test.ts +335 -37
- package/src/lib/__tests__/arrow-builder-integration/binary-arrow-conversion.test.ts +97 -26
- package/src/lib/__tests__/arrow-builder-integration/binary-comparison.test.ts +75 -15
- package/src/lib/__tests__/arrow-builder-integration/binary-format-compliance.test.ts +30 -6
- package/src/lib/__tests__/arrow-builder-integration/buffer-chaining.test.ts +18 -21
- package/src/lib/__tests__/arrow-builder-integration/foundation.test.ts +5 -2
- package/src/lib/__tests__/arrow-builder-integration/integration.test.ts +25 -7
- package/src/lib/__tests__/arrow-builder-integration/lazy-columns.test.ts +3 -2
- package/src/lib/__tests__/buffer-overflow.test.ts +24 -18
- package/src/lib/__tests__/capability-span-context.test.ts +505 -0
- package/src/lib/__tests__/capacity-tuning.test.ts +5 -3
- package/src/lib/__tests__/eager-columns.test.ts +345 -0
- package/src/lib/__tests__/enum-metadata-aot.test.ts +153 -0
- package/src/lib/__tests__/enum-metadata.test.ts +177 -0
- package/src/lib/__tests__/fixtures/empty-vocabulary-runtime.fixture.ts +15 -0
- package/src/lib/__tests__/flushScheduler.test.ts +5 -1
- package/src/lib/__tests__/identity-view.property.test.ts +179 -0
- package/src/lib/__tests__/library.test.ts +19 -235
- package/src/lib/__tests__/message-buffer-families.test.ts +878 -0
- package/src/lib/__tests__/nested-library-tasks.test.ts +14 -15
- package/src/lib/__tests__/op-metadata.test.ts +1 -1
- package/src/lib/__tests__/op-type-safety.test.ts +5 -16
- package/src/lib/__tests__/physical-layout-plan.test.ts +333 -0
- package/src/lib/__tests__/remap-descriptor-integration.test.ts +381 -0
- package/src/lib/__tests__/root-context-construction.test.ts +414 -0
- package/src/lib/__tests__/span-auto-runtime.test.ts +386 -0
- package/src/lib/__tests__/span-buffer-segment-stats.test.ts +221 -0
- package/src/lib/__tests__/span-lifecycle.test.ts +53 -25
- package/src/lib/__tests__/spanbuffer-materializer-parity.test.ts +266 -0
- package/src/lib/__tests__/sync-async-trace.test.ts +24 -23
- package/src/lib/__tests__/tag-writer-aot.test.ts +214 -0
- package/src/lib/__tests__/test-helpers.ts +67 -12
- package/src/lib/__tests__/threadId.test.ts +62 -0
- package/src/lib/__tests__/timestamp.test.ts +221 -93
- package/src/lib/__tests__/traceTopology.property.test.ts +383 -0
- package/src/lib/__tests__/type-narrowing.test.ts +63 -0
- package/src/lib/__tests__/vocabulary-dense-decoding.test.ts +405 -0
- package/src/lib/__tests__/vocabularyRegistry.test.ts +313 -0
- package/src/lib/arrow/lease.ts +43 -0
- package/src/lib/arrow/utils.ts +10 -14
- package/src/lib/arrow/vocabularyDictionary.ts +123 -0
- package/src/lib/bufferStrategy.ts +9 -1
- package/src/lib/cloudflare/traceRows.ts +3 -2
- package/src/lib/codegen/__tests__/evaluatorGenerator.test.ts +21 -141
- package/src/lib/codegen/__tests__/fixedPositionWriter-parity.test.ts +273 -0
- package/src/lib/codegen/__tests__/fixedPositionWriter-uint64.test.ts +61 -34
- package/src/lib/codegen/__tests__/nullBitmap.test.ts +33 -37
- package/src/lib/codegen/__tests__/spanLoggerGenerator.test.ts +34 -18
- package/src/lib/codegen/__tests__/spanLoggerMaterializerParity.test.ts +503 -0
- package/src/lib/codegen/evaluatorGenerator.ts +18 -13
- package/src/lib/codegen/fixedPositionWriterGenerator.ts +329 -245
- package/src/lib/codegen/spanLoggerClosureMaterializer.ts +598 -0
- package/src/lib/codegen/spanLoggerGenerator.ts +241 -177
- package/src/lib/convertToArrow.ts +598 -311
- package/src/lib/defineOpContext.ts +1 -1
- package/src/lib/enumMetadata.ts +121 -0
- package/src/lib/flushScheduler.ts +11 -5
- package/src/lib/library.ts +37 -595
- package/src/lib/logBinding.ts +21 -27
- package/src/lib/op.ts +75 -18
- package/src/lib/opContext/__tests__/retry.test.ts +27 -21
- package/src/lib/opContext/createOpGroup.ts +33 -31
- package/src/lib/opContext/defineOp.ts +88 -11
- package/src/lib/opContext/opGroupTypes.ts +2 -2
- package/src/lib/opContext/opTypes.ts +1 -1
- package/src/lib/opContext/spanContextTypes.ts +98 -17
- package/src/lib/opContext/types.ts +7 -3
- package/src/lib/physicalLayoutPlan.ts +598 -0
- package/src/lib/resolveMessage.ts +67 -0
- package/src/lib/result.ts +20 -33
- package/src/lib/runtimeHint.ts +98 -0
- package/src/lib/schema/__tests__/featureFlags.test.ts +2 -1
- package/src/lib/schema/builder.ts +1 -1
- package/src/lib/schema/types.ts +1 -1
- package/src/lib/span-buffer/aot/v1.ts +26 -0
- package/src/lib/spanBuffer.ts +658 -92
- package/src/lib/spanBufferStats.ts +1 -1
- package/src/lib/spanContext.ts +1350 -861
- package/src/lib/sqlite/sqlite-common.ts +20 -31
- package/src/lib/testing/__tests__/topology-traversal.test.ts +174 -0
- package/src/lib/testing/__tests__/vitest-harness.test.ts +2 -1
- package/src/lib/testing/bun-harness.ts +94 -43
- package/src/lib/testing/extractFacts.ts +64 -78
- package/src/lib/testing/facts.ts +1 -1
- package/src/lib/testing/queryable-span.ts +23 -30
- package/src/lib/testing/span-query.ts +16 -20
- package/src/lib/testing/stdio-replay.ts +25 -8
- package/src/lib/testing/vitest-harness.ts +1 -1
- package/src/lib/threadId.ts +6 -3
- package/src/lib/traceRoot.es.ts +77 -42
- package/src/lib/traceRoot.node.ts +75 -46
- package/src/lib/traceRoot.ts +41 -14
- package/src/lib/traceTopology.ts +279 -0
- package/src/lib/tracer.ts +109 -98
- package/src/lib/tracers/ArrayQueueTracer.ts +1 -1
- package/src/lib/tracers/StdioTracer.ts +15 -13
- package/src/lib/tracers/TestTracer.ts +6 -8
- package/src/lib/tracers/__tests__/ArrayQueueTracer.test.ts +15 -10
- package/src/lib/tracers/__tests__/TestTracer.test.ts +23 -13
- package/src/lib/types.ts +64 -33
- package/src/lib/vocabularyRegistry.ts +439 -0
- package/src/lib/wasm/WasmBufferStrategy.ts +56 -48
- package/src/lib/wasm/__tests__/WasmBufferStrategy.test.ts +215 -11
- package/src/lib/wasm/__tests__/allocatorFreeBlockClamp.test.ts +86 -0
- package/src/lib/wasm/__tests__/wasm-identity-view.test.ts +311 -0
- package/src/lib/wasm/__tests__/wasm-integration.test.ts +417 -44
- package/src/lib/wasm/__tests__/wasm-message-buffer-families.test.ts +588 -0
- package/src/lib/wasm/__tests__/wasmAllocator.test.ts +100 -668
- package/src/lib/wasm/__tests__/wasmSpanBuffer.test.ts +419 -63
- package/src/lib/wasm/__tests__/wasmTraceRoot.test.ts +24 -29
- package/src/lib/wasm/__tests__/wasmTracer.test.ts.disabled +2 -2
- package/src/lib/wasm/wasmAllocator.ts +131 -96
- package/src/lib/wasm/wasmPhysicalLayout.ts +309 -0
- package/src/lib/wasm/wasmSpanBuffer.ts +597 -341
- package/src/lib/wasm/wasmTraceRoot.ts +140 -78
- package/src/vocabulary/register/v1.ts +1 -0
- package/src/wasm.ts +19 -0
- package/src/lib/__tests__/remapped-buffer-view-integration.test.ts +0 -319
- package/src/lib/__tests__/remapped-buffer-view.test.ts +0 -635
- package/src/lib/wasm/allocator.zig +0 -948
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* @module testing/extractFacts
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
import { resolveEntryType, resolveMessage } from '../resolveMessage.js';
|
|
10
11
|
import type { LogSchema } from '../schema/LogSchema.js';
|
|
11
12
|
import {
|
|
12
13
|
ENTRY_TYPE_DEBUG,
|
|
@@ -17,8 +18,10 @@ import {
|
|
|
17
18
|
ENTRY_TYPE_SPAN_ERR,
|
|
18
19
|
ENTRY_TYPE_SPAN_EXCEPTION,
|
|
19
20
|
ENTRY_TYPE_SPAN_OK,
|
|
21
|
+
ENTRY_TYPE_TRACE,
|
|
20
22
|
ENTRY_TYPE_WARN,
|
|
21
23
|
} from '../schema/systemSchema.js';
|
|
24
|
+
import { iterateSpanChildren } from '../traceTopology.js';
|
|
22
25
|
import type { SpanBuffer } from '../types.js';
|
|
23
26
|
import {
|
|
24
27
|
createFactArray,
|
|
@@ -106,12 +109,17 @@ const DEFAULT_OPTIONS: Required<ExtractFactsOptions> = {
|
|
|
106
109
|
tagFields: [],
|
|
107
110
|
};
|
|
108
111
|
|
|
112
|
+
type WalkFrame<T extends LogSchema> = {
|
|
113
|
+
buffer: SpanBuffer<T>;
|
|
114
|
+
children?: Generator<SpanBuffer<T>>;
|
|
115
|
+
};
|
|
116
|
+
|
|
109
117
|
/**
|
|
110
118
|
* Extract facts from a SpanBuffer tree.
|
|
111
119
|
*
|
|
112
120
|
* Walks the buffer tree depth-first and produces facts for:
|
|
113
121
|
* - Span lifecycle (started, ok, err, exception)
|
|
114
|
-
* - Log entries (info, warn, error
|
|
122
|
+
* - Log entries (trace, debug, info, warn, error)
|
|
115
123
|
* - Tag values (from row 0 of each span)
|
|
116
124
|
* - Scope values (propagated through tree)
|
|
117
125
|
* - Feature flag accesses
|
|
@@ -138,7 +146,29 @@ export function extractFacts<T extends LogSchema>(
|
|
|
138
146
|
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
139
147
|
const facts: TraceFact[] = [];
|
|
140
148
|
|
|
141
|
-
|
|
149
|
+
const stack: WalkFrame<T>[] = [{ buffer: rootBuffer }];
|
|
150
|
+
while (stack.length > 0) {
|
|
151
|
+
const frame = stack[stack.length - 1];
|
|
152
|
+
if (!frame) break;
|
|
153
|
+
|
|
154
|
+
if (!frame.children) {
|
|
155
|
+
if (frame.buffer._writeIndex === 0) {
|
|
156
|
+
stack.pop();
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
enterBuffer(frame.buffer, facts, opts);
|
|
160
|
+
frame.children = iterateSpanChildren(frame.buffer);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const next = frame.children.next();
|
|
164
|
+
if (!next.done) {
|
|
165
|
+
stack.push({ buffer: next.value });
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
leaveBuffer(frame.buffer, facts, opts);
|
|
170
|
+
stack.pop();
|
|
171
|
+
}
|
|
142
172
|
|
|
143
173
|
return createFactArray(facts);
|
|
144
174
|
}
|
|
@@ -146,112 +176,67 @@ export function extractFacts<T extends LogSchema>(
|
|
|
146
176
|
/**
|
|
147
177
|
* Walk a buffer and its children, extracting facts.
|
|
148
178
|
*/
|
|
149
|
-
function
|
|
179
|
+
function enterBuffer<T extends LogSchema>(
|
|
150
180
|
buffer: SpanBuffer<T>,
|
|
151
181
|
facts: TraceFact[],
|
|
152
182
|
opts: Required<ExtractFactsOptions>,
|
|
153
183
|
): void {
|
|
154
|
-
|
|
155
|
-
const spanName = buffer.message_values[0];
|
|
184
|
+
const spanName = resolveMessage(buffer, 0) ?? '';
|
|
156
185
|
const writeIndex = buffer._writeIndex;
|
|
186
|
+
if (writeIndex === 0) return;
|
|
157
187
|
|
|
158
|
-
if (writeIndex === 0) {
|
|
159
|
-
// Empty buffer - no facts to extract
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// Always emit span:started as first fact for this span
|
|
164
188
|
facts.push(spanStarted(spanName));
|
|
165
|
-
|
|
166
|
-
// Extract scope facts (from buffer's scope values)
|
|
167
189
|
if (opts.includeScope && buffer._scopeValues) {
|
|
168
190
|
for (const [key, value] of Object.entries(buffer._scopeValues)) {
|
|
169
|
-
if (value !== undefined && value !== null)
|
|
170
|
-
facts.push(scopeFact(key, String(value)));
|
|
171
|
-
}
|
|
191
|
+
if (value !== undefined && value !== null) facts.push(scopeFact(key, String(value)));
|
|
172
192
|
}
|
|
173
193
|
}
|
|
174
|
-
|
|
175
|
-
// Extract tag facts from row 0 (ctx.tag writes here)
|
|
176
|
-
// Also check row 1 (completion row - .with() on ok()/err())
|
|
177
|
-
// And rows 2+ (log rows - .with() on log.*)
|
|
178
194
|
if (opts.includeTags) {
|
|
179
|
-
for (let row = 0; row < writeIndex; row++)
|
|
180
|
-
extractTagFacts(buffer, row, facts, opts);
|
|
181
|
-
}
|
|
195
|
+
for (let row = 0; row < writeIndex; row++) extractTagFacts(buffer, row, facts, opts);
|
|
182
196
|
}
|
|
183
197
|
|
|
184
|
-
// Buffer layout per specs/lmao/01h_entry_types_and_logging_primitives.md:
|
|
185
|
-
// - Row 0: span-start (tags overwrite this row's attribute columns)
|
|
186
|
-
// - Row 1: span-ok/err/exception (completion status)
|
|
187
|
-
// - Row 2+: log entries (info/debug/warn/error), ff entries
|
|
188
|
-
const entryTypes = buffer.entry_type;
|
|
189
|
-
const messages = buffer.message_values;
|
|
190
|
-
|
|
191
|
-
// Process log/ff entries from row 2 onwards
|
|
192
198
|
for (let row = 2; row < writeIndex; row++) {
|
|
193
|
-
const entryType =
|
|
194
|
-
|
|
199
|
+
const entryType = resolveEntryType(buffer, row);
|
|
195
200
|
switch (entryType) {
|
|
196
201
|
case ENTRY_TYPE_INFO:
|
|
197
202
|
case ENTRY_TYPE_DEBUG:
|
|
198
203
|
case ENTRY_TYPE_WARN:
|
|
199
|
-
case ENTRY_TYPE_ERROR:
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
const rowMessage = messages[row];
|
|
203
|
-
const message = typeof rowMessage === 'string' ? rowMessage : '';
|
|
204
|
-
facts.push(logFact(level, message));
|
|
205
|
-
}
|
|
204
|
+
case ENTRY_TYPE_ERROR:
|
|
205
|
+
case ENTRY_TYPE_TRACE:
|
|
206
|
+
if (opts.includeLogs) facts.push(logFact(entryTypeToLogLevel(entryType), resolveMessage(buffer, row) ?? ''));
|
|
206
207
|
break;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
208
|
case ENTRY_TYPE_FF_ACCESS:
|
|
210
|
-
case ENTRY_TYPE_FF_USAGE:
|
|
211
|
-
if (opts.includeFF)
|
|
212
|
-
extractFFfacts(buffer, row, facts);
|
|
213
|
-
}
|
|
209
|
+
case ENTRY_TYPE_FF_USAGE:
|
|
210
|
+
if (opts.includeFF) extractFFfacts(buffer, row, facts);
|
|
214
211
|
break;
|
|
215
|
-
}
|
|
216
212
|
}
|
|
217
213
|
}
|
|
214
|
+
}
|
|
218
215
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
216
|
+
function leaveBuffer<T extends LogSchema>(
|
|
217
|
+
buffer: SpanBuffer<T>,
|
|
218
|
+
facts: TraceFact[],
|
|
219
|
+
opts: Required<ExtractFactsOptions>,
|
|
220
|
+
): void {
|
|
221
|
+
const writeIndex = buffer._writeIndex;
|
|
222
|
+
if (writeIndex === 0) return;
|
|
223
|
+
const spanName = resolveMessage(buffer, 0) ?? '';
|
|
227
224
|
if (writeIndex >= 2) {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
switch (completionEntryType) {
|
|
225
|
+
switch (resolveEntryType(buffer, 1)) {
|
|
231
226
|
case ENTRY_TYPE_SPAN_OK:
|
|
232
227
|
facts.push(spanOk(spanName));
|
|
233
228
|
break;
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
const errorCode = getErrorCode(buffer, 1);
|
|
237
|
-
facts.push(spanErr(spanName, errorCode));
|
|
229
|
+
case ENTRY_TYPE_SPAN_ERR:
|
|
230
|
+
facts.push(spanErr(spanName, getErrorCode(buffer, 1)));
|
|
238
231
|
break;
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
case ENTRY_TYPE_SPAN_EXCEPTION: {
|
|
242
|
-
const message = getExceptionMessage(buffer, 1);
|
|
243
|
-
facts.push(spanException(spanName, message));
|
|
232
|
+
case ENTRY_TYPE_SPAN_EXCEPTION:
|
|
233
|
+
facts.push(spanException(spanName, getExceptionMessage(buffer, 1)));
|
|
244
234
|
break;
|
|
245
|
-
}
|
|
246
235
|
}
|
|
247
236
|
}
|
|
248
|
-
|
|
249
|
-
// Extract duration metric if requested
|
|
250
237
|
if (opts.includeMetrics) {
|
|
251
238
|
const duration = getSpanDuration(buffer);
|
|
252
|
-
if (duration !== undefined) {
|
|
253
|
-
facts.push(metricFact(`${spanName}:duration_ns`, Number(duration)));
|
|
254
|
-
}
|
|
239
|
+
if (duration !== undefined) facts.push(metricFact(`${spanName}:duration_ns`, Number(duration)));
|
|
255
240
|
}
|
|
256
241
|
}
|
|
257
242
|
|
|
@@ -269,7 +254,7 @@ function extractTagFacts<T extends LogSchema>(
|
|
|
269
254
|
|
|
270
255
|
for (const fieldName of fields) {
|
|
271
256
|
// Skip system fields
|
|
272
|
-
if (fieldName.startsWith('_')) continue;
|
|
257
|
+
if (fieldName === 'message' || fieldName.startsWith('_')) continue;
|
|
273
258
|
|
|
274
259
|
const nullsKey = `${fieldName}_nulls`;
|
|
275
260
|
const valuesKey = `${fieldName}_values`;
|
|
@@ -294,10 +279,10 @@ function extractTagFacts<T extends LogSchema>(
|
|
|
294
279
|
*/
|
|
295
280
|
function extractFFfacts<T extends LogSchema>(buffer: SpanBuffer<T>, row: number, facts: TraceFact[]): void {
|
|
296
281
|
// Feature flag entries store the flag name in message_values and the resolved value in ff_value_values.
|
|
297
|
-
const name = buffer
|
|
282
|
+
const name = resolveMessage(buffer, row);
|
|
298
283
|
const value = buffer.ff_value_values[row];
|
|
299
284
|
|
|
300
|
-
if (
|
|
285
|
+
if (name !== undefined && typeof value === 'string') {
|
|
301
286
|
facts.push(ffFact(name, value));
|
|
302
287
|
}
|
|
303
288
|
}
|
|
@@ -316,6 +301,8 @@ function isNull(nulls: Uint8Array, index: number): boolean {
|
|
|
316
301
|
*/
|
|
317
302
|
function entryTypeToLogLevel(entryType: number): LogLevel {
|
|
318
303
|
switch (entryType) {
|
|
304
|
+
case ENTRY_TYPE_TRACE:
|
|
305
|
+
return 'trace';
|
|
319
306
|
case ENTRY_TYPE_DEBUG:
|
|
320
307
|
return 'debug';
|
|
321
308
|
case ENTRY_TYPE_INFO:
|
|
@@ -341,8 +328,7 @@ function getErrorCode<T extends LogSchema>(buffer: SpanBuffer<T>, row: number):
|
|
|
341
328
|
* Get exception message from a span-exception row.
|
|
342
329
|
*/
|
|
343
330
|
function getExceptionMessage<T extends LogSchema>(buffer: SpanBuffer<T>, row: number): string {
|
|
344
|
-
|
|
345
|
-
return typeof message === 'string' ? message : 'Unknown exception';
|
|
331
|
+
return resolveMessage(buffer, row) ?? 'Unknown exception';
|
|
346
332
|
}
|
|
347
333
|
|
|
348
334
|
/**
|
package/src/lib/testing/facts.ts
CHANGED
|
@@ -88,7 +88,7 @@ export function spanException<N extends string, M extends string>(name: N, messa
|
|
|
88
88
|
/**
|
|
89
89
|
* Log levels.
|
|
90
90
|
*/
|
|
91
|
-
export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
91
|
+
export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error';
|
|
92
92
|
|
|
93
93
|
/**
|
|
94
94
|
* A log fact: `log:${level}: ${message}`
|
|
@@ -15,13 +15,15 @@
|
|
|
15
15
|
* @module queryable-span
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
+
import { resolveMessage } from '../resolveMessage.js';
|
|
18
19
|
import type { LogSchema } from '../schema/LogSchema.js';
|
|
20
|
+
import { iterateSpanChildren, iterateSpanTree } from '../traceTopology.js';
|
|
19
21
|
import type { SpanBuffer } from '../types.js';
|
|
20
22
|
import { type ExtractFactsOptions, extractFacts } from './extractFacts.js';
|
|
21
23
|
import type { FactArray } from './facts.js';
|
|
22
24
|
|
|
23
25
|
export interface QueryableSpan<T extends LogSchema = LogSchema> {
|
|
24
|
-
/**
|
|
26
|
+
/** Resolved span name. */
|
|
25
27
|
readonly name: string;
|
|
26
28
|
|
|
27
29
|
/** Extract all facts from this span and its children */
|
|
@@ -52,7 +54,7 @@ class QueryableSpanImpl<T extends LogSchema> implements QueryableSpan<T> {
|
|
|
52
54
|
constructor(readonly buffer: SpanBuffer<T>) {}
|
|
53
55
|
|
|
54
56
|
get name(): string {
|
|
55
|
-
return this.buffer
|
|
57
|
+
return resolveMessage(this.buffer, 0) ?? '';
|
|
56
58
|
}
|
|
57
59
|
|
|
58
60
|
facts(options?: ExtractFactsOptions): FactArray {
|
|
@@ -60,49 +62,40 @@ class QueryableSpanImpl<T extends LogSchema> implements QueryableSpan<T> {
|
|
|
60
62
|
}
|
|
61
63
|
|
|
62
64
|
find(name: string): QueryableSpan<T> | undefined {
|
|
63
|
-
|
|
65
|
+
for (const descendant of iterateDescendantSpans(this.buffer)) {
|
|
66
|
+
if (resolveMessage(descendant, 0) === name) return new QueryableSpanImpl(descendant);
|
|
67
|
+
}
|
|
68
|
+
return undefined;
|
|
64
69
|
}
|
|
65
70
|
|
|
66
71
|
findAll(name: string): QueryableSpan<T>[] {
|
|
67
72
|
const results: QueryableSpan<T>[] = [];
|
|
68
|
-
|
|
73
|
+
for (const descendant of iterateDescendantSpans(this.buffer)) {
|
|
74
|
+
if (resolveMessage(descendant, 0) === name) results.push(new QueryableSpanImpl(descendant));
|
|
75
|
+
}
|
|
69
76
|
return results;
|
|
70
77
|
}
|
|
71
78
|
|
|
72
79
|
get children(): QueryableSpan<T>[] {
|
|
73
|
-
|
|
80
|
+
const result: QueryableSpan<T>[] = [];
|
|
81
|
+
for (const child of iterateSpanChildren(this.buffer)) result.push(new QueryableSpanImpl(child));
|
|
82
|
+
return result;
|
|
74
83
|
}
|
|
75
84
|
|
|
76
85
|
names(): string[] {
|
|
77
86
|
const result: string[] = [];
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function findInChildren<T extends LogSchema>(children: SpanBuffer<T>[], name: string): QueryableSpan<T> | undefined {
|
|
84
|
-
for (const child of children) {
|
|
85
|
-
if (child.message_values[0] === name) {
|
|
86
|
-
return new QueryableSpanImpl(child);
|
|
87
|
-
}
|
|
88
|
-
const found = findInChildren(child._children as SpanBuffer<T>[], name);
|
|
89
|
-
if (found) return found;
|
|
90
|
-
}
|
|
91
|
-
return undefined;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function collectAll<T extends LogSchema>(children: SpanBuffer<T>[], name: string, results: QueryableSpan<T>[]): void {
|
|
95
|
-
for (const child of children) {
|
|
96
|
-
if (child.message_values[0] === name) {
|
|
97
|
-
results.push(new QueryableSpanImpl(child));
|
|
87
|
+
for (const descendant of iterateDescendantSpans(this.buffer)) {
|
|
88
|
+
result.push(resolveMessage(descendant, 0) ?? '');
|
|
98
89
|
}
|
|
99
|
-
|
|
90
|
+
return result;
|
|
100
91
|
}
|
|
101
92
|
}
|
|
102
93
|
|
|
103
|
-
function
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
94
|
+
function* iterateDescendantSpans<T extends LogSchema>(root: SpanBuffer<T>): Generator<SpanBuffer<T>> {
|
|
95
|
+
let previousNodeIndex = root._nodeIndex;
|
|
96
|
+
for (const buffer of iterateSpanTree(root)) {
|
|
97
|
+
if (buffer._nodeIndex === previousNodeIndex) continue;
|
|
98
|
+
previousNodeIndex = buffer._nodeIndex;
|
|
99
|
+
yield buffer;
|
|
107
100
|
}
|
|
108
101
|
}
|
|
@@ -7,18 +7,17 @@
|
|
|
7
7
|
* @module span-query
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
import { resolveMessage } from '../resolveMessage.js';
|
|
10
11
|
import type { LogSchema } from '../schema/LogSchema.js';
|
|
12
|
+
import { iterateSpanTree } from '../traceTopology.js';
|
|
11
13
|
import type { SpanBuffer } from '../types.js';
|
|
12
14
|
import { type ExtractFactsOptions, extractFacts } from './extractFacts.js';
|
|
13
15
|
import type { FactArray } from './facts.js';
|
|
14
16
|
|
|
15
17
|
/** Find first descendant span by name (depth-first) */
|
|
16
18
|
export function findSpan<T extends LogSchema>(root: SpanBuffer<T>, name: string): SpanBuffer<T> | undefined {
|
|
17
|
-
for (const
|
|
18
|
-
|
|
19
|
-
if (typed.message_values[0] === name) return typed;
|
|
20
|
-
const found = findSpan(typed, name);
|
|
21
|
-
if (found) return found;
|
|
19
|
+
for (const descendant of iterateDescendantSpans(root)) {
|
|
20
|
+
if (resolveMessage(descendant, 0) === name) return descendant;
|
|
22
21
|
}
|
|
23
22
|
return undefined;
|
|
24
23
|
}
|
|
@@ -26,7 +25,9 @@ export function findSpan<T extends LogSchema>(root: SpanBuffer<T>, name: string)
|
|
|
26
25
|
/** Find all descendant spans matching name (depth-first) */
|
|
27
26
|
export function findAllSpans<T extends LogSchema>(root: SpanBuffer<T>, name: string): SpanBuffer<T>[] {
|
|
28
27
|
const results: SpanBuffer<T>[] = [];
|
|
29
|
-
|
|
28
|
+
for (const descendant of iterateDescendantSpans(root)) {
|
|
29
|
+
if (resolveMessage(descendant, 0) === name) results.push(descendant);
|
|
30
|
+
}
|
|
30
31
|
return results;
|
|
31
32
|
}
|
|
32
33
|
|
|
@@ -44,22 +45,17 @@ export function extractFactsFor<T extends LogSchema>(
|
|
|
44
45
|
/** Collect all descendant span names (flat list, depth-first) */
|
|
45
46
|
export function spanNames<T extends LogSchema>(root: SpanBuffer<T>): string[] {
|
|
46
47
|
const result: string[] = [];
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function collectSpans<T extends LogSchema>(root: SpanBuffer<T>, name: string, results: SpanBuffer<T>[]): void {
|
|
52
|
-
for (const child of root._children) {
|
|
53
|
-
const typed = child as SpanBuffer<T>;
|
|
54
|
-
if (typed.message_values[0] === name) results.push(typed);
|
|
55
|
-
collectSpans(typed, name, results);
|
|
48
|
+
for (const descendant of iterateDescendantSpans(root)) {
|
|
49
|
+
result.push(resolveMessage(descendant, 0) ?? '');
|
|
56
50
|
}
|
|
51
|
+
return result;
|
|
57
52
|
}
|
|
58
53
|
|
|
59
|
-
function
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
54
|
+
function* iterateDescendantSpans<T extends LogSchema>(root: SpanBuffer<T>): Generator<SpanBuffer<T>> {
|
|
55
|
+
let previousNodeIndex = root._nodeIndex;
|
|
56
|
+
for (const buffer of iterateSpanTree(root)) {
|
|
57
|
+
if (buffer._nodeIndex === previousNodeIndex) continue;
|
|
58
|
+
previousNodeIndex = buffer._nodeIndex;
|
|
59
|
+
yield buffer;
|
|
64
60
|
}
|
|
65
61
|
}
|
|
@@ -2,6 +2,7 @@ import { JsBufferStrategy } from '../JsBufferStrategy.js';
|
|
|
2
2
|
import type { OpContextBinding } from '../opContext/types.js';
|
|
3
3
|
import { createTraceRoot } from '../traceRoot.universal.js';
|
|
4
4
|
import { StdioTracer, type StdioWritable } from '../tracers/StdioTracer.js';
|
|
5
|
+
import { iterateSpanChildren } from '../traceTopology.js';
|
|
5
6
|
import type { AnySpanBuffer } from '../types.js';
|
|
6
7
|
|
|
7
8
|
function isStdioWritable(value: unknown): value is StdioWritable {
|
|
@@ -16,13 +17,31 @@ function makeConsoleWriteStream(write: (line: string) => void): StdioWritable {
|
|
|
16
17
|
},
|
|
17
18
|
};
|
|
18
19
|
}
|
|
20
|
+
type ReplayFrame = {
|
|
21
|
+
buffer: AnySpanBuffer;
|
|
22
|
+
children: Generator<AnySpanBuffer>;
|
|
23
|
+
replayLifecycle: boolean;
|
|
24
|
+
};
|
|
19
25
|
|
|
20
|
-
function
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
26
|
+
function replayChildSpans(tracer: StdioTracer<OpContextBinding>, rootBuffer: AnySpanBuffer): void {
|
|
27
|
+
const stack: ReplayFrame[] = [
|
|
28
|
+
{ buffer: rootBuffer, children: iterateSpanChildren(rootBuffer), replayLifecycle: false },
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
while (stack.length > 0) {
|
|
32
|
+
const frame = stack[stack.length - 1];
|
|
33
|
+
if (!frame) break;
|
|
34
|
+
|
|
35
|
+
const next = frame.children.next();
|
|
36
|
+
if (!next.done) {
|
|
37
|
+
tracer.onSpanStart(next.value);
|
|
38
|
+
stack.push({ buffer: next.value, children: iterateSpanChildren(next.value), replayLifecycle: true });
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
stack.pop();
|
|
43
|
+
if (frame.replayLifecycle) tracer.onSpanEnd(frame.buffer);
|
|
24
44
|
}
|
|
25
|
-
tracer.onSpanEnd(buffer);
|
|
26
45
|
}
|
|
27
46
|
|
|
28
47
|
export function replayTraceToStdio(binding: OpContextBinding, rootBuffer: AnySpanBuffer): void {
|
|
@@ -43,8 +62,6 @@ export function replayTraceToStdio(binding: OpContextBinding, rootBuffer: AnySpa
|
|
|
43
62
|
});
|
|
44
63
|
|
|
45
64
|
tracer.onTraceStart(rootBuffer);
|
|
46
|
-
|
|
47
|
-
replayChildSpan(tracer, child);
|
|
48
|
-
}
|
|
65
|
+
replayChildSpans(tracer, rootBuffer);
|
|
49
66
|
tracer.onTraceEnd(rootBuffer);
|
|
50
67
|
}
|
|
@@ -323,7 +323,7 @@ function createRootTracer<B extends OpContextBinding>({
|
|
|
323
323
|
});
|
|
324
324
|
}
|
|
325
325
|
|
|
326
|
-
async function closeTracer(tracer: Tracer<
|
|
326
|
+
async function closeTracer<B extends OpContextBinding>(tracer: Tracer<B>): Promise<void> {
|
|
327
327
|
const close = Reflect.get(tracer, 'close');
|
|
328
328
|
if (typeof close === 'function') {
|
|
329
329
|
await close.call(tracer);
|
package/src/lib/threadId.ts
CHANGED
|
@@ -39,11 +39,13 @@ let threadIdBigInt: bigint | null = null;
|
|
|
39
39
|
function ensureInitialized(): void {
|
|
40
40
|
if (threadIdBytes !== null) return;
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
// Keep initialization transactional so a failed entropy provider can be retried.
|
|
43
|
+
const bytes = new Uint8Array(THREAD_ID_BYTES);
|
|
43
44
|
|
|
44
45
|
// Use Web Crypto API - available in browsers, Node 19+, Deno, Bun, Workers
|
|
45
46
|
if (typeof crypto !== 'undefined' && typeof crypto.getRandomValues === 'function') {
|
|
46
|
-
crypto.getRandomValues(
|
|
47
|
+
crypto.getRandomValues(bytes);
|
|
48
|
+
threadIdBytes = bytes;
|
|
47
49
|
return;
|
|
48
50
|
}
|
|
49
51
|
|
|
@@ -51,7 +53,8 @@ function ensureInitialized(): void {
|
|
|
51
53
|
try {
|
|
52
54
|
const nodeCrypto = require('node:crypto');
|
|
53
55
|
if (nodeCrypto && typeof nodeCrypto.randomFillSync === 'function') {
|
|
54
|
-
nodeCrypto.randomFillSync(
|
|
56
|
+
nodeCrypto.randomFillSync(bytes);
|
|
57
|
+
threadIdBytes = bytes;
|
|
55
58
|
return;
|
|
56
59
|
}
|
|
57
60
|
} catch {
|