@worker-manager/metrics 1.0.0 → 1.1.0

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 (62) hide show
  1. package/README.md +86 -6
  2. package/dist/HistoryAdmin.d.ts +23 -87
  3. package/dist/HistoryAdmin.js +21 -330
  4. package/dist/HistoryAdmin.js.map +1 -1
  5. package/dist/HistoryStore.d.ts +9 -9
  6. package/dist/HistoryStore.js +22 -0
  7. package/dist/HistoryStore.js.map +1 -1
  8. package/dist/LatencySampler.d.ts +27 -32
  9. package/dist/LatencySampler.js +55 -156
  10. package/dist/LatencySampler.js.map +1 -1
  11. package/dist/LatencyStore.d.ts +8 -3
  12. package/dist/LatencyStore.js +18 -0
  13. package/dist/LatencyStore.js.map +1 -1
  14. package/dist/MetricsRecorder.d.ts +34 -10
  15. package/dist/MetricsRecorder.js +30 -20
  16. package/dist/MetricsRecorder.js.map +1 -1
  17. package/dist/RedisHistoryAdmin.d.ts +95 -0
  18. package/dist/RedisHistoryAdmin.js +328 -0
  19. package/dist/RedisHistoryAdmin.js.map +1 -0
  20. package/dist/RedisMetricsHistoryProvider.d.ts +7 -17
  21. package/dist/RedisMetricsHistoryProvider.js +9 -136
  22. package/dist/RedisMetricsHistoryProvider.js.map +1 -1
  23. package/dist/RedisMetricsStore.d.ts +27 -0
  24. package/dist/RedisMetricsStore.js +42 -0
  25. package/dist/RedisMetricsStore.js.map +1 -0
  26. package/dist/StoreHistoryProvider.d.ts +27 -0
  27. package/dist/StoreHistoryProvider.js +127 -0
  28. package/dist/StoreHistoryProvider.js.map +1 -0
  29. package/dist/index.d.ts +10 -2
  30. package/dist/index.js +10 -1
  31. package/dist/index.js.map +1 -1
  32. package/dist/jobSources.d.ts +97 -0
  33. package/dist/jobSources.js +248 -0
  34. package/dist/jobSources.js.map +1 -0
  35. package/dist/keys.d.ts +7 -0
  36. package/dist/keys.js +23 -1
  37. package/dist/keys.js.map +1 -1
  38. package/dist/postgres/PostgresMetricsHistoryProvider.d.ts +37 -0
  39. package/dist/postgres/PostgresMetricsHistoryProvider.js +30 -0
  40. package/dist/postgres/PostgresMetricsHistoryProvider.js.map +1 -0
  41. package/dist/postgres/PostgresMetricsStore.d.ts +65 -0
  42. package/dist/postgres/PostgresMetricsStore.js +88 -0
  43. package/dist/postgres/PostgresMetricsStore.js.map +1 -0
  44. package/dist/postgres/admin.d.ts +31 -0
  45. package/dist/postgres/admin.js +178 -0
  46. package/dist/postgres/admin.js.map +1 -0
  47. package/dist/postgres/connection.d.ts +53 -0
  48. package/dist/postgres/connection.js +54 -0
  49. package/dist/postgres/connection.js.map +1 -0
  50. package/dist/postgres/context.d.ts +29 -0
  51. package/dist/postgres/context.js +76 -0
  52. package/dist/postgres/context.js.map +1 -0
  53. package/dist/postgres/schema.d.ts +26 -0
  54. package/dist/postgres/schema.js +148 -0
  55. package/dist/postgres/schema.js.map +1 -0
  56. package/dist/postgres/stores.d.ts +51 -0
  57. package/dist/postgres/stores.js +252 -0
  58. package/dist/postgres/stores.js.map +1 -0
  59. package/dist/store.d.ts +80 -0
  60. package/dist/store.js +3 -0
  61. package/dist/store.js.map +1 -0
  62. package/package.json +13 -3
