@noego/telemetry 0.0.1 → 0.0.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.
Files changed (42) hide show
  1. package/dist/cli/telemetry_bin.cjs +57 -57
  2. package/dist/cli/telemetry_bin.cjs.map +1 -1
  3. package/dist/cli/telemetry_bin.js +57 -57
  4. package/dist/cli/telemetry_bin.js.map +1 -1
  5. package/dist/cli/telemetry_cli.cjs +57 -57
  6. package/dist/cli/telemetry_cli.cjs.map +1 -1
  7. package/dist/cli/telemetry_cli.d.cts +3 -3
  8. package/dist/cli/telemetry_cli.d.ts +3 -3
  9. package/dist/cli/telemetry_cli.js +57 -57
  10. package/dist/cli/telemetry_cli.js.map +1 -1
  11. package/dist/core/index.d.cts +5 -5
  12. package/dist/core/index.d.ts +5 -5
  13. package/dist/index.d.cts +6 -6
  14. package/dist/index.d.ts +6 -6
  15. package/dist/{maintenance_coordinator.types-B-bZUNvw.d.cts → maintenance_coordinator.types-C4ULi4A4.d.cts} +2 -2
  16. package/dist/{maintenance_coordinator.types-CBA5y74b.d.ts → maintenance_coordinator.types-ikUrRXmO.d.ts} +2 -2
  17. package/dist/{metric_definition_contract-l4i4SaAp.d.ts → metric_definition_contract-BYtnODhu.d.ts} +1 -1
  18. package/dist/{metric_definition_contract-BR6a_GzF.d.cts → metric_definition_contract-DfhhmTZ1.d.cts} +1 -1
  19. package/dist/node/index.cjs +57 -57
  20. package/dist/node/index.cjs.map +1 -1
  21. package/dist/node/index.d.cts +5 -5
  22. package/dist/node/index.d.ts +5 -5
  23. package/dist/node/index.js +57 -57
  24. package/dist/node/index.js.map +1 -1
  25. package/dist/{query.types-DySoqYop.d.ts → query.types-DU5v7vM0.d.ts} +7 -0
  26. package/dist/{query.types-Bntwh6KF.d.cts → query.types-DuYWbFFe.d.cts} +7 -0
  27. package/dist/sqlite/index.cjs +34 -57
  28. package/dist/sqlite/index.cjs.map +1 -1
  29. package/dist/sqlite/index.d.cts +3 -3
  30. package/dist/sqlite/index.d.ts +3 -3
  31. package/dist/sqlite/index.js +34 -57
  32. package/dist/sqlite/index.js.map +1 -1
  33. package/dist/{storage.types-DjuUMinz.d.cts → storage.types-Bji_pWqr.d.cts} +1 -1
  34. package/dist/{storage.types-BTCGVxOM.d.ts → storage.types-k7oElEB3.d.ts} +1 -1
  35. package/dist/{telemetry_configuration_parser-C7Et_gwG.d.ts → telemetry_configuration_parser-BZ8Nvnle.d.ts} +3 -2
  36. package/dist/{telemetry_configuration_parser-R-niZQRZ.d.cts → telemetry_configuration_parser-CgSN7R6A.d.cts} +3 -2
  37. package/dist/testing/index.d.cts +2 -2
  38. package/dist/testing/index.d.ts +2 -2
  39. package/migrations/1785073006031_raw_events_level_index.down.sql +1 -0
  40. package/migrations/1785073006031_raw_events_level_index.up.sql +5 -0
  41. package/native/noego_telemetry_native.node +0 -0
  42. package/package.json +1 -1
