@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
@@ -254,6 +254,7 @@ var TelemetryTableMap = class _TelemetryTableMap {
254
254
  rawEventsOccurredIndex: this.indexName(mapping.rawEvents, "occurred"),
255
255
  rawEventsConversationIndex: this.indexName(mapping.rawEvents, "conversation"),
256
256
  rawEventsLabelIndex: this.indexName(mapping.rawEvents, "label"),
257
+ rawEventsLevelIndex: this.indexName(mapping.rawEvents, "level"),
257
258
  metricSamplesTimeIndex: this.indexName(mapping.metricSamples, "time"),
258
259
  metricSamplesEventIndex: this.indexName(mapping.metricSamples, "event"),
259
260
  metricRollupsTimeIndex: this.indexName(mapping.metricRollups, "time")
@@ -428,6 +429,7 @@ var SqliteTargetSchema = import_zod.z.object({
428
429
  raw: DurationSchema,
429
430
  lateArrival: DurationSchema.optional(),
430
431
  samples: DurationSchema.optional(),
432
+ levels: import_zod.z.record(import_zod.z.string().min(1), DurationSchema).optional(),
431
433
  rollups: import_zod.z.array(
432
434
  import_zod.z.object({
433
435
  resolution: DurationSchema,
@@ -570,6 +572,7 @@ var NodeTelemetryConfigurationParser = class {
570
572
  true
571
573
  );
572
574
  const samplesMs = target.retention.samples === void 0 ? rawMs + lateArrivalMs : this.durations.parse(target.retention.samples, `${field}.retention.samples`);
575
+ const levelMs = this.resolveLevelRetention(target.retention.levels, field);
573
576
  const rollups = target.retention.rollups.map(
574
577
  (tier, tierIndex) => Object.freeze({
575
578
  resolutionMs: this.durations.parse(
@@ -604,6 +607,7 @@ var NodeTelemetryConfigurationParser = class {
604
607
  rawMs,
605
608
  lateArrivalMs,
606
609
  samplesMs,
610
+ levelMs,
607
611
  rollups: Object.freeze(rollups)
608
612
  }),
609
613
  maintenance: Object.freeze({
@@ -634,6 +638,26 @@ var NodeTelemetryConfigurationParser = class {
634
638
  }
635
639
  return resolved;
636
640
  }
641
+ resolveLevelRetention(levels, field) {
642
+ if (levels === void 0) {
643
+ return Object.freeze({});
644
+ }
645
+ const resolved = {};
646
+ for (const [level, duration] of Object.entries(levels)) {
647
+ const normalized = level.trim().toLowerCase();
648
+ if (normalized.length === 0) {
649
+ throw new Error(`${field}.retention.levels contains an empty level name`);
650
+ }
651
+ if (resolved[normalized] !== void 0) {
652
+ throw new Error(`${field}.retention.levels declares "${normalized}" more than once`);
653
+ }
654
+ resolved[normalized] = this.durations.parse(
655
+ duration,
656
+ `${field}.retention.levels.${normalized}`
657
+ );
658
+ }
659
+ return Object.freeze(resolved);
660
+ }
637
661
  validateRetention(target, field) {
638
662
  const retention = target.retention;
639
663
  const requiredSamplesMs = retention.rawMs + retention.lateArrivalMs;
@@ -3387,73 +3411,49 @@ var TelemetryRepository = class {
3387
3411
  lastSequence: sample.sequence
3388
3412
  };
3389
3413
  }
3414
+ /**
3415
+ * Raw retention is purely time-based, matching the native collector: every
3416
+ * expired row goes in one set-based statement per level band. No page size,
3417
+ * no row cap, and no rollup-completion gate — metric samples are extracted at
3418
+ * ingest and retained on their own clock, so dropping a raw row costs no
3419
+ * metric fidelity, and no row can outlive its window waiting on a rollup.
3420
+ */
3390
3421
  createRawEventRetentionStep(nowMs) {
3391
- const cutoffMs = nowMs - this.options.retention.rawMs;
3392
3422
  const table = this.options.tableMap.quoted("rawEvents");
3393
- const readFirstPage = this.options.connection.prepare(
3394
- `SELECT producer_id, sequence, event_id, occurred_at_ms, monotonic_ns,
3395
- source, process_kind, level, label, conversation_id,
3396
- conversation_id_kind, correlation_id, metadata_json, schema_version
3397
- FROM ${table}
3398
- WHERE target_id = ? AND occurred_at_ms < ?
3399
- ORDER BY occurred_at_ms ASC, producer_id ASC, sequence ASC
3400
- LIMIT ${RETENTION_PAGE_SIZE}`
3401
- );
3402
- const readNextPage = this.options.connection.prepare(
3403
- `SELECT producer_id, sequence, event_id, occurred_at_ms, monotonic_ns,
3404
- source, process_kind, level, label, conversation_id,
3405
- conversation_id_kind, correlation_id, metadata_json, schema_version
3406
- FROM ${table}
3407
- WHERE target_id = ? AND occurred_at_ms < ?
3408
- AND (occurred_at_ms, producer_id, sequence) > (?, ?, ?)
3409
- ORDER BY occurred_at_ms ASC, producer_id ASC, sequence ASC
3410
- LIMIT ${RETENTION_PAGE_SIZE}`
3423
+ const levelMs = this.options.retention.levelMs ?? {};
3424
+ const levels = Object.keys(levelMs);
3425
+ const removeByLevel = this.options.connection.prepare(
3426
+ `DELETE FROM ${table}
3427
+ WHERE target_id = ? AND lower(coalesce(level, '')) = ? AND occurred_at_ms < ?`
3411
3428
  );
3412
- const remove = this.options.connection.prepare(
3413
- `DELETE FROM ${table} WHERE target_id = ? AND producer_id = ? AND sequence = ?`
3429
+ const fallbackPlaceholders = levels.map(() => "?").join(", ");
3430
+ const removeFallback = this.options.connection.prepare(
3431
+ `DELETE FROM ${table}
3432
+ WHERE target_id = ? AND occurred_at_ms < ?` + (levels.length === 0 ? "" : ` AND lower(coalesce(level, '')) NOT IN (${fallbackPlaceholders})`)
3414
3433
  );
3415
- let cursor = null;
3434
+ let done = false;
3416
3435
  return () => {
3417
- const rows = cursor === null ? readFirstPage.all(this.options.targetId, cutoffMs) : readNextPage.all(
3418
- this.options.targetId,
3419
- cutoffMs,
3420
- cursor.occurredAtMs,
3421
- cursor.producerId,
3422
- cursor.sequence
3423
- );
3424
- if (rows.length === 0) {
3436
+ if (done) {
3425
3437
  return { deleted: 0, done: true };
3426
3438
  }
3427
- const scanned = rows.map((row) => {
3428
- const parsed = this.rowParser.parseRawEnvelope(row);
3429
- if (!parsed.ok) {
3430
- throw new Error(parsed.error);
3431
- }
3432
- return parsed.value;
3433
- });
3434
- const eligible = scanned.filter((envelope) => this.rawEventHasRequiredRollups(envelope));
3439
+ done = true;
3435
3440
  const transaction = this.options.connection.transaction(() => {
3436
- let deleted2 = 0;
3437
- for (const envelope of eligible) {
3438
- deleted2 += remove.run(
3439
- this.options.targetId,
3440
- envelope.producerId,
3441
- envelope.sequence
3442
- ).changes;
3441
+ let deleted = 0;
3442
+ for (const level of levels) {
3443
+ const retainMs = levelMs[level];
3444
+ if (retainMs === void 0) {
3445
+ continue;
3446
+ }
3447
+ deleted += removeByLevel.run(this.options.targetId, level, nowMs - retainMs).changes;
3443
3448
  }
3444
- return deleted2;
3449
+ deleted += removeFallback.run(
3450
+ this.options.targetId,
3451
+ nowMs - this.options.retention.rawMs,
3452
+ ...levels
3453
+ ).changes;
3454
+ return deleted;
3445
3455
  });
3446
- const deleted = transaction();
3447
- const last = scanned[scanned.length - 1];
3448
- if (last === void 0 || rows.length < RETENTION_PAGE_SIZE) {
3449
- return { deleted, done: true };
3450
- }
3451
- cursor = {
3452
- occurredAtMs: last.occurredAtMs,
3453
- producerId: last.producerId,
3454
- sequence: last.sequence
3455
- };
3456
- return { deleted, done: false };
3456
+ return { deleted: transaction(), done: true };
3457
3457
  };
3458
3458
  }
3459
3459
  rawEventHasRequiredRollups(envelope) {