@@ -0,0 +1,80 @@
1
+ import type { MetricsClient } from './connection';
2
+ import type { MinutePoint } from './dataMapping';
3
+ import type { HistoryStats, PurgeOptions, PurgeResult } from './HistoryAdmin';
4
+ export interface Retention {
5
+ /** Days of minute-level detail. Doubles as the recorder's catch-up window. */
6
+ minutes: number;
7
+ /** Days of hourly rollup. */
8
+ hours: number;
9
+ /** Days of daily totals, which is what the shipped charts read. */
10
+ days: number;
11
+ }
12
+ export type LatencyMetric = 'runtime' | 'waittime';
13
+ /**
14
+ * Completed and failed throughput, stored at minute, hour and day resolution per queue plus
15
+ * the `__global__` rollup.
16
+ *
17
+ * Writes are absolute per-minute values, never increments: the minute tier is a ledger, and
18
+ * each write applies only its difference against what the ledger already holds, to every
19
+ * coarser tier. Re-writing a minute that is already stored is therefore a no-op, which is what
20
+ * lets a restarted recorder, or a second one, re-snapshot an overlapping window safely.
21
+ */
22
+ export interface CounterStore {
23
+ readonly retention: Retention;
24
+ upsertMinutes(queue: string, metric: string, points: MinutePoint[]): Promise<void>;
25
+ /** One entry per requested day: `null` when never recorded, a number (maybe 0) when it was. */
26
+ readDailyTotals(queue: string, metric: string, days: string[]): Promise<(number | null)[]>;
27
+ /** Hourly buckets over the given days, keyed by absolute hour index. */
28
+ readHours(queue: string, metric: string, days: string[]): Promise<Record<string, number>>;
29
+ }
30
+ /**
31
+ * Latency histograms (runtime, waittime) and the queue-age gauge, at hour and day resolution,
32
+ * plus the small amount of coordination state the sampler keeps next to them.
33
+ *
34
+ * Histograms are merged by increment, so unlike the counters a double write double-counts.
35
+ * The lease is what prevents that: only its holder scans a queue on a given tick.
36
+ */
37
+ export interface LatencyStorage {
38
+ readonly retention: Retention;
39
+ addSamples(queue: string, metric: LatencyMetric, hour: number, vector: number[]): Promise<void>;
40
+ recordQueueAge(queue: string, hour: number, ms: number): Promise<void>;
41
+ /** Keyed by ISO day for `'day'`, by absolute hour index for `'hour'`. */
42
+ readRange(queue: string, metric: LatencyMetric, granularity: 'hour' | 'day', days: string[]): Promise<Record<string, number[]>>;
43
+ readQueueAge(queue: string, granularity: 'hour' | 'day', days: string[]): Promise<Record<string, number>>;
44
+ /** Set-if-absent with a crash-ceiling TTL. `true` when `holder` now owns the queue's lease. */
45
+ acquireLease(queue: string, holder: string, ttlMs: number): Promise<boolean>;
46
+ /** Compare and delete: a lease that expired and was retaken by someone else is left alone. */
47
+ releaseLease(queue: string, holder: string): Promise<void>;
48
+ /** Finish-time bound of the last scan, epoch ms, or `null` for a cold start. */
49
+ readWatermark(queue: string): Promise<number | null>;
50
+ writeWatermark(queue: string, ms: number, ttlSeconds: number): Promise<void>;
51
+ }
52
+ /** Footprint and cleanup, backing the board's storage panel. */
53
+ export interface HistoryAdministration {
54
+ stats(): Promise<HistoryStats>;
55
+ purge(options?: PurgeOptions): Promise<PurgeResult>;
56
+ }
57
+ /**
58
+ * Where recorded history lives. `RedisMetricsStore` and `PostgresMetricsStore` are the two
59
+ * implementations; hand either to `MetricsRecorder`, a history provider or
60
+ * `MetricsHistoryAdmin` as `store`.
61
+ *
62
+ * The members are the seam those classes are built on rather than an API to call directly.
63
+ */
64
+ export interface MetricsStore {
65
+ /** @internal */
66
+ counterStore(retention: Retention): CounterStore;
67
+ /** @internal */
68
+ latencyStore(retention: Retention): LatencyStorage;
69
+ /** @internal */
70
+ administration(): HistoryAdministration;
71
+ /**
72
+ * @internal
73
+ * The Redis the sampler reads Redis-backed queues through. A Redis store answers with its
74
+ * own client, which is the queues' Redis in the classic single-Redis setup; `null` makes the
75
+ * sampler ask each adapter for its own client instead.
76
+ */
77
+ readonly jobClient: MetricsClient | null;
78
+ /** Releases what the store opened itself. A connection handed in is left to its owner. */
79
+ close(): Promise<void>;
80
+ }
package/dist/store.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@worker-manager/metrics",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Opt-in long-retention historical job metrics recorder and provider for Worker Manager.",
5
5
  "keywords": [
6
6
  "bull",
@@ -8,6 +8,8 @@
8
8
  "dashboard",
9
9
  "history",
10
10
  "metrics",
11
+ "postgres",
12
+ "postgresql",
11
13
  "queue",
12
14
  "redis"
13
15
  ],
@@ -32,22 +34,30 @@
32
34
  "test": "jest"
33
35
  },
34
36
  "dependencies": {
35
- "@worker-manager/api": "1.0.0"
37
+ "@worker-manager/api": "1.1.0"
36
38
  },
37
39
  "devDependencies": {
38
40
  "@types/jest": "^30.0.0",
39
41
  "@types/node": "^22.20.1",
42
+ "@types/pg": "^8.23.1",
40
43
  "bullmq": "^5.81.3",
41
44
  "bullmq-v6": "npm:bullmq@^6",
42
45
  "ioredis": "^6.0.0",
43
46
  "jest": "^30.4.2",
47
+ "pg": "^8.23.0",
44
48
  "ts-jest": "^29.4.12",
45
49
  "typescript": "^5.9.3"
46
50
  },
47
51
  "peerDependencies": {
48
- "ioredis": "^5.0.0 || ^6.0.0"
52
+ "ioredis": "^5.0.0 || ^6.0.0",
53
+ "pg": "^8.11.0"
49
54
  },
50
55
  "engines": {
51
56
  "node": ">=20"
57
+ },
58
+ "peerDependenciesMeta": {
59
+ "pg": {
60
+ "optional": true
61
+ }
52
62
  }
53
63
  }