@@ -221,6 +221,7 @@ var TelemetryTableMap = class _TelemetryTableMap {
221
221
  rawEventsOccurredIndex: this.indexName(mapping.rawEvents, "occurred"),
222
222
  rawEventsConversationIndex: this.indexName(mapping.rawEvents, "conversation"),
223
223
  rawEventsLabelIndex: this.indexName(mapping.rawEvents, "label"),
224
+ rawEventsLevelIndex: this.indexName(mapping.rawEvents, "level"),
224
225
  metricSamplesTimeIndex: this.indexName(mapping.metricSamples, "time"),
225
226
  metricSamplesEventIndex: this.indexName(mapping.metricSamples, "event"),
226
227
  metricRollupsTimeIndex: this.indexName(mapping.metricRollups, "time")
@@ -395,6 +396,7 @@ var SqliteTargetSchema = z.object({
395
396
  raw: DurationSchema,
396
397
  lateArrival: DurationSchema.optional(),
397
398
  samples: DurationSchema.optional(),
399
+ levels: z.record(z.string().min(1), DurationSchema).optional(),
398
400
  rollups: z.array(
399
401
  z.object({
400
402
  resolution: DurationSchema,
@@ -537,6 +539,7 @@ var NodeTelemetryConfigurationParser = class {
537
539
  true
538
540
  );
539
541
  const samplesMs = target.retention.samples === void 0 ? rawMs + lateArrivalMs : this.durations.parse(target.retention.samples, `${field}.retention.samples`);
542
+ const levelMs = this.resolveLevelRetention(target.retention.levels, field);
540
543
  const rollups = target.retention.rollups.map(
541
544
  (tier, tierIndex) => Object.freeze({
542
545
  resolutionMs: this.durations.parse(
@@ -571,6 +574,7 @@ var NodeTelemetryConfigurationParser = class {
571
574
  rawMs,
572
575
  lateArrivalMs,
573
576
  samplesMs,
577
+ levelMs,
574
578
  rollups: Object.freeze(rollups)
575
579
  }),
576
580
  maintenance: Object.freeze({
@@ -601,6 +605,26 @@ var NodeTelemetryConfigurationParser = class {
601
605
  }
602
606
  return resolved;
603
607
  }
608
+ resolveLevelRetention(levels, field) {
609
+ if (levels === void 0) {
610
+ return Object.freeze({});
611
+ }
612
+ const resolved = {};
613
+ for (const [level, duration] of Object.entries(levels)) {
614
+ const normalized = level.trim().toLowerCase();
615
+ if (normalized.length === 0) {
616
+ throw new Error(`${field}.retention.levels contains an empty level name`);
617
+ }
618
+ if (resolved[normalized] !== void 0) {
619
+ throw new Error(`${field}.retention.levels declares "${normalized}" more than once`);
620
+ }
621
+ resolved[normalized] = this.durations.parse(
622
+ duration,
623
+ `${field}.retention.levels.${normalized}`
624
+ );
625
+ }
626
+ return Object.freeze(resolved);
627
+ }
604
628
  validateRetention(target, field) {
605
629
  const retention = target.retention;
606
630
  const requiredSamplesMs = retention.rawMs + retention.lateArrivalMs;
@@ -3364,73 +3388,49 @@ var TelemetryRepository = class {
3364
3388
  lastSequence: sample.sequence
3365
3389
  };
3366
3390
  }
3391
+ /**
3392
+ * Raw retention is purely time-based, matching the native collector: every
3393
+ * expired row goes in one set-based statement per level band. No page size,
3394
+ * no row cap, and no rollup-completion gate — metric samples are extracted at
3395
+ * ingest and retained on their own clock, so dropping a raw row costs no
3396
+ * metric fidelity, and no row can outlive its window waiting on a rollup.
3397
+ */
3367
3398
  createRawEventRetentionStep(nowMs) {
3368
- const cutoffMs = nowMs - this.options.retention.rawMs;
3369
3399
  const table = this.options.tableMap.quoted("rawEvents");
3370
- const readFirstPage = this.options.connection.prepare(
3371
- `SELECT producer_id, sequence, event_id, occurred_at_ms, monotonic_ns,
3372
- source, process_kind, level, label, conversation_id,
3373
- conversation_id_kind, correlation_id, metadata_json, schema_version
3374
- FROM ${table}
3375
- WHERE target_id = ? AND occurred_at_ms < ?
3376
- ORDER BY occurred_at_ms ASC, producer_id ASC, sequence ASC
3377
- LIMIT ${RETENTION_PAGE_SIZE}`
3378
- );
3379
- const readNextPage = this.options.connection.prepare(
3380
- `SELECT producer_id, sequence, event_id, occurred_at_ms, monotonic_ns,
3381
- source, process_kind, level, label, conversation_id,
3382
- conversation_id_kind, correlation_id, metadata_json, schema_version
3383
- FROM ${table}
3384
- WHERE target_id = ? AND occurred_at_ms < ?
3385
- AND (occurred_at_ms, producer_id, sequence) > (?, ?, ?)
3386
- ORDER BY occurred_at_ms ASC, producer_id ASC, sequence ASC
3387
- LIMIT ${RETENTION_PAGE_SIZE}`
3400
+ const levelMs = this.options.retention.levelMs ?? {};
3401
+ const levels = Object.keys(levelMs);
3402
+ const removeByLevel = this.options.connection.prepare(
3403
+ `DELETE FROM ${table}
3404
+ WHERE target_id = ? AND lower(coalesce(level, '')) = ? AND occurred_at_ms < ?`
3388
3405
  );
3389
- const remove = this.options.connection.prepare(
3390
- `DELETE FROM ${table} WHERE target_id = ? AND producer_id = ? AND sequence = ?`
3406
+ const fallbackPlaceholders = levels.map(() => "?").join(", ");
3407
+ const removeFallback = this.options.connection.prepare(
3408
+ `DELETE FROM ${table}
3409
+ WHERE target_id = ? AND occurred_at_ms < ?` + (levels.length === 0 ? "" : ` AND lower(coalesce(level, '')) NOT IN (${fallbackPlaceholders})`)
3391
3410
  );
3392
- let cursor = null;
3411
+ let done = false;
3393
3412
  return () => {
3394
- const rows = cursor === null ? readFirstPage.all(this.options.targetId, cutoffMs) : readNextPage.all(
3395
- this.options.targetId,
3396
- cutoffMs,
3397
- cursor.occurredAtMs,
3398
- cursor.producerId,
3399
- cursor.sequence
3400
- );
3401
- if (rows.length === 0) {
3413
+ if (done) {
3402
3414
  return { deleted: 0, done: true };
3403
3415
  }
3404
- const scanned = rows.map((row) => {
3405
- const parsed = this.rowParser.parseRawEnvelope(row);
3406
- if (!parsed.ok) {
3407
- throw new Error(parsed.error);
3408
- }
3409
- return parsed.value;
3410
- });
3411
- const eligible = scanned.filter((envelope) => this.rawEventHasRequiredRollups(envelope));
3416
+ done = true;
3412
3417
  const transaction = this.options.connection.transaction(() => {
3413
- let deleted2 = 0;
3414
- for (const envelope of eligible) {
3415
- deleted2 += remove.run(
3416
- this.options.targetId,
3417
- envelope.producerId,
3418
- envelope.sequence
3419
- ).changes;
3418
+ let deleted = 0;
3419
+ for (const level of levels) {
3420
+ const retainMs = levelMs[level];
3421
+ if (retainMs === void 0) {
3422
+ continue;
3423
+ }
3424
+ deleted += removeByLevel.run(this.options.targetId, level, nowMs - retainMs).changes;
3420
3425
  }
3421
- return deleted2;
3426
+ deleted += removeFallback.run(
3427
+ this.options.targetId,
3428
+ nowMs - this.options.retention.rawMs,
3429
+ ...levels
3430
+ ).changes;
3431
+ return deleted;
3422
3432
  });
3423
- const deleted = transaction();
3424
- const last = scanned[scanned.length - 1];
3425
- if (last === void 0 || rows.length < RETENTION_PAGE_SIZE) {
3426
- return { deleted, done: true };
3427
- }
3428
- cursor = {
3429
- occurredAtMs: last.occurredAtMs,
3430
- producerId: last.producerId,
3431
- sequence: last.sequence
3432
- };
3433
- return { deleted, done: false };
3433
+ return { deleted: transaction(), done: true };
3434
3434
  };
3435
3435
  }
3436
3436
  rawEventHasRequiredRollups(envelope) {