@mastra/clickhouse 1.21.0-alpha.0 → 1.21.0-alpha.2
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/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/integrations-databases-clickhouse.md +2 -2
- package/dist/docs/references/reference-storage-retention.md +9 -7
- package/dist/index.cjs +22 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +22 -2
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/observability/v-next/index.d.ts +1 -1
- package/dist/storage/domains/observability/v-next/index.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/trace-query.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/docs/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: mastra-clickhouse
|
|
|
3
3
|
description: Documentation for @mastra/clickhouse. Use when working with @mastra/clickhouse APIs, configuration, or implementation.
|
|
4
4
|
metadata:
|
|
5
5
|
package: "@mastra/clickhouse"
|
|
6
|
-
version: "1.21.0-alpha.
|
|
6
|
+
version: "1.21.0-alpha.2"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
## When to use
|
|
@@ -89,7 +89,7 @@ export const mastra = new Mastra({
|
|
|
89
89
|
|
|
90
90
|
Trace deletion cascades to spans, trace roots and branches, metrics, logs, scores, and feedback linked by trace ID. Signals without a trace ID are preserved. Mastra records the deletion predicate, then waits for ClickHouse lightweight delete masks to be applied. Normal reads no longer return the rows matched by that operation when the call resolves.
|
|
91
91
|
|
|
92
|
-
Lightweight deletion is a hide-only operation that marks rows with ClickHouse's `_row_exists` mask. Physical removal depends on merges and deployment-configured retention TTLs. `ObservabilityStorageClickhouseVNext` applies retention only when you
|
|
92
|
+
Lightweight deletion is a hide-only operation that marks rows with ClickHouse's `_row_exists` mask. Physical removal depends on merges and deployment-configured retention TTLs. `ObservabilityStorageClickhouseVNext` applies retention only when you pass the `retention` option. Mastra doesn't configure a default retention TTL.
|
|
93
93
|
|
|
94
94
|
When all five observability signals have finite retention, Mastra also applies a TTL to deletion requests so they outlive the signal rows they protect. If any signal is unbounded, deletion requests remain unbounded. See [storage retention](https://mastra.ai/reference/storage/retention) for how the deletion-request TTL is calculated.
|
|
95
95
|
|
|
@@ -275,7 +275,7 @@ Don't set `replication` on ClickHouse Cloud. Cloud rewrites `MergeTree` to `Shar
|
|
|
275
275
|
|
|
276
276
|
### Observability domain options
|
|
277
277
|
|
|
278
|
-
`ObservabilityStorageClickhouse` and `ObservabilityStorageClickhouseVNext` accept the same connection options as `ClickhouseStore` (`url`, `username`, `password`, or a pre-configured `client`).
|
|
278
|
+
`ObservabilityStorageClickhouse` and `ObservabilityStorageClickhouseVNext` accept the same connection options as `ClickhouseStore` (`url`, `username`, `password`, or a pre-configured `client`). `ObservabilityStorageClickhouseVNext` also accepts `retention`, the per-signal TTL in days described in [ClickHouse native TTL](https://mastra.ai/reference/storage/retention), and `traceQuery`, the execution limits for [advanced trace queries](https://mastra.ai/reference/observability/tracing/trace-query).
|
|
279
279
|
|
|
280
280
|
## Hosting options
|
|
281
281
|
|
|
@@ -15,7 +15,7 @@ Storage adapters use the shared core retention contract for `prune()`, or a data
|
|
|
15
15
|
| Adapter | Mechanism | Retention support |
|
|
16
16
|
| -------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
17
17
|
| libSQL | `prune()` | All supported growth domains |
|
|
18
|
-
| PostgreSQL | `prune()` | All supported growth domains.
|
|
18
|
+
| PostgreSQL | `prune()` | All supported growth domains. vNext observability drops expired partitions or chunks |
|
|
19
19
|
| MongoDB | `prune()` or native TTL | All supported growth domains. Native TTL indexes are also available |
|
|
20
20
|
| DuckDB | `prune()` | Observability spans, metrics, logs, scores, and feedback |
|
|
21
21
|
| MySQL | `prune()` | Observability spans |
|
|
@@ -102,10 +102,10 @@ Each domain specifies its age-prunable tables and the timestamp column that anch
|
|
|
102
102
|
| `memory` | `resources` | `createdAt` | Resource age |
|
|
103
103
|
| `threadState` | `threadState` | `updatedAt` | Inactivity: state for still-active threads survives |
|
|
104
104
|
| `observability` | `spans` | `startedAt` | Span age |
|
|
105
|
-
| `observability` | `metrics` | `timestamp` | Metric event age (
|
|
106
|
-
| `observability` | `logs` | `timestamp` | Log event age (
|
|
107
|
-
| `observability` | `scores` | `timestamp` | Score event age (
|
|
108
|
-
| `observability` | `feedback` | `timestamp` | Feedback event age (
|
|
105
|
+
| `observability` | `metrics` | `timestamp` | Metric event age (vNext only) |
|
|
106
|
+
| `observability` | `logs` | `timestamp` | Log event age (vNext only) |
|
|
107
|
+
| `observability` | `scores` | `timestamp` | Score event age (vNext only) |
|
|
108
|
+
| `observability` | `feedback` | `timestamp` | Feedback event age (vNext only) |
|
|
109
109
|
| `scores` | `scorers` | `createdAt` | Score record age |
|
|
110
110
|
| `workflows` | `workflowSnapshot` | `updatedAt` | Inactivity, suspended or long-running workflows survive |
|
|
111
111
|
| `backgroundTasks` | `backgroundTasks` | `completedAt` | Time since completion, in-flight tasks (`NULL`) are never pruned |
|
|
@@ -122,7 +122,7 @@ Each domain specifies its age-prunable tables and the timestamp column that anch
|
|
|
122
122
|
> - On PostgreSQL, timestamp anchors use the timezone-aware mirror columns (for example `createdAtZ`, `completedAtZ`).
|
|
123
123
|
> - DuckDB observability stores append-only events for all five signals. Its `spans` policy uses the event `timestamp` column rather than `startedAt`.
|
|
124
124
|
> - LibSQL and PostgreSQL support all domains above except `harness`, which PostgreSQL doesn't implement. MongoDB supports all except `threadState` and `harness`. DuckDB, MySQL, Microsoft SQL Server, Oracle Database, Amazon Aurora DSQL, and Google Cloud Spanner currently support retention only in their `observability` domains, with the signal coverage shown in the support matrix.
|
|
125
|
-
> - The
|
|
125
|
+
> - The vNext PostgreSQL observability domain stores signal events in day-partitioned tables (`spans`, `metrics`, `logs`, `scores`, `feedback`). For it, `prune()` drops whole day partitions (or TimescaleDB chunks) that are entirely older than the cutoff instead of deleting rows: effective level of detail is one day, and a partition is only dropped once its entire day is past `maxAge`. `PruneResult.deleted` reports the number of rows in the dropped partitions.
|
|
126
126
|
|
|
127
127
|
## Methods
|
|
128
128
|
|
|
@@ -208,7 +208,9 @@ You can also cancel a long-running prune with an `AbortSignal`: the loop stops b
|
|
|
208
208
|
|
|
209
209
|
ClickHouse observability storage uses native table TTLs instead of `prune()`. Configure retention as days per signal. `init()` applies the TTLs to new and existing tables and skips `ALTER TABLE` statements when the configured TTL is already present.
|
|
210
210
|
|
|
211
|
-
|
|
211
|
+
Omitted signals, and signals set to zero or less, get no TTL. When you remove a signal from `retention`, the next `init()` or `applyRetention()` removes that table's TTL. If Mastra can't read the current TTLs from `system.tables`, it applies the configured TTLs and leaves the others unchanged.
|
|
212
|
+
|
|
213
|
+
For deployments that need to update TTL configuration without running the full initialization path, call `applyRetention()` on the vNext observability store:
|
|
212
214
|
|
|
213
215
|
```typescript
|
|
214
216
|
import { ObservabilityStorageClickhouseVNext } from '@mastra/clickhouse'
|
package/dist/index.cjs
CHANGED
|
@@ -6516,6 +6516,9 @@ async function getScorePercentiles(client, args) {
|
|
|
6516
6516
|
//#endregion
|
|
6517
6517
|
//#region src/storage/domains/observability/v-next/trace-query.ts
|
|
6518
6518
|
const TRACE_STATUS_SQL = `if(isNotNull(r.error), 'error', 'success')`;
|
|
6519
|
+
function durationMsSql(startedAt, endedAt) {
|
|
6520
|
+
return `dateDiff('millisecond', ${startedAt}, ${endedAt})`;
|
|
6521
|
+
}
|
|
6519
6522
|
const TRACE_FIELDS = {
|
|
6520
6523
|
traceId: {
|
|
6521
6524
|
sql: "r.traceId",
|
|
@@ -6537,6 +6540,10 @@ const TRACE_FIELDS = {
|
|
|
6537
6540
|
sql: "r.endedAt",
|
|
6538
6541
|
parameterType: "DateTime64(3, 'UTC')"
|
|
6539
6542
|
},
|
|
6543
|
+
durationMs: {
|
|
6544
|
+
sql: durationMsSql("r.startedAt", "r.endedAt"),
|
|
6545
|
+
parameterType: "Float64"
|
|
6546
|
+
},
|
|
6540
6547
|
entityName: {
|
|
6541
6548
|
sql: "r.entityName",
|
|
6542
6549
|
parameterType: "String"
|
|
@@ -6552,6 +6559,10 @@ const TRACE_FIELDS = {
|
|
|
6552
6559
|
status: {
|
|
6553
6560
|
sql: TRACE_STATUS_SQL,
|
|
6554
6561
|
parameterType: "String"
|
|
6562
|
+
},
|
|
6563
|
+
tags: {
|
|
6564
|
+
sql: "r.tags",
|
|
6565
|
+
parameterType: "String"
|
|
6555
6566
|
}
|
|
6556
6567
|
};
|
|
6557
6568
|
const SPAN_FIELDS = {
|
|
@@ -6741,6 +6752,11 @@ function compileScalarPredicate(predicate, registry, parameters, allowMetadata =
|
|
|
6741
6752
|
};
|
|
6742
6753
|
})() : fieldDefinition(registry, predicate.field);
|
|
6743
6754
|
if (predicate.type === "presence") return `${predicate.operator === "exists" ? "isNotNull" : "isNull"}(${field.sql})`;
|
|
6755
|
+
if (predicate.type === "collection") {
|
|
6756
|
+
if (!("value" in predicate)) return `${predicate.operator}(${field.sql})`;
|
|
6757
|
+
const member = parameters.add(predicate.value, field.parameterType);
|
|
6758
|
+
return predicate.operator === "includes" ? `has(${field.sql}, ${member})` : `notEmpty(${field.sql}) AND NOT has(${field.sql}, ${member})`;
|
|
6759
|
+
}
|
|
6744
6760
|
if (predicate.type === "membership") {
|
|
6745
6761
|
const values = predicate.values.map((value) => parameters.add(value, field.parameterType)).join(", ");
|
|
6746
6762
|
return `ifNull(${`${field.sql} ${predicate.operator === "in" ? "IN" : "NOT IN"} (${values})`}, ${predicate.operator === "in" ? "0" : "1"})`;
|
|
@@ -6765,6 +6781,7 @@ function compileFeedbackScalarPredicate(predicate, parameters) {
|
|
|
6765
6781
|
const present = `(isNotNull(s.valueString) OR isNotNull(s.valueNumber))`;
|
|
6766
6782
|
return predicate.operator === "exists" ? present : `NOT ${present}`;
|
|
6767
6783
|
}
|
|
6784
|
+
if (predicate.type === "collection") throw new Error("Unsupported trusted trace-query field: value");
|
|
6768
6785
|
return compileScalarPredicate(predicate, typeof (predicate.type === "membership" ? predicate.values[0] : predicate.value) === "number" ? { value: {
|
|
6769
6786
|
sql: "s.valueNumber",
|
|
6770
6787
|
parameterType: "Float64"
|
|
@@ -6851,7 +6868,7 @@ function compileClickHouseTraceScope(selection, relationCollections, parameters,
|
|
|
6851
6868
|
if(JSONType(attributes, 'provider') = 'String', JSONExtractString(attributes, 'provider'), NULL) AS provider,
|
|
6852
6869
|
startedAt,
|
|
6853
6870
|
endedAt,
|
|
6854
|
-
|
|
6871
|
+
${durationMsSql("startedAt", "endedAt")} AS durationMs,
|
|
6855
6872
|
if(isNotNull(error), 'error', 'success') AS status,
|
|
6856
6873
|
error,
|
|
6857
6874
|
entityType,
|
|
@@ -7106,7 +7123,8 @@ function compileClickHouseTraceQueryValues(plan) {
|
|
|
7106
7123
|
if (plan.predicateScope === "trace" && plan.path.startsWith("metadata.")) {
|
|
7107
7124
|
const key = parameters.add(plan.path.slice(9), "String");
|
|
7108
7125
|
field = `coalesce(if(mapContains(r.metadataSearch, ${key}), r.metadataSearch[${key}], NULL), nullIf(trim(JSONExtractString(r.metadataRaw, ${key})), ''))`;
|
|
7109
|
-
} else
|
|
7126
|
+
} else if (plan.predicateScope === "trace" && plan.path === "tags") field = `arrayJoin(arrayDistinct(${TRACE_FIELDS.tags.sql}))`;
|
|
7127
|
+
else field = fieldDefinition(discoveryRegistry(plan.predicateScope), plan.path).sql;
|
|
7110
7128
|
const search = plan.search ? `AND positionCaseInsensitiveUTF8(value, ${parameters.add(plan.search, "String")}) > 0` : "";
|
|
7111
7129
|
const limit = parameters.add(plan.limit + 1, "UInt64");
|
|
7112
7130
|
return {
|
|
@@ -8555,6 +8573,7 @@ var ObservabilityStorageClickhouseVNext = class extends _mastra_core_storage.Obs
|
|
|
8555
8573
|
"metrics",
|
|
8556
8574
|
"logs",
|
|
8557
8575
|
"trace-query",
|
|
8576
|
+
"trace-query-root-duration",
|
|
8558
8577
|
"trace-query-discovery",
|
|
8559
8578
|
"thread-query",
|
|
8560
8579
|
"trace-query-tenant-scope"
|
|
@@ -8564,6 +8583,7 @@ var ObservabilityStorageClickhouseVNext = class extends _mastra_core_storage.Obs
|
|
|
8564
8583
|
"logs",
|
|
8565
8584
|
"delta-polling",
|
|
8566
8585
|
"trace-query",
|
|
8586
|
+
"trace-query-root-duration",
|
|
8567
8587
|
"trace-query-discovery",
|
|
8568
8588
|
"thread-query",
|
|
8569
8589
|
"trace-query-tenant-scope"
|