@mastra/duckdb 1.6.4 → 1.7.0-alpha.1
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/{db-TBEcMD49.cjs → db-CJBcanx4.cjs} +27 -1
- package/dist/db-CJBcanx4.cjs.map +1 -0
- package/dist/{db-Dl0fY488.js → db-b2jufH0V.js} +27 -1
- package/dist/db-b2jufH0V.js.map +1 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/index.cjs +12 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +12 -4
- package/dist/index.js.map +1 -1
- package/dist/{observability-CT5eidI9.js → observability-Bt92lKRG.js} +396 -8
- package/dist/observability-Bt92lKRG.js.map +1 -0
- package/dist/{observability-CYOty2wB.cjs → observability-yLoG0tl3.cjs} +418 -8
- package/dist/observability-yLoG0tl3.cjs.map +1 -0
- package/dist/storage/db/index.d.ts +5 -0
- package/dist/storage/db/index.d.ts.map +1 -1
- package/dist/storage/domains/observability/index.d.ts +3 -2
- package/dist/storage/domains/observability/index.d.ts.map +1 -1
- package/dist/storage/domains/observability/scores.d.ts.map +1 -1
- package/dist/storage/domains/observability/trace-query.d.ts +9 -0
- package/dist/storage/domains/observability/trace-query.d.ts.map +1 -0
- package/dist/storage/domains/observability/tracing.d.ts +7 -1
- package/dist/storage/domains/observability/tracing.d.ts.map +1 -1
- package/dist/storage/index.d.ts +1 -0
- package/dist/storage/index.d.ts.map +1 -1
- package/package.json +3 -3
- package/dist/db-Dl0fY488.js.map +0 -1
- package/dist/db-TBEcMD49.cjs.map +0 -1
- package/dist/observability-CT5eidI9.js.map +0 -1
- package/dist/observability-CYOty2wB.cjs.map +0 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { t as DuckDBConnection } from "./db-
|
|
1
|
+
import { t as DuckDBConnection } from "./db-b2jufH0V.js";
|
|
2
2
|
import { ErrorCategory, ErrorDomain, MastraError } from "@mastra/core/error";
|
|
3
|
+
import * as coreStorage from "@mastra/core/storage";
|
|
3
4
|
import { BRANCH_SPAN_TYPES, METRIC_DISTINCT_COLUMNS, ObservabilityStorage, buildInputPreview, computeTraceStatus, createStorageErrorId, feedbackRecordSchema, listBranchesArgsSchema, listFeedbackArgsSchema, listLogsArgsSchema, listMetricsArgsSchema, listScoresArgsSchema, listTracesArgsSchema, toTraceSpans } from "@mastra/core/storage";
|
|
4
5
|
import { coreFeatures } from "@mastra/core/features";
|
|
5
6
|
import { EntityType } from "@mastra/core/observability";
|
|
@@ -2070,6 +2071,43 @@ async function migrateSignalTables(db, logger) {
|
|
|
2070
2071
|
}
|
|
2071
2072
|
//#endregion
|
|
2072
2073
|
//#region src/storage/domains/observability/scores.ts
|
|
2074
|
+
const SCORE_UPSERT_CLAUSE = `ON CONFLICT (scoreId) DO UPDATE SET ${[
|
|
2075
|
+
"timestamp",
|
|
2076
|
+
"traceId",
|
|
2077
|
+
"spanId",
|
|
2078
|
+
"experimentId",
|
|
2079
|
+
"scoreTraceId",
|
|
2080
|
+
"entityType",
|
|
2081
|
+
"entityId",
|
|
2082
|
+
"entityName",
|
|
2083
|
+
"entityVersionId",
|
|
2084
|
+
"parentEntityVersionId",
|
|
2085
|
+
"parentEntityType",
|
|
2086
|
+
"parentEntityId",
|
|
2087
|
+
"parentEntityName",
|
|
2088
|
+
"rootEntityVersionId",
|
|
2089
|
+
"rootEntityType",
|
|
2090
|
+
"rootEntityId",
|
|
2091
|
+
"rootEntityName",
|
|
2092
|
+
"userId",
|
|
2093
|
+
"organizationId",
|
|
2094
|
+
"resourceId",
|
|
2095
|
+
"runId",
|
|
2096
|
+
"sessionId",
|
|
2097
|
+
"threadId",
|
|
2098
|
+
"requestId",
|
|
2099
|
+
"environment",
|
|
2100
|
+
"executionSource",
|
|
2101
|
+
"serviceName",
|
|
2102
|
+
"scorerId",
|
|
2103
|
+
"scorerVersion",
|
|
2104
|
+
"scoreSource",
|
|
2105
|
+
"score",
|
|
2106
|
+
"reason",
|
|
2107
|
+
"tags",
|
|
2108
|
+
"metadata",
|
|
2109
|
+
"scope"
|
|
2110
|
+
].map((column) => `${column} = excluded.${column}`).join(", ")}`;
|
|
2073
2111
|
const SCORE_GROUP_BY_COLUMNS = /* @__PURE__ */ new Set([
|
|
2074
2112
|
"timestamp",
|
|
2075
2113
|
"traceId",
|
|
@@ -2278,7 +2316,7 @@ async function createScore(db, args) {
|
|
|
2278
2316
|
jsonV(s.metadata),
|
|
2279
2317
|
jsonV(s.scope ?? null)
|
|
2280
2318
|
].join(", ")})
|
|
2281
|
-
|
|
2319
|
+
${SCORE_UPSERT_CLAUSE}`);
|
|
2282
2320
|
}
|
|
2283
2321
|
/** Insert multiple score events in a single statement. */
|
|
2284
2322
|
async function batchCreateScores(db, args) {
|
|
@@ -2333,7 +2371,7 @@ async function batchCreateScores(db, args) {
|
|
|
2333
2371
|
scorerId, scorerVersion, scoreSource, score, reason, tags, metadata, scope
|
|
2334
2372
|
)
|
|
2335
2373
|
VALUES ${tuples.join(",\n ")}
|
|
2336
|
-
|
|
2374
|
+
${SCORE_UPSERT_CLAUSE}`);
|
|
2337
2375
|
}
|
|
2338
2376
|
/** Query score events with filtering, ordering, and pagination. */
|
|
2339
2377
|
async function listScores(db, args) {
|
|
@@ -2519,6 +2557,323 @@ async function getScorePercentiles(db, args) {
|
|
|
2519
2557
|
return { series };
|
|
2520
2558
|
}
|
|
2521
2559
|
//#endregion
|
|
2560
|
+
//#region src/storage/domains/observability/trace-query.ts
|
|
2561
|
+
const TRACE_STATUS_SQL = `CASE WHEN r.error IS NOT NULL THEN 'error' ELSE 'success' END`;
|
|
2562
|
+
const TRACE_FIELDS = {
|
|
2563
|
+
traceId: {
|
|
2564
|
+
sql: "r.traceId",
|
|
2565
|
+
parameterType: "scalar"
|
|
2566
|
+
},
|
|
2567
|
+
threadId: {
|
|
2568
|
+
sql: "r.threadId",
|
|
2569
|
+
parameterType: "scalar"
|
|
2570
|
+
},
|
|
2571
|
+
resourceId: {
|
|
2572
|
+
sql: "r.resourceId",
|
|
2573
|
+
parameterType: "scalar"
|
|
2574
|
+
},
|
|
2575
|
+
startedAt: {
|
|
2576
|
+
sql: "r.startedAt",
|
|
2577
|
+
parameterType: "timestamp"
|
|
2578
|
+
},
|
|
2579
|
+
endedAt: {
|
|
2580
|
+
sql: "r.endedAt",
|
|
2581
|
+
parameterType: "timestamp"
|
|
2582
|
+
},
|
|
2583
|
+
entityName: {
|
|
2584
|
+
sql: "r.entityName",
|
|
2585
|
+
parameterType: "scalar"
|
|
2586
|
+
},
|
|
2587
|
+
entityType: {
|
|
2588
|
+
sql: "r.entityType",
|
|
2589
|
+
parameterType: "scalar"
|
|
2590
|
+
},
|
|
2591
|
+
environment: {
|
|
2592
|
+
sql: "r.environment",
|
|
2593
|
+
parameterType: "scalar"
|
|
2594
|
+
},
|
|
2595
|
+
status: {
|
|
2596
|
+
sql: TRACE_STATUS_SQL,
|
|
2597
|
+
parameterType: "scalar"
|
|
2598
|
+
}
|
|
2599
|
+
};
|
|
2600
|
+
const SPAN_FIELDS = {
|
|
2601
|
+
spanType: {
|
|
2602
|
+
sql: "s.spanType",
|
|
2603
|
+
parameterType: "scalar"
|
|
2604
|
+
},
|
|
2605
|
+
error: {
|
|
2606
|
+
sql: "s.error",
|
|
2607
|
+
parameterType: "scalar"
|
|
2608
|
+
}
|
|
2609
|
+
};
|
|
2610
|
+
const SCORE_FIELDS = {
|
|
2611
|
+
scorerId: {
|
|
2612
|
+
sql: "s.scorerId",
|
|
2613
|
+
parameterType: "scalar"
|
|
2614
|
+
},
|
|
2615
|
+
score: {
|
|
2616
|
+
sql: "s.score",
|
|
2617
|
+
parameterType: "scalar"
|
|
2618
|
+
}
|
|
2619
|
+
};
|
|
2620
|
+
const TRACE_SELECT = `
|
|
2621
|
+
r.traceId AS traceId,
|
|
2622
|
+
r.spanId AS rootSpanId,
|
|
2623
|
+
r.threadId AS threadId,
|
|
2624
|
+
r.resourceId AS resourceId,
|
|
2625
|
+
r.startedAt AS startedAt,
|
|
2626
|
+
r.endedAt AS endedAt,
|
|
2627
|
+
r.entityName AS entityName,
|
|
2628
|
+
r.entityType AS entityType,
|
|
2629
|
+
r.environment AS environment,
|
|
2630
|
+
${TRACE_STATUS_SQL} AS status`;
|
|
2631
|
+
function fieldDefinition(registry, field) {
|
|
2632
|
+
const definition = registry[field];
|
|
2633
|
+
if (definition === void 0) throw new Error(`Unsupported trusted trace-query field: ${field}`);
|
|
2634
|
+
return definition;
|
|
2635
|
+
}
|
|
2636
|
+
function parameterSql(type) {
|
|
2637
|
+
return type === "timestamp" ? "CAST(? AS TIMESTAMP)" : "?";
|
|
2638
|
+
}
|
|
2639
|
+
function compileScalarPredicate(predicate, registry) {
|
|
2640
|
+
if (predicate.type === "boolean") {
|
|
2641
|
+
const values = [];
|
|
2642
|
+
return {
|
|
2643
|
+
sql: predicate.args.map((arg) => {
|
|
2644
|
+
const compiled = compileScalarPredicate(arg, registry);
|
|
2645
|
+
values.push(...compiled.values);
|
|
2646
|
+
return `(${compiled.sql})`;
|
|
2647
|
+
}).join(predicate.operator === "and" ? " AND " : " OR "),
|
|
2648
|
+
values
|
|
2649
|
+
};
|
|
2650
|
+
}
|
|
2651
|
+
if (predicate.type === "not") {
|
|
2652
|
+
const compiled = compileScalarPredicate(predicate.arg, registry);
|
|
2653
|
+
return {
|
|
2654
|
+
sql: `NOT (${compiled.sql})`,
|
|
2655
|
+
values: compiled.values
|
|
2656
|
+
};
|
|
2657
|
+
}
|
|
2658
|
+
const field = fieldDefinition(registry, predicate.field);
|
|
2659
|
+
if (predicate.type === "presence") return {
|
|
2660
|
+
sql: `${field.sql} IS ${predicate.operator === "exists" ? "NOT " : ""}NULL`,
|
|
2661
|
+
values: []
|
|
2662
|
+
};
|
|
2663
|
+
if (predicate.type === "membership") {
|
|
2664
|
+
const list = predicate.values.map(() => parameterSql(field.parameterType)).join(", ");
|
|
2665
|
+
if (predicate.operator === "in") return {
|
|
2666
|
+
sql: `${field.sql} IS NOT NULL AND ${field.sql} IN (${list})`,
|
|
2667
|
+
values: predicate.values
|
|
2668
|
+
};
|
|
2669
|
+
return {
|
|
2670
|
+
sql: `${field.sql} IS NULL OR ${field.sql} NOT IN (${list})`,
|
|
2671
|
+
values: predicate.values
|
|
2672
|
+
};
|
|
2673
|
+
}
|
|
2674
|
+
const parameter = parameterSql(field.parameterType);
|
|
2675
|
+
const operators = {
|
|
2676
|
+
lt: "<",
|
|
2677
|
+
lte: "<=",
|
|
2678
|
+
gt: ">",
|
|
2679
|
+
gte: ">="
|
|
2680
|
+
};
|
|
2681
|
+
if (predicate.operator === "eq") return {
|
|
2682
|
+
sql: `${field.sql} IS NOT DISTINCT FROM ${parameter}`,
|
|
2683
|
+
values: [predicate.value]
|
|
2684
|
+
};
|
|
2685
|
+
if (predicate.operator === "ne") return {
|
|
2686
|
+
sql: `${field.sql} IS DISTINCT FROM ${parameter}`,
|
|
2687
|
+
values: [predicate.value]
|
|
2688
|
+
};
|
|
2689
|
+
const operator = operators[predicate.operator];
|
|
2690
|
+
if (operator === void 0) throw new Error(`Unsupported trusted trace-query operator: ${predicate.operator}`);
|
|
2691
|
+
return {
|
|
2692
|
+
sql: `${field.sql} IS NOT NULL AND ${field.sql} ${operator} ${parameter}`,
|
|
2693
|
+
values: [predicate.value]
|
|
2694
|
+
};
|
|
2695
|
+
}
|
|
2696
|
+
function compilePredicate(predicate) {
|
|
2697
|
+
if (predicate.type === "relation") {
|
|
2698
|
+
const registry = predicate.collection === "spans" ? SPAN_FIELDS : SCORE_FIELDS;
|
|
2699
|
+
const compiled = compileScalarPredicate(predicate.predicate, registry);
|
|
2700
|
+
const existence = `EXISTS (
|
|
2701
|
+
SELECT 1 FROM ${predicate.collection === "spans" ? "current_spans" : "current_scores"} s
|
|
2702
|
+
WHERE s.traceId IS NOT NULL
|
|
2703
|
+
AND s.traceId = r.traceId
|
|
2704
|
+
AND (${compiled.sql})
|
|
2705
|
+
)`;
|
|
2706
|
+
return {
|
|
2707
|
+
sql: predicate.quantifier === "some" ? existence : `NOT ${existence}`,
|
|
2708
|
+
values: compiled.values
|
|
2709
|
+
};
|
|
2710
|
+
}
|
|
2711
|
+
if (predicate.type === "boolean") {
|
|
2712
|
+
const values = [];
|
|
2713
|
+
return {
|
|
2714
|
+
sql: predicate.args.map((arg) => {
|
|
2715
|
+
const compiled = compilePredicate(arg);
|
|
2716
|
+
values.push(...compiled.values);
|
|
2717
|
+
return `(${compiled.sql})`;
|
|
2718
|
+
}).join(predicate.operator === "and" ? " AND " : " OR "),
|
|
2719
|
+
values
|
|
2720
|
+
};
|
|
2721
|
+
}
|
|
2722
|
+
if (predicate.type === "not") {
|
|
2723
|
+
const compiled = compilePredicate(predicate.arg);
|
|
2724
|
+
return {
|
|
2725
|
+
sql: `NOT (${compiled.sql})`,
|
|
2726
|
+
values: compiled.values
|
|
2727
|
+
};
|
|
2728
|
+
}
|
|
2729
|
+
return compileScalarPredicate(predicate, TRACE_FIELDS);
|
|
2730
|
+
}
|
|
2731
|
+
function collectRelatedCollections(predicate, collections = /* @__PURE__ */ new Set()) {
|
|
2732
|
+
if (!predicate) return collections;
|
|
2733
|
+
if (predicate.type === "relation") collections.add(predicate.collection);
|
|
2734
|
+
else if (predicate.type === "boolean") for (const arg of predicate.args) collectRelatedCollections(arg, collections);
|
|
2735
|
+
else if (predicate.type === "not") collectRelatedCollections(predicate.arg, collections);
|
|
2736
|
+
return collections;
|
|
2737
|
+
}
|
|
2738
|
+
function compileDuckDBTraceQuery(plan) {
|
|
2739
|
+
const values = [plan.timeRange.from, plan.timeRange.to];
|
|
2740
|
+
const conditions = [
|
|
2741
|
+
`r.endedAt IS NOT NULL`,
|
|
2742
|
+
`r.startedAt >= CAST(? AS TIMESTAMP)`,
|
|
2743
|
+
`r.startedAt < CAST(? AS TIMESTAMP)`
|
|
2744
|
+
];
|
|
2745
|
+
if (plan.where) {
|
|
2746
|
+
const predicate = compilePredicate(plan.where);
|
|
2747
|
+
conditions.push(`(${predicate.sql})`);
|
|
2748
|
+
values.push(...predicate.values);
|
|
2749
|
+
}
|
|
2750
|
+
const relatedCollections = collectRelatedCollections(plan.where);
|
|
2751
|
+
const ctes = [
|
|
2752
|
+
`root_events AS (
|
|
2753
|
+
SELECT
|
|
2754
|
+
*,
|
|
2755
|
+
CASE
|
|
2756
|
+
WHEN eventType = 'start' THEN timestamp
|
|
2757
|
+
ELSE lag(timestamp) OVER (PARTITION BY traceId, spanId ORDER BY cursorId)
|
|
2758
|
+
END AS startedAt
|
|
2759
|
+
FROM span_events
|
|
2760
|
+
WHERE parentSpanId IS NULL
|
|
2761
|
+
)`,
|
|
2762
|
+
`current_roots AS (
|
|
2763
|
+
SELECT * EXCLUDE (rootRank)
|
|
2764
|
+
FROM (
|
|
2765
|
+
SELECT *, row_number() OVER (PARTITION BY traceId ORDER BY cursorId DESC) AS rootRank
|
|
2766
|
+
FROM root_events
|
|
2767
|
+
)
|
|
2768
|
+
WHERE rootRank = 1
|
|
2769
|
+
)`,
|
|
2770
|
+
`root_scope AS (
|
|
2771
|
+
SELECT *
|
|
2772
|
+
FROM current_roots r
|
|
2773
|
+
WHERE r.endedAt IS NOT NULL
|
|
2774
|
+
AND r.startedAt >= CAST(? AS TIMESTAMP)
|
|
2775
|
+
AND r.startedAt < CAST(? AS TIMESTAMP)
|
|
2776
|
+
)`
|
|
2777
|
+
];
|
|
2778
|
+
if (relatedCollections.has("spans")) ctes.push(`current_spans AS (
|
|
2779
|
+
SELECT * EXCLUDE (currentRank)
|
|
2780
|
+
FROM (
|
|
2781
|
+
SELECT
|
|
2782
|
+
e.*,
|
|
2783
|
+
row_number() OVER (
|
|
2784
|
+
PARTITION BY e.traceId, e.spanId
|
|
2785
|
+
ORDER BY CASE WHEN e.endedAt IS NULL THEN 1 ELSE 0 END ASC, e.cursorId DESC
|
|
2786
|
+
) AS currentRank
|
|
2787
|
+
FROM span_events e
|
|
2788
|
+
INNER JOIN root_scope roots ON roots.traceId = e.traceId
|
|
2789
|
+
)
|
|
2790
|
+
WHERE currentRank = 1
|
|
2791
|
+
)`);
|
|
2792
|
+
if (relatedCollections.has("scores")) ctes.push(`current_scores AS (
|
|
2793
|
+
SELECT s.*
|
|
2794
|
+
FROM score_events s
|
|
2795
|
+
INNER JOIN root_scope roots ON roots.traceId = s.traceId
|
|
2796
|
+
)`);
|
|
2797
|
+
ctes.push(`candidates AS (
|
|
2798
|
+
SELECT ${TRACE_SELECT}
|
|
2799
|
+
FROM root_scope r
|
|
2800
|
+
WHERE ${conditions.slice(3).join("\n AND ") || "TRUE"}
|
|
2801
|
+
)`);
|
|
2802
|
+
const candidates = `WITH ${ctes.join(",\n ")}`;
|
|
2803
|
+
if (plan.result === "groups") {
|
|
2804
|
+
const pageCondition = plan.cursor ? `AND threadId > ?` : "";
|
|
2805
|
+
if (plan.cursor) values.push(plan.cursor.threadId);
|
|
2806
|
+
values.push(plan.limit + 1);
|
|
2807
|
+
return {
|
|
2808
|
+
sql: `${candidates}
|
|
2809
|
+
SELECT threadId
|
|
2810
|
+
FROM candidates
|
|
2811
|
+
WHERE threadId IS NOT NULL ${pageCondition}
|
|
2812
|
+
GROUP BY threadId
|
|
2813
|
+
ORDER BY threadId ASC
|
|
2814
|
+
LIMIT ?`,
|
|
2815
|
+
values
|
|
2816
|
+
};
|
|
2817
|
+
}
|
|
2818
|
+
const orderField = plan.orderBy.field;
|
|
2819
|
+
const direction = plan.orderBy.direction === "asc" ? "ASC" : "DESC";
|
|
2820
|
+
let pageCondition = "";
|
|
2821
|
+
if (plan.cursor) {
|
|
2822
|
+
pageCondition = `WHERE (${orderField} ${plan.orderBy.direction === "asc" ? ">" : "<"} CAST(? AS TIMESTAMP) OR (${orderField} = CAST(? AS TIMESTAMP) AND traceId > ?))`;
|
|
2823
|
+
values.push(plan.cursor.sortValue, plan.cursor.sortValue, plan.cursor.traceId);
|
|
2824
|
+
}
|
|
2825
|
+
values.push(plan.limit + 1);
|
|
2826
|
+
return {
|
|
2827
|
+
sql: `${candidates}
|
|
2828
|
+
SELECT *
|
|
2829
|
+
FROM candidates
|
|
2830
|
+
${pageCondition}
|
|
2831
|
+
ORDER BY ${orderField} ${direction}, traceId ASC
|
|
2832
|
+
LIMIT ?`,
|
|
2833
|
+
values
|
|
2834
|
+
};
|
|
2835
|
+
}
|
|
2836
|
+
function asIsoTimestamp(value) {
|
|
2837
|
+
return value instanceof Date ? value.toISOString() : new Date(value).toISOString();
|
|
2838
|
+
}
|
|
2839
|
+
async function queryTraces(db, plan) {
|
|
2840
|
+
const query = compileDuckDBTraceQuery(plan);
|
|
2841
|
+
const rows = await db.query(query.sql, query.values);
|
|
2842
|
+
const visibleRows = rows.slice(0, plan.limit);
|
|
2843
|
+
if (plan.result === "groups") {
|
|
2844
|
+
const groups = visibleRows.map((row) => ({ threadId: String(row.threadId) }));
|
|
2845
|
+
const last = groups.at(-1);
|
|
2846
|
+
return coreStorage.traceQueryResponseSchema.parse({
|
|
2847
|
+
groups,
|
|
2848
|
+
page: { next: rows.length > plan.limit && last ? coreStorage.encodeTraceQueryCursor(plan, {
|
|
2849
|
+
result: "groups",
|
|
2850
|
+
threadId: last.threadId
|
|
2851
|
+
}) : null }
|
|
2852
|
+
});
|
|
2853
|
+
}
|
|
2854
|
+
const traces = visibleRows.map((row) => ({
|
|
2855
|
+
traceId: String(row.traceId),
|
|
2856
|
+
rootSpanId: String(row.rootSpanId),
|
|
2857
|
+
threadId: row.threadId == null ? null : String(row.threadId),
|
|
2858
|
+
resourceId: row.resourceId == null ? null : String(row.resourceId),
|
|
2859
|
+
startedAt: asIsoTimestamp(row.startedAt),
|
|
2860
|
+
endedAt: asIsoTimestamp(row.endedAt),
|
|
2861
|
+
entityName: row.entityName == null ? null : String(row.entityName),
|
|
2862
|
+
entityType: row.entityType == null ? null : String(row.entityType),
|
|
2863
|
+
environment: row.environment == null ? null : String(row.environment),
|
|
2864
|
+
status: row.status
|
|
2865
|
+
}));
|
|
2866
|
+
const last = traces.at(-1);
|
|
2867
|
+
return coreStorage.traceQueryResponseSchema.parse({
|
|
2868
|
+
traces,
|
|
2869
|
+
page: { next: rows.length > plan.limit && last ? coreStorage.encodeTraceQueryCursor(plan, {
|
|
2870
|
+
result: "traces",
|
|
2871
|
+
sortValue: last[plan.orderBy.field],
|
|
2872
|
+
traceId: last.traceId
|
|
2873
|
+
}) : null }
|
|
2874
|
+
});
|
|
2875
|
+
}
|
|
2876
|
+
//#endregion
|
|
2522
2877
|
//#region src/storage/domains/observability/tracing.ts
|
|
2523
2878
|
const COLUMNS_SQL = [
|
|
2524
2879
|
"eventType",
|
|
@@ -3015,11 +3370,36 @@ async function batchCreateSpans(db, args) {
|
|
|
3015
3370
|
return events;
|
|
3016
3371
|
}));
|
|
3017
3372
|
}
|
|
3018
|
-
/**
|
|
3373
|
+
/**
|
|
3374
|
+
* Delete all span events for the given trace IDs, cascading to trace-linked
|
|
3375
|
+
* signal events (metrics, logs, scores, feedback). Signal rows with a NULL
|
|
3376
|
+
* traceId are never affected. When the optional tenant scope
|
|
3377
|
+
* (`organizationId` / `resourceId`) is set, every DELETE additionally
|
|
3378
|
+
* requires the row's tenant columns to match.
|
|
3379
|
+
*/
|
|
3019
3380
|
async function batchDeleteTraces(db, args) {
|
|
3020
3381
|
if (args.traceIds.length === 0) return;
|
|
3021
3382
|
const placeholders = args.traceIds.map(() => "?").join(", ");
|
|
3022
|
-
|
|
3383
|
+
const params = [...args.traceIds];
|
|
3384
|
+
let scopeCondition = "";
|
|
3385
|
+
if (args.organizationId !== void 0) {
|
|
3386
|
+
scopeCondition += ` AND organizationId = ?`;
|
|
3387
|
+
params.push(args.organizationId);
|
|
3388
|
+
}
|
|
3389
|
+
if (args.resourceId !== void 0) {
|
|
3390
|
+
scopeCondition += ` AND resourceId = ?`;
|
|
3391
|
+
params.push(args.resourceId);
|
|
3392
|
+
}
|
|
3393
|
+
await db.executeTransaction([
|
|
3394
|
+
"span_events",
|
|
3395
|
+
"metric_events",
|
|
3396
|
+
"log_events",
|
|
3397
|
+
"score_events",
|
|
3398
|
+
"feedback_events"
|
|
3399
|
+
].map((table) => ({
|
|
3400
|
+
sql: `DELETE FROM ${table} WHERE traceId IN (${placeholders})${scopeCondition}`,
|
|
3401
|
+
params
|
|
3402
|
+
})));
|
|
3023
3403
|
}
|
|
3024
3404
|
/** Reconstruct a single span from its event history. */
|
|
3025
3405
|
async function getSpan(db, args) {
|
|
@@ -3717,11 +4097,16 @@ var ObservabilityStorageDuckDB = class extends ObservabilityStorage {
|
|
|
3717
4097
|
};
|
|
3718
4098
|
}
|
|
3719
4099
|
getFeatures() {
|
|
3720
|
-
if (!deltaPollingFeatureEnabled()) return [
|
|
4100
|
+
if (!deltaPollingFeatureEnabled()) return [
|
|
4101
|
+
"metrics",
|
|
4102
|
+
"logs",
|
|
4103
|
+
"trace-query"
|
|
4104
|
+
];
|
|
3721
4105
|
return [
|
|
3722
4106
|
"metrics",
|
|
3723
4107
|
"logs",
|
|
3724
|
-
"delta-polling"
|
|
4108
|
+
"delta-polling",
|
|
4109
|
+
"trace-query"
|
|
3725
4110
|
];
|
|
3726
4111
|
}
|
|
3727
4112
|
async createSpan(args) {
|
|
@@ -3751,6 +4136,9 @@ var ObservabilityStorageDuckDB = class extends ObservabilityStorage {
|
|
|
3751
4136
|
async listTraces(args) {
|
|
3752
4137
|
return listTraces(this.db, args);
|
|
3753
4138
|
}
|
|
4139
|
+
async queryTraces(plan) {
|
|
4140
|
+
return queryTraces(this.db, plan);
|
|
4141
|
+
}
|
|
3754
4142
|
async listTracesLight(args) {
|
|
3755
4143
|
if (args.mode === "delta") return super.listTracesLight(args);
|
|
3756
4144
|
return listTracesLight(this.db, args);
|
|
@@ -3858,4 +4246,4 @@ var ObservabilityStorageDuckDB = class extends ObservabilityStorage {
|
|
|
3858
4246
|
//#endregion
|
|
3859
4247
|
export { ObservabilityStorageDuckDB };
|
|
3860
4248
|
|
|
3861
|
-
//# sourceMappingURL=observability-
|
|
4249
|
+
//# sourceMappingURL=observability-Bt92lKRG.js.map
|