@grest-ts/metrics 0.0.5

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 (125) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +40 -0
  3. package/dist/src/GGMetric.d.ts +60 -0
  4. package/dist/src/GGMetric.d.ts.map +1 -0
  5. package/dist/src/GGMetric.js +64 -0
  6. package/dist/src/GGMetric.js.map +1 -0
  7. package/dist/src/GGMetricKey.d.ts +13 -0
  8. package/dist/src/GGMetricKey.d.ts.map +1 -0
  9. package/dist/src/GGMetricKey.js +29 -0
  10. package/dist/src/GGMetricKey.js.map +1 -0
  11. package/dist/src/GGMetrics.d.ts +10 -0
  12. package/dist/src/GGMetrics.d.ts.map +1 -0
  13. package/dist/src/GGMetrics.js +29 -0
  14. package/dist/src/GGMetrics.js.map +1 -0
  15. package/dist/src/GGMetricsDefineStorage.d.ts +4 -0
  16. package/dist/src/GGMetricsDefineStorage.d.ts.map +1 -0
  17. package/dist/src/GGMetricsDefineStorage.js +7 -0
  18. package/dist/src/GGMetricsDefineStorage.js.map +1 -0
  19. package/dist/src/GGMetricsLoader.d.ts +8 -0
  20. package/dist/src/GGMetricsLoader.d.ts.map +1 -0
  21. package/dist/src/GGMetricsLoader.js +17 -0
  22. package/dist/src/GGMetricsLoader.js.map +1 -0
  23. package/dist/src/GGMetricsStore.d.ts +9 -0
  24. package/dist/src/GGMetricsStore.d.ts.map +1 -0
  25. package/dist/src/GGMetricsStore.js +20 -0
  26. package/dist/src/GGMetricsStore.js.map +1 -0
  27. package/dist/src/exporters/GGJsonMetricsExporter.d.ts +41 -0
  28. package/dist/src/exporters/GGJsonMetricsExporter.d.ts.map +1 -0
  29. package/dist/src/exporters/GGJsonMetricsExporter.js +129 -0
  30. package/dist/src/exporters/GGJsonMetricsExporter.js.map +1 -0
  31. package/dist/src/exporters/GGMetricsExporter.d.ts +41 -0
  32. package/dist/src/exporters/GGMetricsExporter.d.ts.map +1 -0
  33. package/dist/src/exporters/GGMetricsExporter.js +70 -0
  34. package/dist/src/exporters/GGMetricsExporter.js.map +1 -0
  35. package/dist/src/exporters/GGNestedMetricsExporter.d.ts +33 -0
  36. package/dist/src/exporters/GGNestedMetricsExporter.d.ts.map +1 -0
  37. package/dist/src/exporters/GGNestedMetricsExporter.js +275 -0
  38. package/dist/src/exporters/GGNestedMetricsExporter.js.map +1 -0
  39. package/dist/src/index-browser.d.ts +17 -0
  40. package/dist/src/index-browser.d.ts.map +1 -0
  41. package/dist/src/index-browser.js +17 -0
  42. package/dist/src/index-browser.js.map +1 -0
  43. package/dist/src/index-node.d.ts +17 -0
  44. package/dist/src/index-node.d.ts.map +1 -0
  45. package/dist/src/index-node.js +20 -0
  46. package/dist/src/index-node.js.map +1 -0
  47. package/dist/src/keys/GGCounterKey.d.ts +11 -0
  48. package/dist/src/keys/GGCounterKey.d.ts.map +1 -0
  49. package/dist/src/keys/GGCounterKey.js +21 -0
  50. package/dist/src/keys/GGCounterKey.js.map +1 -0
  51. package/dist/src/keys/GGGaugeKey.d.ts +13 -0
  52. package/dist/src/keys/GGGaugeKey.d.ts.map +1 -0
  53. package/dist/src/keys/GGGaugeKey.js +27 -0
  54. package/dist/src/keys/GGGaugeKey.js.map +1 -0
  55. package/dist/src/keys/GGHistogramKey.d.ts +13 -0
  56. package/dist/src/keys/GGHistogramKey.d.ts.map +1 -0
  57. package/dist/src/keys/GGHistogramKey.js +27 -0
  58. package/dist/src/keys/GGHistogramKey.js.map +1 -0
  59. package/dist/src/keys/GGLazyGaugeKey.d.ts +21 -0
  60. package/dist/src/keys/GGLazyGaugeKey.d.ts.map +1 -0
  61. package/dist/src/keys/GGLazyGaugeKey.js +25 -0
  62. package/dist/src/keys/GGLazyGaugeKey.js.map +1 -0
  63. package/dist/src/metric/GGCounter.d.ts +7 -0
  64. package/dist/src/metric/GGCounter.d.ts.map +1 -0
  65. package/dist/src/metric/GGCounter.js +14 -0
  66. package/dist/src/metric/GGCounter.js.map +1 -0
  67. package/dist/src/metric/GGGauge.d.ts +9 -0
  68. package/dist/src/metric/GGGauge.d.ts.map +1 -0
  69. package/dist/src/metric/GGGauge.js +31 -0
  70. package/dist/src/metric/GGGauge.js.map +1 -0
  71. package/dist/src/metric/GGHistogram.d.ts +27 -0
  72. package/dist/src/metric/GGHistogram.d.ts.map +1 -0
  73. package/dist/src/metric/GGHistogram.js +41 -0
  74. package/dist/src/metric/GGHistogram.js.map +1 -0
  75. package/dist/src/metric/GGLazyGauge.d.ts +20 -0
  76. package/dist/src/metric/GGLazyGauge.d.ts.map +1 -0
  77. package/dist/src/metric/GGLazyGauge.js +27 -0
  78. package/dist/src/metric/GGLazyGauge.js.map +1 -0
  79. package/dist/src/tsconfig.json +16 -0
  80. package/dist/testkit/GGMetricsCommands.d.ts +18 -0
  81. package/dist/testkit/GGMetricsCommands.d.ts.map +1 -0
  82. package/dist/testkit/GGMetricsCommands.js +77 -0
  83. package/dist/testkit/GGMetricsCommands.js.map +1 -0
  84. package/dist/testkit/GGMetricsInterceptor.d.ts +34 -0
  85. package/dist/testkit/GGMetricsInterceptor.d.ts.map +1 -0
  86. package/dist/testkit/GGMetricsInterceptor.js +202 -0
  87. package/dist/testkit/GGMetricsInterceptor.js.map +1 -0
  88. package/dist/testkit/GGMetricsWith.d.ts +22 -0
  89. package/dist/testkit/GGMetricsWith.d.ts.map +1 -0
  90. package/dist/testkit/GGMetricsWith.js +61 -0
  91. package/dist/testkit/GGMetricsWith.js.map +1 -0
  92. package/dist/testkit/GGTestMetricsExporter.d.ts +40 -0
  93. package/dist/testkit/GGTestMetricsExporter.d.ts.map +1 -0
  94. package/dist/testkit/GGTestMetricsExporter.js +119 -0
  95. package/dist/testkit/GGTestMetricsExporter.js.map +1 -0
  96. package/dist/testkit/GGTestSelectorMetrics.d.ts +15 -0
  97. package/dist/testkit/GGTestSelectorMetrics.d.ts.map +1 -0
  98. package/dist/testkit/GGTestSelectorMetrics.js +16 -0
  99. package/dist/testkit/GGTestSelectorMetrics.js.map +1 -0
  100. package/dist/testkit/index-testkit.d.ts +6 -0
  101. package/dist/testkit/index-testkit.d.ts.map +1 -0
  102. package/dist/testkit/index-testkit.js +6 -0
  103. package/dist/testkit/index-testkit.js.map +1 -0
  104. package/dist/tsconfig.publish.tsbuildinfo +1 -0
  105. package/package.json +58 -0
  106. package/src/GGMetric.ts +124 -0
  107. package/src/GGMetricKey.ts +38 -0
  108. package/src/GGMetrics.ts +34 -0
  109. package/src/GGMetricsDefineStorage.ts +8 -0
  110. package/src/GGMetricsLoader.ts +21 -0
  111. package/src/GGMetricsStore.ts +26 -0
  112. package/src/exporters/GGJsonMetricsExporter.ts +176 -0
  113. package/src/exporters/GGMetricsExporter.ts +88 -0
  114. package/src/exporters/GGNestedMetricsExporter.ts +335 -0
  115. package/src/index-browser.ts +16 -0
  116. package/src/index-node.ts +21 -0
  117. package/src/keys/GGCounterKey.ts +29 -0
  118. package/src/keys/GGGaugeKey.ts +37 -0
  119. package/src/keys/GGHistogramKey.ts +37 -0
  120. package/src/keys/GGLazyGaugeKey.ts +36 -0
  121. package/src/metric/GGCounter.ts +19 -0
  122. package/src/metric/GGGauge.ts +38 -0
  123. package/src/metric/GGHistogram.ts +68 -0
  124. package/src/metric/GGLazyGauge.ts +31 -0
  125. package/src/tsconfig.json +16 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Grest Games OÜ
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # @grest-ts/metrics
2
+
3
+ Type-safe metrics collection library for Grest Framework.
4
+
5
+ ## Features
6
+
7
+ Type-safe metrics collection library with support for counters, gauges, and histograms.
8
+
9
+ Provides a structured way to define, collect, and export application metrics with:
10
+
11
+ - Prometheus-style metrics (Counter, Gauge, Histogram)
12
+ - Type-safe labels
13
+ - Centralized metric definitions
14
+ - Multiple export formats
15
+
16
+ Type-safe metrics collection library with support for counters, gauges, and histograms.
17
+
18
+ ## Quick usage example
19
+
20
+ ```typescript
21
+ // Define metric keys.
22
+ // This additionally acts as documentation of metrics provided by the application.
23
+ export const AppMetrics = GGMetrics.define('/app/', () => ({
24
+ actions: new GGCounterKey('actions_total', {
25
+ help: 'Total number of actions',
26
+ labelNames: ['type']
27
+ }),
28
+ // ... add more metrics here. All well documented and type safe.
29
+ }));
30
+
31
+ // Usage in the runtime.
32
+ AppMetrics.actions.inc(1, {type: "read"}); // labels are typesafe (values are always strings)
33
+
34
+ ```
35
+
36
+ ## Documentation
37
+
38
+ - [Usage](./README-usage.md) - How to define and collect metrics
39
+ - [Testing](./README-testkit.md) - How to test metric changes with testkit
40
+ - [Extending](./README-extending.md) - How to add custom exporters
@@ -0,0 +1,60 @@
1
+ import { GGMetricKey } from "./GGMetricKey";
2
+ /**
3
+ * Configuration for grouping metrics in nested exporters.
4
+ * - labels: Which labels to use for grouping (must be subset of labelNames)
5
+ * - template: Optional template string for the group key. Use {labelName} for placeholders.
6
+ * Missing values become empty strings. Defaults to values.join(',')
7
+ * Example: "{api}.{method}" produces "MyApi.myMethod"
8
+ */
9
+ export interface GroupByConfig<TLabels extends GGMetricLabels = {}> {
10
+ labels: readonly (keyof TLabels & string)[];
11
+ template?: string;
12
+ }
13
+ export interface GGMetricOptionsBase {
14
+ help: string;
15
+ maxLabelCombinations?: number;
16
+ }
17
+ export interface GGMetricOptionsWithLabels<TLabels extends GGMetricLabels> {
18
+ help: string;
19
+ maxLabelCombinations?: number;
20
+ labelNames: readonly (keyof TLabels & string)[];
21
+ groupBy?: GroupByConfig<TLabels>;
22
+ }
23
+ /**
24
+ * Options for metrics. When TLabels has keys, labelNames is required and must match those keys.
25
+ * Uses {} as "no labels" because keyof {} = never, while keyof Record<string, never> = string.
26
+ */
27
+ export type GGMetricOptions<TLabels extends GGMetricLabels = {}> = keyof TLabels extends never ? GGMetricOptionsBase : GGMetricOptionsWithLabels<TLabels>;
28
+ export declare abstract class GGMetric<TLabels extends GGMetricLabels = {}, TValue = unknown, TKey extends GGMetricKey<TLabels> = GGMetricKey<TLabels>> {
29
+ readonly key: TKey;
30
+ private readonly values;
31
+ private readonly compiledGetKey;
32
+ constructor(key: TKey);
33
+ private compileGetKey;
34
+ get name(): string;
35
+ reset(): void;
36
+ protected abstract getDefaultValue(): TValue;
37
+ /**
38
+ * Can't throw.
39
+ * Uses AOT-compiled function for fast key generation.
40
+ */
41
+ protected getKey(labels: TLabels): tMetricKey;
42
+ /**
43
+ * Can't throw.
44
+ */
45
+ protected getByKey(key: tMetricKey): TValue | undefined;
46
+ protected setByKey(key: tMetricKey, value: TValue): void;
47
+ getValue(...args: LabelsArgs<TLabels>): TValue;
48
+ getValues(): Map<string, TValue>;
49
+ }
50
+ export type tMetricKey = string & {
51
+ tMetricKey: never;
52
+ };
53
+ export type GGMetricLabels = Record<string, string | number | boolean>;
54
+ /**
55
+ * Helper type for labels parameter. Makes labels required when TLabels has keys.
56
+ * - When TLabels = {}, no argument needed
57
+ * - When TLabels has keys, labels argument is required
58
+ */
59
+ export type LabelsArgs<TLabels extends GGMetricLabels> = keyof TLabels extends never ? [] : [labels: TLabels];
60
+ //# sourceMappingURL=GGMetric.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GGMetric.d.ts","sourceRoot":"","sources":["../../src/GGMetric.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAE1C;;;;;;GAMG;AACH,MAAM,WAAW,aAAa,CAAC,OAAO,SAAS,cAAc,GAAG,EAAE;IAC9D,MAAM,EAAE,SAAS,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC,EAAE,CAAC;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,yBAAyB,CAAC,OAAO,SAAS,cAAc;IACrE,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,UAAU,EAAE,SAAS,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC,EAAE,CAAC;IAChD,OAAO,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;CACpC;AAED;;;GAGG;AACH,MAAM,MAAM,eAAe,CAAC,OAAO,SAAS,cAAc,GAAG,EAAE,IAC3D,MAAM,OAAO,SAAS,KAAK,GACrB,mBAAmB,GACnB,yBAAyB,CAAC,OAAO,CAAC,CAAC;AAE7C,8BAAsB,QAAQ,CAC1B,OAAO,SAAS,cAAc,GAAG,EAAE,EACnC,MAAM,GAAG,OAAO,EAChB,IAAI,SAAS,WAAW,CAAC,OAAO,CAAC,GAAG,WAAW,CAAC,OAAO,CAAC;IAGxD,SAAgB,GAAG,EAAE,IAAI,CAAC;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6B;IACpD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAkC;gBAE9C,GAAG,EAAE,IAAI;IAK5B,OAAO,CAAC,aAAa;IAerB,IAAW,IAAI,IAAI,MAAM,CAExB;IAEM,KAAK,IAAI,IAAI;IAIpB,SAAS,CAAC,QAAQ,CAAC,eAAe,IAAI,MAAM;IAE5C;;;OAGG;IACH,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,UAAU;IAI7C;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS;IAcvD,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAIjD,QAAQ,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,MAAM;IAI9C,SAAS,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;CAG1C;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG;IAAE,UAAU,EAAE,KAAK,CAAA;CAAE,CAAC;AAExD,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;AAEvE;;;;GAIG;AACH,MAAM,MAAM,UAAU,CAAC,OAAO,SAAS,cAAc,IACjD,MAAM,OAAO,SAAS,KAAK,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC"}
@@ -0,0 +1,64 @@
1
+ export class GGMetric {
2
+ key;
3
+ values = new Map();
4
+ compiledGetKey;
5
+ constructor(key) {
6
+ this.key = key;
7
+ this.compiledGetKey = this.compileGetKey();
8
+ }
9
+ compileGetKey() {
10
+ const labelNames = this.key.labelNames;
11
+ if (labelNames.length === 0) {
12
+ return () => '';
13
+ }
14
+ // Build the function body: "name1=" + (l?.name1 ?? "") + ",name2=" + (l?.name2 ?? "")
15
+ let body = 'return ';
16
+ for (let i = 0; i < labelNames.length; i++) {
17
+ const name = labelNames[i];
18
+ if (i > 0)
19
+ body += '+","+';
20
+ body += `"${name}="+(l?.${name}??"")`;
21
+ }
22
+ return new Function('l', body);
23
+ }
24
+ get name() {
25
+ return this.key.name;
26
+ }
27
+ reset() {
28
+ this.values.clear();
29
+ }
30
+ /**
31
+ * Can't throw.
32
+ * Uses AOT-compiled function for fast key generation.
33
+ */
34
+ getKey(labels) {
35
+ return this.compiledGetKey(labels);
36
+ }
37
+ /**
38
+ * Can't throw.
39
+ */
40
+ getByKey(key) {
41
+ const value = this.values.get(key);
42
+ if (value === undefined) {
43
+ if (this.values.size >= this.key.maxLabelCombinations) {
44
+ return undefined;
45
+ }
46
+ const defaultValue = this.getDefaultValue();
47
+ this.setByKey(key, defaultValue);
48
+ return defaultValue;
49
+ }
50
+ else {
51
+ return value;
52
+ }
53
+ }
54
+ setByKey(key, value) {
55
+ this.values.set(key, value);
56
+ }
57
+ getValue(...args) {
58
+ return this.getByKey(this.getKey(args[0]));
59
+ }
60
+ getValues() {
61
+ return this.values;
62
+ }
63
+ }
64
+ //# sourceMappingURL=GGMetric.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GGMetric.js","sourceRoot":"","sources":["../../src/GGMetric.ts"],"names":[],"mappings":"AAmCA,MAAM,OAAgB,QAAQ;IAMV,GAAG,CAAO;IACT,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACnC,cAAc,CAAkC;IAEjE,YAAmB,GAAS;QACxB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;IAC/C,CAAC;IAEO,aAAa;QACjB,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC;QACvC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,GAAG,EAAE,CAAC,EAAgB,CAAC;QAClC,CAAC;QACD,sFAAsF;QACtF,IAAI,IAAI,GAAG,SAAS,CAAC;QACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;YAC3B,IAAI,CAAC,GAAG,CAAC;gBAAE,IAAI,IAAI,OAAO,CAAC;YAC3B,IAAI,IAAI,IAAI,IAAI,UAAU,IAAI,OAAO,CAAC;QAC1C,CAAC;QACD,OAAO,IAAI,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAoC,CAAC;IACtE,CAAC;IAED,IAAW,IAAI;QACX,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;IACzB,CAAC;IAEM,KAAK;QACR,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;IAID;;;OAGG;IACO,MAAM,CAAC,MAAe;QAC5B,OAAO,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAED;;OAEG;IACO,QAAQ,CAAC,GAAe;QAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACtB,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE,CAAC;gBACpD,OAAO,SAAS,CAAC;YACrB,CAAC;YACD,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;YAC5C,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;YACjC,OAAO,YAAY,CAAC;QACxB,CAAC;aAAM,CAAC;YACJ,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;IAES,QAAQ,CAAC,GAAe,EAAE,KAAa;QAC7C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAChC,CAAC;IAEM,QAAQ,CAAC,GAAG,IAAyB;QACxC,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAY,CAAC,CAAC,CAAC;IAC1D,CAAC;IAEM,SAAS;QACZ,OAAO,IAAI,CAAC,MAAM,CAAC;IACvB,CAAC;CACJ"}
@@ -0,0 +1,13 @@
1
+ import { GGMetric, GGMetricLabels, GGMetricOptions, GroupByConfig } from "./GGMetric.js";
2
+ export declare abstract class GGMetricKey<TLabels extends GGMetricLabels = {}, TMetric extends GGMetric<TLabels, any, any> = GGMetric<TLabels, any, any>> {
3
+ readonly root: string;
4
+ readonly name: string;
5
+ readonly help: string;
6
+ readonly labelNames: readonly string[];
7
+ readonly maxLabelCombinations?: number;
8
+ readonly groupBy?: GroupByConfig<TLabels>;
9
+ protected constructor(name: string, options: GGMetricOptions<TLabels>);
10
+ protected getMetric(): TMetric;
11
+ abstract create(): TMetric;
12
+ }
13
+ //# sourceMappingURL=GGMetricKey.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GGMetricKey.d.ts","sourceRoot":"","sources":["../../src/GGMetricKey.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,QAAQ,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAC,MAAM,eAAe,CAAC;AAEvF,8BAAsB,WAAW,CAC7B,OAAO,SAAS,cAAc,GAAG,EAAE,EACnC,OAAO,SAAS,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC;IAGzE,SAAgB,IAAI,EAAE,MAAM,CAAC;IAC7B,SAAgB,IAAI,EAAE,MAAM,CAAC;IAC7B,SAAgB,IAAI,EAAE,MAAM,CAAC;IAC7B,SAAgB,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9C,SAAgB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9C,SAAgB,OAAO,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IAEjD,SAAS,aAAa,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,CAAC,OAAO,CAAC;IAgBrE,SAAS,CAAC,SAAS,IAAI,OAAO;aAId,MAAM,IAAI,OAAO;CACpC"}
@@ -0,0 +1,29 @@
1
+ import { GGMetrics } from "./GGMetrics.js";
2
+ import { GG_METRICS } from "./GGMetricsLoader.js";
3
+ export class GGMetricKey {
4
+ root;
5
+ name;
6
+ help;
7
+ labelNames;
8
+ maxLabelCombinations;
9
+ groupBy;
10
+ constructor(name, options) {
11
+ this.root = GGMetrics.getDefinitionContext();
12
+ if (!this.root) {
13
+ throw new Error("Metric key must be created inside GGMetrics.define()");
14
+ }
15
+ this.name = this.root + name;
16
+ this.help = options.help;
17
+ this.labelNames = ('labelNames' in options ? options.labelNames : []);
18
+ this.maxLabelCombinations = options.maxLabelCombinations;
19
+ this.groupBy = ('groupBy' in options ? options.groupBy : undefined);
20
+ Object.freeze(this.labelNames);
21
+ if (this.groupBy) {
22
+ Object.freeze(this.groupBy.labels);
23
+ }
24
+ }
25
+ getMetric() {
26
+ return GG_METRICS.get().get(this);
27
+ }
28
+ }
29
+ //# sourceMappingURL=GGMetricKey.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GGMetricKey.js","sourceRoot":"","sources":["../../src/GGMetricKey.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAC,UAAU,EAAC,MAAM,sBAAsB,CAAC;AAGhD,MAAM,OAAgB,WAAW;IAKb,IAAI,CAAS;IACb,IAAI,CAAS;IACb,IAAI,CAAS;IACb,UAAU,CAAoB;IAC9B,oBAAoB,CAAU;IAC9B,OAAO,CAA0B;IAEjD,YAAsB,IAAY,EAAE,OAAiC;QACjE,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC,oBAAoB,EAAE,CAAC;QAC7C,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;QAC5E,CAAC;QACD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,UAAU,GAAG,CAAC,YAAY,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAwC,CAAC;QAC7G,IAAI,CAAC,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC;QACzD,IAAI,CAAC,OAAO,GAAG,CAAC,SAAS,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAuC,CAAC;QAC1G,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC/B,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACvC,CAAC;IACL,CAAC;IAES,SAAS;QACf,OAAO,UAAU,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAY,CAAC;IACjD,CAAC;CAGJ"}
@@ -0,0 +1,10 @@
1
+ export type GGMetricsDefinition<T> = T & {
2
+ __isGGMetricsDefinition: never;
3
+ };
4
+ export declare class GGMetrics {
5
+ static define<T>(name: string, define: () => T): GGMetricsDefinition<T>;
6
+ static getDefinitionContext(): string;
7
+ static toJSON(metrics: GGMetricsDefinition<any>): Record<string, unknown>;
8
+ private static collectKeys;
9
+ }
10
+ //# sourceMappingURL=GGMetrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GGMetrics.d.ts","sourceRoot":"","sources":["../../src/GGMetrics.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,mBAAmB,CAAC,CAAC,IAAI,CAAC,GAAG;IAAE,uBAAuB,EAAE,KAAK,CAAA;CAAE,CAAC;AAE5E,qBAAa,SAAS;WAEJ,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC;WAIhE,oBAAoB,IAAI,MAAM;WAI9B,MAAM,CAAC,OAAO,EAAE,mBAAmB,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAMhF,OAAO,CAAC,MAAM,CAAC,WAAW;CAY7B"}
@@ -0,0 +1,29 @@
1
+ import { GGMetricKey } from "./GGMetricKey.js";
2
+ import { METRICS_DEFINE_CONTEXT } from "./GGMetricsDefineStorage.js";
3
+ export class GGMetrics {
4
+ static define(name, define) {
5
+ return METRICS_DEFINE_CONTEXT.run(name, define);
6
+ }
7
+ static getDefinitionContext() {
8
+ return METRICS_DEFINE_CONTEXT.getStore();
9
+ }
10
+ static toJSON(metrics) {
11
+ const result = {};
12
+ this.collectKeys(metrics, result);
13
+ return result;
14
+ }
15
+ static collectKeys(obj, result) {
16
+ if (obj instanceof GGMetricKey) {
17
+ result[obj.name] = {
18
+ type: obj.constructor.name,
19
+ help: obj.help
20
+ };
21
+ }
22
+ else if (obj && typeof obj === 'object') {
23
+ for (const value of Object.values(obj)) {
24
+ this.collectKeys(value, result);
25
+ }
26
+ }
27
+ }
28
+ }
29
+ //# sourceMappingURL=GGMetrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GGMetrics.js","sourceRoot":"","sources":["../../src/GGMetrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAC,sBAAsB,EAAC,MAAM,0BAA0B,CAAC;AAIhE,MAAM,OAAO,SAAS;IAEX,MAAM,CAAC,MAAM,CAAI,IAAY,EAAE,MAAe;QACjD,OAAO,sBAAsB,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAA2B,CAAA;IAC7E,CAAC;IAEM,MAAM,CAAC,oBAAoB;QAC9B,OAAO,sBAAsB,CAAC,QAAQ,EAAG,CAAA;IAC7C,CAAC;IAEM,MAAM,CAAC,MAAM,CAAC,OAAiC;QAClD,MAAM,MAAM,GAA4B,EAAE,CAAC;QAC3C,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAClC,OAAO,MAAM,CAAC;IAClB,CAAC;IAEO,MAAM,CAAC,WAAW,CAAC,GAAY,EAAE,MAA+B;QACpE,IAAI,GAAG,YAAY,WAAW,EAAE,CAAC;YAC7B,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG;gBACf,IAAI,EAAE,GAAG,CAAC,WAAW,CAAC,IAAI;gBAC1B,IAAI,EAAE,GAAG,CAAC,IAAI;aACjB,CAAC;QACN,CAAC;aAAM,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YACxC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;gBACrC,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YACpC,CAAC;QACL,CAAC;IACL,CAAC;CACJ"}
@@ -0,0 +1,4 @@
1
+ import { type IAsyncStorage } from "@grest-ts/common";
2
+ export declare let METRICS_DEFINE_CONTEXT: IAsyncStorage<string>;
3
+ export declare function _initMetricsStorage(storage: IAsyncStorage<string>): void;
4
+ //# sourceMappingURL=GGMetricsDefineStorage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GGMetricsDefineStorage.d.ts","sourceRoot":"","sources":["../../src/GGMetricsDefineStorage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAGzE,eAAO,IAAI,sBAAsB,EAAE,aAAa,CAAC,MAAM,CAA6B,CAAC;AAErF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,IAAI,CAExE"}
@@ -0,0 +1,7 @@
1
+ import { BrowserAsyncStorage } from "@grest-ts/common";
2
+ // Browser-safe by default. Node.js entry replaces with real AsyncLocalStorage.
3
+ export let METRICS_DEFINE_CONTEXT = new BrowserAsyncStorage();
4
+ export function _initMetricsStorage(storage) {
5
+ METRICS_DEFINE_CONTEXT = storage;
6
+ }
7
+ //# sourceMappingURL=GGMetricsDefineStorage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GGMetricsDefineStorage.js","sourceRoot":"","sources":["../../src/GGMetricsDefineStorage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,mBAAmB,EAAqB,MAAM,kBAAkB,CAAC;AAEzE,+EAA+E;AAC/E,MAAM,CAAC,IAAI,sBAAsB,GAA0B,IAAI,mBAAmB,EAAE,CAAC;AAErF,MAAM,UAAU,mBAAmB,CAAC,OAA8B;IAC9D,sBAAsB,GAAG,OAAO,CAAC;AACrC,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { GGMetricsStore } from "./GGMetricsStore";
2
+ import { GGLocatorKey } from "@grest-ts/locator";
3
+ export declare const GG_METRICS: GGLocatorKey<GGMetricsStore>;
4
+ export declare class GGMetricsLoader {
5
+ private readonly store;
6
+ constructor(store?: GGMetricsStore);
7
+ }
8
+ //# sourceMappingURL=GGMetricsLoader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GGMetricsLoader.d.ts","sourceRoot":"","sources":["../../src/GGMetricsLoader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAY,YAAY,EAAuB,MAAM,mBAAmB,CAAC;AAEhF,eAAO,MAAM,UAAU,8BAAgD,CAAC;AAExE,qBAAa,eAAe;IAExB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiB;gBAE3B,KAAK,CAAC,EAAE,cAAc;CAWrC"}
@@ -0,0 +1,17 @@
1
+ import { GGMetricsStore } from "./GGMetricsStore.js";
2
+ import { GGLocator, GGLocatorKey, GGLocatorServiceType } from "@grest-ts/locator";
3
+ export const GG_METRICS = new GGLocatorKey("GGMetrics");
4
+ export class GGMetricsLoader {
5
+ store;
6
+ constructor(store) {
7
+ this.store = store ?? new GGMetricsStore();
8
+ GGLocator.getScope().setWithLifecycle(GG_METRICS, this.store, {
9
+ type: GGLocatorServiceType.CONFIG + 1,
10
+ start: async () => {
11
+ },
12
+ teardown: async () => {
13
+ }
14
+ });
15
+ }
16
+ }
17
+ //# sourceMappingURL=GGMetricsLoader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GGMetricsLoader.js","sourceRoot":"","sources":["../../src/GGMetricsLoader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAC,SAAS,EAAE,YAAY,EAAE,oBAAoB,EAAC,MAAM,mBAAmB,CAAC;AAEhF,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,YAAY,CAAiB,WAAW,CAAC,CAAC;AAExE,MAAM,OAAO,eAAe;IAEP,KAAK,CAAiB;IAEvC,YAAY,KAAsB;QAC9B,IAAI,CAAC,KAAK,GAAG,KAAK,IAAI,IAAI,cAAc,EAAE,CAAC;QAE3C,SAAS,CAAC,QAAQ,EAAE,CAAC,gBAAgB,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,EAAE;YAC1D,IAAI,EAAE,oBAAoB,CAAC,MAAM,GAAG,CAAC;YACrC,KAAK,EAAE,KAAK,IAAI,EAAE;YAClB,CAAC;YACD,QAAQ,EAAE,KAAK,IAAI,EAAE;YACrB,CAAC;SACJ,CAAC,CAAA;IACN,CAAC;CACJ"}
@@ -0,0 +1,9 @@
1
+ import { GGMetric, GGMetricLabels } from "./GGMetric.js";
2
+ import { GGMetricKey } from "./GGMetricKey.js";
3
+ export declare class GGMetricsStore {
4
+ private readonly metrics;
5
+ get<TLabel extends GGMetricLabels>(key: GGMetricKey<TLabel>): GGMetric<TLabel>;
6
+ getAllMetrics(): IterableIterator<GGMetric<any>>;
7
+ reset(): void;
8
+ }
9
+ //# sourceMappingURL=GGMetricsStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GGMetricsStore.d.ts","sourceRoot":"","sources":["../../src/GGMetricsStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAE,cAAc,EAAC,MAAM,eAAe,CAAC;AACvD,OAAO,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAE7C,qBAAa,cAAc;IAEvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoC;IAErD,GAAG,CAAC,MAAM,SAAS,cAAc,EAAE,GAAG,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC;IAS9E,aAAa,IAAI,gBAAgB,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAIhD,KAAK,IAAI,IAAI;CAKvB"}
@@ -0,0 +1,20 @@
1
+ export class GGMetricsStore {
2
+ metrics = new Map();
3
+ get(key) {
4
+ let metric = this.metrics.get(key.name);
5
+ if (!metric) {
6
+ metric = key.create();
7
+ this.metrics.set(key.name, metric);
8
+ }
9
+ return metric;
10
+ }
11
+ getAllMetrics() {
12
+ return this.metrics.values();
13
+ }
14
+ reset() {
15
+ for (const metric of this.metrics.values()) {
16
+ metric.reset();
17
+ }
18
+ }
19
+ }
20
+ //# sourceMappingURL=GGMetricsStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GGMetricsStore.js","sourceRoot":"","sources":["../../src/GGMetricsStore.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,cAAc;IAEN,OAAO,GAAG,IAAI,GAAG,EAAyB,CAAC;IAErD,GAAG,CAAgC,GAAwB;QAC9D,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC;YACtB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACvC,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;IAEM,aAAa;QAChB,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;IACjC,CAAC;IAEM,KAAK;QACR,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YACzC,MAAM,CAAC,KAAK,EAAE,CAAC;QACnB,CAAC;IACL,CAAC;CACJ"}
@@ -0,0 +1,41 @@
1
+ import { GGMetric } from "../GGMetric.js";
2
+ import { GGMetricsExporter, ExporterConfig } from "./GGMetricsExporter.js";
3
+ export type JsonMetricConverter = (metric: GGMetric<any>, exporter: GGJsonMetricsExporter) => JsonMetric;
4
+ export declare class GGJsonMetricsExporter extends GGMetricsExporter<JsonMetricsOutput> {
5
+ private static converters;
6
+ /**
7
+ * Register a converter for a custom metric type.
8
+ */
9
+ static registerConverter(metricClass: Function, converter: JsonMetricConverter): void;
10
+ constructor(config?: ExporterConfig);
11
+ getMetrics(): JsonMetricsOutput;
12
+ private convertMetric;
13
+ /**
14
+ * Parse a label key string into a labels object.
15
+ * Exposed for use by converters.
16
+ */
17
+ parseLabels(labelKey: string): Record<string, string>;
18
+ }
19
+ export interface JsonMetricValue {
20
+ labels: Record<string, string>;
21
+ value: number | JsonHistogramValue;
22
+ }
23
+ export interface JsonHistogramValue {
24
+ count: number;
25
+ sum: number;
26
+ avg: number;
27
+ min: number;
28
+ max: number;
29
+ buckets: Record<string, number>;
30
+ }
31
+ export interface JsonMetric {
32
+ name: string;
33
+ type: string;
34
+ help: string;
35
+ values: JsonMetricValue[];
36
+ }
37
+ export interface JsonMetricsOutput {
38
+ timestamp: number;
39
+ metrics: Record<string, JsonMetric>;
40
+ }
41
+ //# sourceMappingURL=GGJsonMetricsExporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GGJsonMetricsExporter.d.ts","sourceRoot":"","sources":["../../../src/exporters/GGJsonMetricsExporter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,gBAAgB,CAAC;AAKxC,OAAO,EAAC,iBAAiB,EAAE,cAAc,EAAC,MAAM,wBAAwB,CAAC;AAEzE,MAAM,MAAM,mBAAmB,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,qBAAqB,KAAK,UAAU,CAAC;AAEzG,qBAAa,qBAAsB,SAAQ,iBAAiB,CAAC,iBAAiB,CAAC;IAG3E,OAAO,CAAC,MAAM,CAAC,UAAU,CAA4C;IASrE;;OAEG;IACH,MAAM,CAAC,iBAAiB,CAAC,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,mBAAmB,GAAG,IAAI;gBAIzE,MAAM,GAAE,cAAmB;IAIvC,UAAU,IAAI,iBAAiB;IAa/B,OAAO,CAAC,aAAa;IAQrB;;;OAGG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;CAYxD;AAkFD,MAAM,WAAW,eAAe;IAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,KAAK,EAAE,MAAM,GAAG,kBAAkB,CAAC;CACtC;AAED,MAAM,WAAW,kBAAkB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CACvC"}
@@ -0,0 +1,129 @@
1
+ import { GGCounter } from "../metric/GGCounter.js";
2
+ import { GGGauge } from "../metric/GGGauge.js";
3
+ import { GGLazyGauge } from "../metric/GGLazyGauge.js";
4
+ import { GGHistogram } from "../metric/GGHistogram.js";
5
+ import { GGMetricsExporter } from "./GGMetricsExporter.js";
6
+ export class GGJsonMetricsExporter extends GGMetricsExporter {
7
+ // Static map for extensibility - register converters for new metric types
8
+ static converters = new Map();
9
+ static {
10
+ GGJsonMetricsExporter.registerConverter(GGCounter, convertCounter);
11
+ GGJsonMetricsExporter.registerConverter(GGGauge, convertGauge);
12
+ GGJsonMetricsExporter.registerConverter(GGLazyGauge, convertLazyGauge);
13
+ GGJsonMetricsExporter.registerConverter(GGHistogram, convertHistogram);
14
+ }
15
+ /**
16
+ * Register a converter for a custom metric type.
17
+ */
18
+ static registerConverter(metricClass, converter) {
19
+ GGJsonMetricsExporter.converters.set(metricClass, converter);
20
+ }
21
+ constructor(config = {}) {
22
+ super(config);
23
+ }
24
+ getMetrics() {
25
+ const output = {
26
+ timestamp: Date.now(),
27
+ metrics: {}
28
+ };
29
+ for (const metric of this.getFilteredMetrics()) {
30
+ output.metrics[metric.name] = this.convertMetric(metric);
31
+ }
32
+ return output;
33
+ }
34
+ convertMetric(metric) {
35
+ const converter = GGJsonMetricsExporter.converters.get(metric.constructor);
36
+ if (!converter) {
37
+ throw new Error(`No converter registered for metric type: ${metric.constructor.name}`);
38
+ }
39
+ return converter(metric, this);
40
+ }
41
+ /**
42
+ * Parse a label key string into a labels object.
43
+ * Exposed for use by converters.
44
+ */
45
+ parseLabels(labelKey) {
46
+ if (!labelKey)
47
+ return {};
48
+ const labels = {};
49
+ const parts = labelKey.split(',');
50
+ for (const part of parts) {
51
+ const [key, val] = part.split('=');
52
+ if (key && val !== undefined) {
53
+ labels[key] = val;
54
+ }
55
+ }
56
+ return labels;
57
+ }
58
+ }
59
+ // Built-in converters
60
+ function convertCounter(metric, exporter) {
61
+ const values = [];
62
+ for (const [labelKey, value] of metric.getValues()) {
63
+ values.push({
64
+ labels: exporter.parseLabels(labelKey),
65
+ value
66
+ });
67
+ }
68
+ return {
69
+ name: metric.name,
70
+ type: 'counter',
71
+ help: metric.key.help,
72
+ values
73
+ };
74
+ }
75
+ function convertGauge(metric, exporter) {
76
+ const values = [];
77
+ for (const [labelKey, value] of metric.getValues()) {
78
+ values.push({
79
+ labels: exporter.parseLabels(labelKey),
80
+ value
81
+ });
82
+ }
83
+ return {
84
+ name: metric.name,
85
+ type: 'gauge',
86
+ help: metric.key.help,
87
+ values
88
+ };
89
+ }
90
+ function convertLazyGauge(metric, exporter) {
91
+ // Lazy gauge computes value on read - no labels
92
+ return {
93
+ name: metric.name,
94
+ type: 'gauge',
95
+ help: metric.key.help,
96
+ values: [{
97
+ labels: {},
98
+ value: metric.getValue()
99
+ }]
100
+ };
101
+ }
102
+ function convertHistogram(metric, exporter) {
103
+ const values = [];
104
+ const buckets = metric.getBuckets();
105
+ for (const [labelKey, data] of metric.getValues()) {
106
+ const bucketObj = {};
107
+ for (let i = 0; i < buckets.length; i++) {
108
+ bucketObj[String(buckets[i])] = data.values[i] ?? 0;
109
+ }
110
+ values.push({
111
+ labels: exporter.parseLabels(labelKey),
112
+ value: {
113
+ count: data.count,
114
+ sum: data.sum,
115
+ avg: data.count > 0 ? data.sum / data.count : 0,
116
+ min: data.min === Infinity ? 0 : data.min,
117
+ max: data.max === -Infinity ? 0 : data.max,
118
+ buckets: bucketObj
119
+ }
120
+ });
121
+ }
122
+ return {
123
+ name: metric.name,
124
+ type: 'histogram',
125
+ help: metric.key.help,
126
+ values
127
+ };
128
+ }
129
+ //# sourceMappingURL=GGJsonMetricsExporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GGJsonMetricsExporter.js","sourceRoot":"","sources":["../../../src/exporters/GGJsonMetricsExporter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import { GGMetricsStore } from "../GGMetricsStore.js";
2
+ import { GGMetric } from "../GGMetric.js";
3
+ export interface ExporterConfig {
4
+ store?: GGMetricsStore;
5
+ include?: unknown[];
6
+ exclude?: unknown[];
7
+ }
8
+ /**
9
+ * Abstract base class for metrics exporters.
10
+ * Handles config parsing, metric filtering, and key discovery.
11
+ */
12
+ export declare abstract class GGMetricsExporter<TOutput> {
13
+ protected readonly store: GGMetricsStore;
14
+ private readonly includeKeys?;
15
+ private readonly excludeKeys?;
16
+ constructor(config?: ExporterConfig);
17
+ /**
18
+ * Discover all GGMetricKey instances from an array of objects.
19
+ * Objects can be individual keys, or nested structures containing keys.
20
+ */
21
+ private discoverKeys;
22
+ private discoverKeysRecursive;
23
+ /**
24
+ * Check if a metric should be included in the export.
25
+ * Exclude takes precedence over include.
26
+ */
27
+ protected shouldIncludeMetric(metric: GGMetric<any>): boolean;
28
+ /**
29
+ * Get all metrics that pass the include/exclude filters.
30
+ */
31
+ protected getFilteredMetrics(): Iterable<GGMetric<any>>;
32
+ /**
33
+ * Export metrics to the output format.
34
+ */
35
+ abstract getMetrics(): TOutput;
36
+ /**
37
+ * Export metrics as a JSON string.
38
+ */
39
+ getMetricsString(): string;
40
+ }
41
+ //# sourceMappingURL=GGMetricsExporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GGMetricsExporter.d.ts","sourceRoot":"","sources":["../../../src/exporters/GGMetricsExporter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,EAAC,MAAM,sBAAsB,CAAC;AAEpD,OAAO,EAAC,QAAQ,EAAC,MAAM,gBAAgB,CAAC;AAGxC,MAAM,WAAW,cAAc;IAC3B,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;CACvB;AAED;;;GAGG;AACH,8BAAsB,iBAAiB,CAAC,OAAO;IAC3C,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IACzC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAwB;IACrD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAwB;gBAEzC,MAAM,GAAE,cAAmB;IAMvC;;;OAGG;IACH,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,qBAAqB;IAU7B;;;OAGG;IACH,SAAS,CAAC,mBAAmB,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,OAAO;IAa7D;;OAEG;IACH,SAAS,CAAE,kBAAkB,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAQxD;;OAEG;IACH,QAAQ,CAAC,UAAU,IAAI,OAAO;IAE9B;;OAEG;IACH,gBAAgB,IAAI,MAAM;CAG7B"}