@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
@@ -244,6 +244,7 @@ var TelemetryTableMap = class _TelemetryTableMap {
244
244
  rawEventsOccurredIndex: this.indexName(mapping.rawEvents, "occurred"),
245
245
  rawEventsConversationIndex: this.indexName(mapping.rawEvents, "conversation"),
246
246
  rawEventsLabelIndex: this.indexName(mapping.rawEvents, "label"),
247
+ rawEventsLevelIndex: this.indexName(mapping.rawEvents, "level"),
247
248
  metricSamplesTimeIndex: this.indexName(mapping.metricSamples, "time"),
248
249
  metricSamplesEventIndex: this.indexName(mapping.metricSamples, "event"),
249
250
  metricRollupsTimeIndex: this.indexName(mapping.metricRollups, "time")
@@ -418,6 +419,7 @@ var SqliteTargetSchema = import_zod.z.object({
418
419
  raw: DurationSchema,
419
420
  lateArrival: DurationSchema.optional(),
420
421
  samples: DurationSchema.optional(),
422
+ levels: import_zod.z.record(import_zod.z.string().min(1), DurationSchema).optional(),
421
423
  rollups: import_zod.z.array(
422
424
  import_zod.z.object({
423
425
  resolution: DurationSchema,
@@ -560,6 +562,7 @@ var NodeTelemetryConfigurationParser = class {
560
562
  true
561
563
  );
562
564
  const samplesMs = target.retention.samples === void 0 ? rawMs + lateArrivalMs : this.durations.parse(target.retention.samples, `${field}.retention.samples`);
565
+ const levelMs = this.resolveLevelRetention(target.retention.levels, field);
563
566
  const rollups = target.retention.rollups.map(
564
567
  (tier, tierIndex) => Object.freeze({
565
568
  resolutionMs: this.durations.parse(
@@ -594,6 +597,7 @@ var NodeTelemetryConfigurationParser = class {
594
597
  rawMs,
595
598
  lateArrivalMs,
596
599
  samplesMs,
600
+ levelMs,
597
601
  rollups: Object.freeze(rollups)
598
602
  }),
599
603
  maintenance: Object.freeze({
@@ -624,6 +628,26 @@ var NodeTelemetryConfigurationParser = class {
624
628
  }
625
629
  return resolved;
626
630
  }
631
+ resolveLevelRetention(levels, field) {
632
+ if (levels === void 0) {
633
+ return Object.freeze({});
634
+ }
635
+ const resolved = {};
636
+ for (const [level, duration] of Object.entries(levels)) {
637
+ const normalized = level.trim().toLowerCase();
638
+ if (normalized.length === 0) {
639
+ throw new Error(`${field}.retention.levels contains an empty level name`);
640
+ }
641
+ if (resolved[normalized] !== void 0) {
642
+ throw new Error(`${field}.retention.levels declares "${normalized}" more than once`);
643
+ }
644
+ resolved[normalized] = this.durations.parse(
645
+ duration,
646
+ `${field}.retention.levels.${normalized}`
647
+ );
648
+ }
649
+ return Object.freeze(resolved);
650
+ }
627
651
  validateRetention(target, field) {
628
652
  const retention = target.retention;
629
653
  const requiredSamplesMs = retention.rawMs + retention.lateArrivalMs;
@@ -3377,73 +3401,49 @@ var TelemetryRepository = class {
3377
3401
  lastSequence: sample.sequence
3378
3402
  };
3379
3403
  }
3404
+ /**
3405
+ * Raw retention is purely time-based, matching the native collector: every
3406
+ * expired row goes in one set-based statement per level band. No page size,
3407
+ * no row cap, and no rollup-completion gate — metric samples are extracted at
3408
+ * ingest and retained on their own clock, so dropping a raw row costs no
3409
+ * metric fidelity, and no row can outlive its window waiting on a rollup.
3410
+ */
3380
3411
  createRawEventRetentionStep(nowMs) {
3381
- const cutoffMs = nowMs - this.options.retention.rawMs;
3382
3412
  const table = this.options.tableMap.quoted("rawEvents");
3383
- const readFirstPage = this.options.connection.prepare(
3384
- `SELECT producer_id, sequence, event_id, occurred_at_ms, monotonic_ns,
3385
- source, process_kind, level, label, conversation_id,
3386
- conversation_id_kind, correlation_id, metadata_json, schema_version
3387
- FROM ${table}
3388
- WHERE target_id = ? AND occurred_at_ms < ?
3389
- ORDER BY occurred_at_ms ASC, producer_id ASC, sequence ASC
3390
- LIMIT ${RETENTION_PAGE_SIZE}`
3391
- );
3392
- const readNextPage = this.options.connection.prepare(
3393
- `SELECT producer_id, sequence, event_id, occurred_at_ms, monotonic_ns,
3394
- source, process_kind, level, label, conversation_id,
3395
- conversation_id_kind, correlation_id, metadata_json, schema_version
3396
- FROM ${table}
3397
- WHERE target_id = ? AND occurred_at_ms < ?
3398
- AND (occurred_at_ms, producer_id, sequence) > (?, ?, ?)
3399
- ORDER BY occurred_at_ms ASC, producer_id ASC, sequence ASC
3400
- LIMIT ${RETENTION_PAGE_SIZE}`
3413
+ const levelMs = this.options.retention.levelMs ?? {};
3414
+ const levels = Object.keys(levelMs);
3415
+ const removeByLevel = this.options.connection.prepare(
3416
+ `DELETE FROM ${table}
3417
+ WHERE target_id = ? AND lower(coalesce(level, '')) = ? AND occurred_at_ms < ?`
3401
3418
  );
3402
- const remove = this.options.connection.prepare(
3403
- `DELETE FROM ${table} WHERE target_id = ? AND producer_id = ? AND sequence = ?`
3419
+ const fallbackPlaceholders = levels.map(() => "?").join(", ");
3420
+ const removeFallback = this.options.connection.prepare(
3421
+ `DELETE FROM ${table}
3422
+ WHERE target_id = ? AND occurred_at_ms < ?` + (levels.length === 0 ? "" : ` AND lower(coalesce(level, '')) NOT IN (${fallbackPlaceholders})`)
3404
3423
  );
3405
- let cursor = null;
3424
+ let done = false;
3406
3425
  return () => {
3407
- const rows = cursor === null ? readFirstPage.all(this.options.targetId, cutoffMs) : readNextPage.all(
3408
- this.options.targetId,
3409
- cutoffMs,
3410
- cursor.occurredAtMs,
3411
- cursor.producerId,
3412
- cursor.sequence
3413
- );
3414
- if (rows.length === 0) {
3426
+ if (done) {
3415
3427
  return { deleted: 0, done: true };
3416
3428
  }
3417
- const scanned = rows.map((row) => {
3418
- const parsed = this.rowParser.parseRawEnvelope(row);
3419
- if (!parsed.ok) {
3420
- throw new Error(parsed.error);
3421
- }
3422
- return parsed.value;
3423
- });
3424
- const eligible = scanned.filter((envelope) => this.rawEventHasRequiredRollups(envelope));
3429
+ done = true;
3425
3430
  const transaction = this.options.connection.transaction(() => {
3426
- let deleted2 = 0;
3427
- for (const envelope of eligible) {
3428
- deleted2 += remove.run(
3429
- this.options.targetId,
3430
- envelope.producerId,
3431
- envelope.sequence
3432
- ).changes;
3431
+ let deleted = 0;
3432
+ for (const level of levels) {
3433
+ const retainMs = levelMs[level];
3434
+ if (retainMs === void 0) {
3435
+ continue;
3436
+ }
3437
+ deleted += removeByLevel.run(this.options.targetId, level, nowMs - retainMs).changes;
3433
3438
  }
3434
- return deleted2;
3439
+ deleted += removeFallback.run(
3440
+ this.options.targetId,
3441
+ nowMs - this.options.retention.rawMs,
3442
+ ...levels
3443
+ ).changes;
3444
+ return deleted;
3435
3445
  });
3436
- const deleted = transaction();
3437
- const last = scanned[scanned.length - 1];
3438
- if (last === void 0 || rows.length < RETENTION_PAGE_SIZE) {
3439
- return { deleted, done: true };
3440
- }
3441
- cursor = {
3442
- occurredAtMs: last.occurredAtMs,
3443
- producerId: last.producerId,
3444
- sequence: last.sequence
3445
- };
3446
- return { deleted, done: false };
3446
+ return { deleted: transaction(), done: true };
3447
3447
  };
3448
3448
  }
3449
3449
  rawEventHasRequiredRollups(envelope) {