@zuplo/cli 6.72.10 → 6.72.11
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.
- package/node_modules/@posthog/core/dist/index.d.ts +2 -2
- package/node_modules/@posthog/core/dist/index.d.ts.map +1 -1
- package/node_modules/@posthog/core/dist/index.js +9 -0
- package/node_modules/@posthog/core/dist/index.mjs +2 -2
- package/node_modules/@posthog/core/dist/metrics/config.d.ts +9 -0
- package/node_modules/@posthog/core/dist/metrics/config.d.ts.map +1 -0
- package/node_modules/@posthog/core/dist/metrics/config.js +49 -0
- package/node_modules/@posthog/core/dist/metrics/config.mjs +15 -0
- package/node_modules/@posthog/core/dist/metrics/index.d.ts +8 -1
- package/node_modules/@posthog/core/dist/metrics/index.d.ts.map +1 -1
- package/node_modules/@posthog/core/dist/metrics/index.js +39 -19
- package/node_modules/@posthog/core/dist/metrics/index.mjs +36 -19
- package/node_modules/@posthog/core/dist/metrics/types.d.ts +1 -1
- package/node_modules/@posthog/core/dist/metrics/types.d.ts.map +1 -1
- package/node_modules/@posthog/core/dist/posthog-core-stateless.d.ts +9 -1
- package/node_modules/@posthog/core/dist/posthog-core-stateless.d.ts.map +1 -1
- package/node_modules/@posthog/core/dist/posthog-core-stateless.js +44 -1
- package/node_modules/@posthog/core/dist/posthog-core-stateless.mjs +44 -1
- package/node_modules/@posthog/core/package.json +2 -2
- package/node_modules/@posthog/core/src/index.ts +3 -0
- package/node_modules/@posthog/core/src/metrics/config.ts +23 -0
- package/node_modules/@posthog/core/src/metrics/index.spec.ts +49 -0
- package/node_modules/@posthog/core/src/metrics/index.ts +66 -24
- package/node_modules/@posthog/core/src/metrics/types.ts +1 -0
- package/node_modules/@posthog/core/src/posthog-core-stateless.ts +52 -2
- package/node_modules/@zuplo/core/package.json +1 -1
- package/node_modules/@zuplo/graphql/package.json +1 -1
- package/node_modules/@zuplo/openapi-tools/package.json +1 -1
- package/node_modules/@zuplo/otel/package.json +1 -1
- package/node_modules/@zuplo/runtime/package.json +1 -1
- package/package.json +6 -6
|
@@ -7,9 +7,9 @@ export { PostHogLogs } from './logs';
|
|
|
7
7
|
export type { BeforeSendLogFn, BufferedLogEntry, CaptureLogger, LogSdkContext, PostHogLogsConfig, ResolvedPostHogLogsConfig, } from './logs/types';
|
|
8
8
|
export type { CaptureLogOptions, LogAttributeValue, LogAttributes, LogSeverityLevel } from './logs/types';
|
|
9
9
|
export type { ExceptionRateLimiterConfig } from '@posthog/types';
|
|
10
|
-
export { PostHogMetrics, buildOtlpMetricsPayload, buildMetricsResourceAttributes, DEFAULT_HISTOGRAM_BOUNDS, } from './metrics';
|
|
10
|
+
export { PostHogMetrics, buildOtlpMetricsPayload, buildMetricsResourceAttributes, DEFAULT_HISTOGRAM_BOUNDS, resolveMetricsConfig, } from './metrics';
|
|
11
11
|
export type { MetricsHost, PostHogMetricsConfig, ResolvedPostHogMetricsConfig, SendMetricsBatchOutcome, } from './metrics';
|
|
12
|
-
export type { CaptureMetricOptions, MetricAttributes, MetricAttributeValue, MetricSample, MetricType, } from './metrics/types';
|
|
12
|
+
export type { CaptureMetricOptions, MetricAttributes, MetricAttributeValue, MetricSample, MetricType, Metrics, MetricsConfig, } from './metrics/types';
|
|
13
13
|
export { uuidv7 } from './vendor/uuidv7';
|
|
14
14
|
export * from './cookie';
|
|
15
15
|
export * from './posthog-core';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,YAAY,EACZ,oBAAoB,GACrB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,YAAY,EACZ,UAAU,EACV,aAAa,EACb,eAAe,EACf,sBAAsB,EACtB,0BAA0B,GAC3B,MAAM,QAAQ,CAAA;AACf,cAAc,SAAS,CAAA;AACvB,OAAO,KAAK,aAAa,MAAM,kBAAkB,CAAA;AACjD,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,uBAAuB,EACvB,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,EACd,kBAAkB,GACnB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AACpC,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,yBAAyB,GAC1B,MAAM,cAAc,CAAA;AAIrB,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAGzG,YAAY,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAA;AAChE,OAAO,EACL,cAAc,EACd,uBAAuB,EACvB,8BAA8B,EAC9B,wBAAwB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,YAAY,EACZ,oBAAoB,GACrB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,YAAY,EACZ,UAAU,EACV,aAAa,EACb,eAAe,EACf,sBAAsB,EACtB,0BAA0B,GAC3B,MAAM,QAAQ,CAAA;AACf,cAAc,SAAS,CAAA;AACvB,OAAO,KAAK,aAAa,MAAM,kBAAkB,CAAA;AACjD,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,uBAAuB,EACvB,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,EACd,kBAAkB,GACnB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AACpC,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,yBAAyB,GAC1B,MAAM,cAAc,CAAA;AAIrB,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAGzG,YAAY,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAA;AAChE,OAAO,EACL,cAAc,EACd,uBAAuB,EACvB,8BAA8B,EAC9B,wBAAwB,EACxB,oBAAoB,GACrB,MAAM,WAAW,CAAA;AAClB,YAAY,EACV,WAAW,EACX,oBAAoB,EACpB,4BAA4B,EAC5B,uBAAuB,GACxB,MAAM,WAAW,CAAA;AAElB,YAAY,EACV,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,YAAY,EACZ,UAAU,EACV,OAAO,EACP,aAAa,GACd,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AACxC,cAAc,UAAU,CAAA;AACxB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,0BAA0B,CAAA;AACxC,cAAc,mBAAmB,CAAA;AACjC,cAAc,SAAS,CAAA;AACvB,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA"}
|
|
@@ -112,6 +112,7 @@ var __webpack_exports__ = {};
|
|
|
112
112
|
isNativeAsyncGzipError: ()=>_gzip__WEBPACK_IMPORTED_MODULE_1__.isNativeAsyncGzipError,
|
|
113
113
|
isNativeAsyncGzipReadError: ()=>_gzip__WEBPACK_IMPORTED_MODULE_1__.isNativeAsyncGzipReadError,
|
|
114
114
|
parsePayload: ()=>_featureFlagUtils__WEBPACK_IMPORTED_MODULE_0__.parsePayload,
|
|
115
|
+
resolveMetricsConfig: ()=>_metrics__WEBPACK_IMPORTED_MODULE_6__.resolveMetricsConfig,
|
|
115
116
|
toOtlpAnyValue: ()=>_logs_logs_utils__WEBPACK_IMPORTED_MODULE_4__.toOtlpAnyValue,
|
|
116
117
|
toOtlpKeyValueList: ()=>_logs_logs_utils__WEBPACK_IMPORTED_MODULE_4__.toOtlpKeyValueList,
|
|
117
118
|
uuidv7: ()=>_vendor_uuidv7__WEBPACK_IMPORTED_MODULE_7__.uuidv7
|
|
@@ -143,6 +144,7 @@ var __webpack_exports__ = {};
|
|
|
143
144
|
"getFeatureFlagValue",
|
|
144
145
|
"getValidationError",
|
|
145
146
|
"default",
|
|
147
|
+
"resolveMetricsConfig",
|
|
146
148
|
"getRequirementsHint",
|
|
147
149
|
"isGzipData",
|
|
148
150
|
"getOtlpSeverityNumber",
|
|
@@ -184,6 +186,7 @@ var __webpack_exports__ = {};
|
|
|
184
186
|
"getFeatureFlagValue",
|
|
185
187
|
"getValidationError",
|
|
186
188
|
"default",
|
|
189
|
+
"resolveMetricsConfig",
|
|
187
190
|
"getRequirementsHint",
|
|
188
191
|
"isGzipData",
|
|
189
192
|
"getOtlpSeverityNumber",
|
|
@@ -220,6 +223,7 @@ var __webpack_exports__ = {};
|
|
|
220
223
|
"getFeatureFlagValue",
|
|
221
224
|
"getValidationError",
|
|
222
225
|
"default",
|
|
226
|
+
"resolveMetricsConfig",
|
|
223
227
|
"getRequirementsHint",
|
|
224
228
|
"isGzipData",
|
|
225
229
|
"getOtlpSeverityNumber",
|
|
@@ -256,6 +260,7 @@ var __webpack_exports__ = {};
|
|
|
256
260
|
"getFeatureFlagValue",
|
|
257
261
|
"getValidationError",
|
|
258
262
|
"default",
|
|
263
|
+
"resolveMetricsConfig",
|
|
259
264
|
"getRequirementsHint",
|
|
260
265
|
"isGzipData",
|
|
261
266
|
"getOtlpSeverityNumber",
|
|
@@ -292,6 +297,7 @@ var __webpack_exports__ = {};
|
|
|
292
297
|
"getFeatureFlagValue",
|
|
293
298
|
"getValidationError",
|
|
294
299
|
"default",
|
|
300
|
+
"resolveMetricsConfig",
|
|
295
301
|
"getRequirementsHint",
|
|
296
302
|
"isGzipData",
|
|
297
303
|
"getOtlpSeverityNumber",
|
|
@@ -328,6 +334,7 @@ var __webpack_exports__ = {};
|
|
|
328
334
|
"getFeatureFlagValue",
|
|
329
335
|
"getValidationError",
|
|
330
336
|
"default",
|
|
337
|
+
"resolveMetricsConfig",
|
|
331
338
|
"getRequirementsHint",
|
|
332
339
|
"isGzipData",
|
|
333
340
|
"getOtlpSeverityNumber",
|
|
@@ -366,6 +373,7 @@ exports.isGzipSupported = __webpack_exports__.isGzipSupported;
|
|
|
366
373
|
exports.isNativeAsyncGzipError = __webpack_exports__.isNativeAsyncGzipError;
|
|
367
374
|
exports.isNativeAsyncGzipReadError = __webpack_exports__.isNativeAsyncGzipReadError;
|
|
368
375
|
exports.parsePayload = __webpack_exports__.parsePayload;
|
|
376
|
+
exports.resolveMetricsConfig = __webpack_exports__.resolveMetricsConfig;
|
|
369
377
|
exports.toOtlpAnyValue = __webpack_exports__.toOtlpAnyValue;
|
|
370
378
|
exports.toOtlpKeyValueList = __webpack_exports__.toOtlpKeyValueList;
|
|
371
379
|
exports.uuidv7 = __webpack_exports__.uuidv7;
|
|
@@ -395,6 +403,7 @@ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
|
395
403
|
"isNativeAsyncGzipError",
|
|
396
404
|
"isNativeAsyncGzipReadError",
|
|
397
405
|
"parsePayload",
|
|
406
|
+
"resolveMetricsConfig",
|
|
398
407
|
"toOtlpAnyValue",
|
|
399
408
|
"toOtlpKeyValueList",
|
|
400
409
|
"uuidv7"
|
|
@@ -2,7 +2,7 @@ import { flagDetailsToResults, getEnabledFromValue, getFeatureFlagValue, getVari
|
|
|
2
2
|
import { gzipCompress, isGzipData, isGzipRequest, isGzipSupported, isNativeAsyncGzipError, isNativeAsyncGzipReadError } from "./gzip.mjs";
|
|
3
3
|
import { buildOtlpLogRecord, buildOtlpLogsPayload, buildResourceAttributes, getOtlpSeverityNumber, getOtlpSeverityText, toOtlpAnyValue, toOtlpKeyValueList } from "./logs/logs-utils.mjs";
|
|
4
4
|
import { PostHogLogs } from "./logs/index.mjs";
|
|
5
|
-
import { DEFAULT_HISTOGRAM_BOUNDS, PostHogMetrics, buildMetricsResourceAttributes, buildOtlpMetricsPayload } from "./metrics/index.mjs";
|
|
5
|
+
import { DEFAULT_HISTOGRAM_BOUNDS, PostHogMetrics, buildMetricsResourceAttributes, buildOtlpMetricsPayload, resolveMetricsConfig } from "./metrics/index.mjs";
|
|
6
6
|
import { uuidv7 } from "./vendor/uuidv7.mjs";
|
|
7
7
|
import { getLengthFromRules, getRequirementsHint, getValidationError } from "./surveys/validation.mjs";
|
|
8
8
|
export * from "./utils/index.mjs";
|
|
@@ -12,4 +12,4 @@ export * from "./posthog-core-stateless.mjs";
|
|
|
12
12
|
export * from "./tracing-headers.mjs";
|
|
13
13
|
export * from "./types.mjs";
|
|
14
14
|
import * as __WEBPACK_EXTERNAL_MODULE__error_tracking_index_mjs_b3406d6f__ from "./error-tracking/index.mjs";
|
|
15
|
-
export { DEFAULT_HISTOGRAM_BOUNDS, __WEBPACK_EXTERNAL_MODULE__error_tracking_index_mjs_b3406d6f__ as ErrorTracking, PostHogLogs, PostHogMetrics, buildMetricsResourceAttributes, buildOtlpLogRecord, buildOtlpLogsPayload, buildOtlpMetricsPayload, buildResourceAttributes, flagDetailsToResults, getEnabledFromValue, getFeatureFlagValue, getLengthFromRules, getOtlpSeverityNumber, getOtlpSeverityText, getRequirementsHint, getValidationError, getVariantFromValue, gzipCompress, isGzipData, isGzipRequest, isGzipSupported, isNativeAsyncGzipError, isNativeAsyncGzipReadError, parsePayload, toOtlpAnyValue, toOtlpKeyValueList, uuidv7 };
|
|
15
|
+
export { DEFAULT_HISTOGRAM_BOUNDS, __WEBPACK_EXTERNAL_MODULE__error_tracking_index_mjs_b3406d6f__ as ErrorTracking, PostHogLogs, PostHogMetrics, buildMetricsResourceAttributes, buildOtlpLogRecord, buildOtlpLogsPayload, buildOtlpMetricsPayload, buildResourceAttributes, flagDetailsToResults, getEnabledFromValue, getFeatureFlagValue, getLengthFromRules, getOtlpSeverityNumber, getOtlpSeverityText, getRequirementsHint, getValidationError, getVariantFromValue, gzipCompress, isGzipData, isGzipRequest, isGzipSupported, isNativeAsyncGzipError, isNativeAsyncGzipReadError, parsePayload, resolveMetricsConfig, toOtlpAnyValue, toOtlpKeyValueList, uuidv7 };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { MetricsConfig } from '@posthog/types';
|
|
2
|
+
import type { ResolvedPostHogMetricsConfig } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Resolves the public `metrics` config into the shape `PostHogMetrics`
|
|
5
|
+
* consumes. Same precedence rule as logs: OTLP keys in `resourceAttributes`
|
|
6
|
+
* win over the named config fields.
|
|
7
|
+
*/
|
|
8
|
+
export declare function resolveMetricsConfig(config: MetricsConfig | undefined): ResolvedPostHogMetricsConfig;
|
|
9
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/metrics/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,SAAS,CAAA;AAK3D;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,GAAG,4BAA4B,CAWpG"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
5
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: definition[key]
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
})();
|
|
11
|
+
(()=>{
|
|
12
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
13
|
+
})();
|
|
14
|
+
(()=>{
|
|
15
|
+
__webpack_require__.r = (exports1)=>{
|
|
16
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
|
+
value: 'Module'
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
20
|
+
value: true
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
var __webpack_exports__ = {};
|
|
25
|
+
__webpack_require__.r(__webpack_exports__);
|
|
26
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
resolveMetricsConfig: ()=>resolveMetricsConfig
|
|
28
|
+
});
|
|
29
|
+
const DEFAULT_FLUSH_INTERVAL_MS = 10000;
|
|
30
|
+
const DEFAULT_MAX_SERIES_PER_FLUSH = 1000;
|
|
31
|
+
function resolveMetricsConfig(config) {
|
|
32
|
+
const resourceAttributes = config?.resourceAttributes;
|
|
33
|
+
return {
|
|
34
|
+
serviceName: resourceAttributes?.['service.name'] ?? config?.serviceName,
|
|
35
|
+
serviceVersion: resourceAttributes?.['service.version'] ?? config?.serviceVersion,
|
|
36
|
+
environment: resourceAttributes?.['deployment.environment'] ?? config?.environment,
|
|
37
|
+
resourceAttributes,
|
|
38
|
+
beforeSend: config?.beforeSend,
|
|
39
|
+
flushIntervalMs: config?.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS,
|
|
40
|
+
maxSeriesPerFlush: config?.maxSeriesPerFlush ?? DEFAULT_MAX_SERIES_PER_FLUSH
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
exports.resolveMetricsConfig = __webpack_exports__.resolveMetricsConfig;
|
|
44
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
45
|
+
"resolveMetricsConfig"
|
|
46
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
47
|
+
Object.defineProperty(exports, '__esModule', {
|
|
48
|
+
value: true
|
|
49
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const DEFAULT_FLUSH_INTERVAL_MS = 10000;
|
|
2
|
+
const DEFAULT_MAX_SERIES_PER_FLUSH = 1000;
|
|
3
|
+
function resolveMetricsConfig(config) {
|
|
4
|
+
const resourceAttributes = config?.resourceAttributes;
|
|
5
|
+
return {
|
|
6
|
+
serviceName: resourceAttributes?.['service.name'] ?? config?.serviceName,
|
|
7
|
+
serviceVersion: resourceAttributes?.['service.version'] ?? config?.serviceVersion,
|
|
8
|
+
environment: resourceAttributes?.['deployment.environment'] ?? config?.environment,
|
|
9
|
+
resourceAttributes,
|
|
10
|
+
beforeSend: config?.beforeSend,
|
|
11
|
+
flushIntervalMs: config?.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS,
|
|
12
|
+
maxSeriesPerFlush: config?.maxSeriesPerFlush ?? DEFAULT_MAX_SERIES_PER_FLUSH
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export { resolveMetricsConfig };
|
|
@@ -25,6 +25,7 @@ export declare class PostHogMetrics {
|
|
|
25
25
|
private _seriesCapWarned;
|
|
26
26
|
private _typeByName;
|
|
27
27
|
private _typeCollisionWarned;
|
|
28
|
+
private _generation;
|
|
28
29
|
constructor(_instance: MetricsHost, _config: ResolvedPostHogMetricsConfig, _logger: Logger);
|
|
29
30
|
count(name: string, value?: number, options?: CaptureMetricOptions): void;
|
|
30
31
|
gauge(name: string, value: number, options?: CaptureMetricOptions): void;
|
|
@@ -39,9 +40,14 @@ export declare class PostHogMetrics {
|
|
|
39
40
|
* send. The caller owns delivery; there is no retry for a drained window.
|
|
40
41
|
*/
|
|
41
42
|
drainWindow(): OtlpMetricsPayload | null;
|
|
42
|
-
/** Clears the flush timer
|
|
43
|
+
/** Clears the flush timer, drops the current window, and invalidates in-flight flushes. */
|
|
43
44
|
reset(): void;
|
|
44
45
|
private _capture;
|
|
46
|
+
/**
|
|
47
|
+
* Cardinality gate for adding a series to the live window — warns once per
|
|
48
|
+
* window when the cap is hit. Applied on capture and on merge-back alike.
|
|
49
|
+
*/
|
|
50
|
+
private _admitNewSeries;
|
|
45
51
|
private _fold;
|
|
46
52
|
private _runBeforeSend;
|
|
47
53
|
private _armFlushTimer;
|
|
@@ -57,5 +63,6 @@ export declare class PostHogMetrics {
|
|
|
57
63
|
private _mergeWindowBack;
|
|
58
64
|
}
|
|
59
65
|
export { buildOtlpMetricsPayload, buildMetricsResourceAttributes, DEFAULT_HISTOGRAM_BOUNDS } from './metrics-utils';
|
|
66
|
+
export { resolveMetricsConfig } from './config';
|
|
60
67
|
export type { MetricsHost, PostHogMetricsConfig, ResolvedPostHogMetricsConfig, SendMetricsBatchOutcome } from './types';
|
|
61
68
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/metrics/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EAMpB,kBAAkB,EAEnB,MAAM,gBAAgB,CAAA;AACvB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAWtC,OAAO,KAAK,EAAE,WAAW,EAAE,4BAA4B,EAAE,MAAM,SAAS,CAAA;AA2BxE;;;;;;;;;;;;;GAaG;AACH,qBAAa,cAAc;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/metrics/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EAMpB,kBAAkB,EAEnB,MAAM,gBAAgB,CAAA;AACvB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAWtC,OAAO,KAAK,EAAE,WAAW,EAAE,4BAA4B,EAAE,MAAM,SAAS,CAAA;AA2BxE;;;;;;;;;;;;;GAaG;AACH,qBAAa,cAAc;IAmBvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IApB1B,OAAO,CAAC,OAAO,CAAiC;IAChD,OAAO,CAAC,WAAW,CAAC,CAAmC;IAGvD,OAAO,CAAC,aAAa,CAA6B;IAElD,OAAO,CAAC,gBAAgB,CAAQ;IAIhC,OAAO,CAAC,WAAW,CAAgC;IACnD,OAAO,CAAC,oBAAoB,CAAoB;IAIhD,OAAO,CAAC,WAAW,CAAI;gBAGJ,SAAS,EAAE,WAAW,EACtB,OAAO,EAAE,4BAA4B,EACrC,OAAO,EAAE,MAAM;IAGlC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,MAAU,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,IAAI;IAI5E,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,IAAI;IAIxE,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,IAAI;IAI5E,iFAAiF;IACjF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBtB;;;;;;OAMG;IACH,WAAW,IAAI,kBAAkB,GAAG,IAAI;IAYxC,2FAA2F;IAC3F,KAAK,IAAI,IAAI;IAUb,OAAO,CAAC,QAAQ;IAsEhB;;;OAGG;IACH,OAAO,CAAC,eAAe;IAcvB,OAAO,CAAC,KAAK;IA6Bb,OAAO,CAAC,cAAc;IAuBtB,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,gBAAgB;YAOV,QAAQ;IAuCtB,OAAO,CAAC,aAAa;IASrB;;;OAGG;IACH,OAAO,CAAC,aAAa;IAwDrB,oFAAoF;IACpF,OAAO,CAAC,gBAAgB;CAqCzB;AAED,OAAO,EAAE,uBAAuB,EAAE,8BAA8B,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAA;AACnH,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAC/C,YAAY,EAAE,WAAW,EAAE,oBAAoB,EAAE,4BAA4B,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAA"}
|
|
@@ -27,11 +27,13 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
27
27
|
buildMetricsResourceAttributes: ()=>external_metrics_utils_js_namespaceObject.buildMetricsResourceAttributes,
|
|
28
28
|
PostHogMetrics: ()=>PostHogMetrics,
|
|
29
29
|
buildOtlpMetricsPayload: ()=>external_metrics_utils_js_namespaceObject.buildOtlpMetricsPayload,
|
|
30
|
+
resolveMetricsConfig: ()=>external_config_js_namespaceObject.resolveMetricsConfig,
|
|
30
31
|
DEFAULT_HISTOGRAM_BOUNDS: ()=>external_metrics_utils_js_namespaceObject.DEFAULT_HISTOGRAM_BOUNDS
|
|
31
32
|
});
|
|
32
33
|
const index_js_namespaceObject = require("../utils/index.js");
|
|
33
34
|
const logs_utils_js_namespaceObject = require("../logs/logs-utils.js");
|
|
34
35
|
const external_metrics_utils_js_namespaceObject = require("./metrics-utils.js");
|
|
36
|
+
const external_config_js_namespaceObject = require("./config.js");
|
|
35
37
|
const OTLP_TEMPORALITY_DELTA = 1;
|
|
36
38
|
class PostHogMetrics {
|
|
37
39
|
constructor(_instance, _config, _logger){
|
|
@@ -43,6 +45,7 @@ class PostHogMetrics {
|
|
|
43
45
|
this._seriesCapWarned = false;
|
|
44
46
|
this._typeByName = new Map();
|
|
45
47
|
this._typeCollisionWarned = new Set();
|
|
48
|
+
this._generation = 0;
|
|
46
49
|
}
|
|
47
50
|
count(name, value = 1, options) {
|
|
48
51
|
this._capture({
|
|
@@ -93,6 +96,7 @@ class PostHogMetrics {
|
|
|
93
96
|
return this._buildPayload(window);
|
|
94
97
|
}
|
|
95
98
|
reset() {
|
|
99
|
+
this._generation++;
|
|
96
100
|
this._clearFlushTimer();
|
|
97
101
|
this._series = new Map();
|
|
98
102
|
this._flushPromise = null;
|
|
@@ -107,36 +111,46 @@ class PostHogMetrics {
|
|
|
107
111
|
if (!filtered.name || 'string' != typeof filtered.name) return void this._logger.warn('Dropping metric with empty name');
|
|
108
112
|
if ('number' != typeof filtered.value || !Number.isFinite(filtered.value)) return void this._logger.warn(`Dropping metric '${filtered.name}': value must be a finite number`);
|
|
109
113
|
if ('count' === filtered.type && filtered.value < 0) return void this._logger.warn(`Dropping count '${filtered.name}': counters are monotonic, value must be >= 0`);
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
114
|
+
let attributes;
|
|
115
|
+
let key;
|
|
116
|
+
try {
|
|
117
|
+
attributes = filtered.attributes ? {
|
|
118
|
+
...filtered.attributes
|
|
119
|
+
} : void 0;
|
|
120
|
+
key = (0, external_metrics_utils_js_namespaceObject.seriesKey)(filtered.type, filtered.name, filtered.unit, attributes);
|
|
121
|
+
} catch (e) {
|
|
122
|
+
this._logger.warn(`Dropping metric '${filtered.name}': attributes could not be serialized`, e);
|
|
123
|
+
return;
|
|
115
124
|
}
|
|
116
|
-
const key = (0, external_metrics_utils_js_namespaceObject.seriesKey)(filtered.type, filtered.name, filtered.unit, filtered.attributes);
|
|
117
125
|
let state = this._series.get(key);
|
|
118
126
|
if (!state) {
|
|
119
|
-
if (this.
|
|
120
|
-
if (!this._seriesCapWarned) {
|
|
121
|
-
this._seriesCapWarned = true;
|
|
122
|
-
this._logger.warn(`Metric series cap reached (${this._config.maxSeriesPerFlush} per flush window); dropping new series until the next flush. Reduce attribute cardinality.`);
|
|
123
|
-
}
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
127
|
+
if (!this._admitNewSeries()) return;
|
|
126
128
|
state = {
|
|
127
129
|
name: filtered.name,
|
|
128
130
|
type: filtered.type,
|
|
129
131
|
unit: filtered.unit,
|
|
130
|
-
attributes
|
|
131
|
-
...filtered.attributes
|
|
132
|
-
} : void 0,
|
|
132
|
+
attributes,
|
|
133
133
|
windowStartMs: Date.now()
|
|
134
134
|
};
|
|
135
135
|
this._series.set(key, state);
|
|
136
136
|
}
|
|
137
|
+
const seenType = this._typeByName.get(filtered.name);
|
|
138
|
+
if (void 0 === seenType) this._typeByName.set(filtered.name, filtered.type);
|
|
139
|
+
else if (seenType !== filtered.type && !this._typeCollisionWarned.has(filtered.name)) {
|
|
140
|
+
this._typeCollisionWarned.add(filtered.name);
|
|
141
|
+
this._logger.warn(`Metric name '${filtered.name}' is already used as a ${seenType}; recording it as a ${filtered.type} too will blend both series in charts. Use a distinct name.`);
|
|
142
|
+
}
|
|
137
143
|
this._fold(state, filtered.value);
|
|
138
144
|
this._armFlushTimer();
|
|
139
145
|
}
|
|
146
|
+
_admitNewSeries() {
|
|
147
|
+
if (this._series.size < this._config.maxSeriesPerFlush) return true;
|
|
148
|
+
if (!this._seriesCapWarned) {
|
|
149
|
+
this._seriesCapWarned = true;
|
|
150
|
+
this._logger.warn(`Metric series cap reached (${this._config.maxSeriesPerFlush} per flush window); dropping new series until the next flush. Reduce attribute cardinality.`);
|
|
151
|
+
}
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
140
154
|
_fold(state, value) {
|
|
141
155
|
switch(state.type){
|
|
142
156
|
case 'count':
|
|
@@ -188,7 +202,9 @@ class PostHogMetrics {
|
|
|
188
202
|
if (this._flushTimer) return;
|
|
189
203
|
this._flushTimer = (0, index_js_namespaceObject.safeSetTimeout)(()=>{
|
|
190
204
|
this._flushTimer = void 0;
|
|
191
|
-
this.flush().catch(()=>{
|
|
205
|
+
this.flush().catch((e)=>{
|
|
206
|
+
this._logger.error('Metrics flush failed:', e);
|
|
207
|
+
});
|
|
192
208
|
}, this._config.flushIntervalMs);
|
|
193
209
|
}
|
|
194
210
|
_clearFlushTimer() {
|
|
@@ -204,7 +220,9 @@ class PostHogMetrics {
|
|
|
204
220
|
this._seriesCapWarned = false;
|
|
205
221
|
this._typeByName = new Map();
|
|
206
222
|
this._typeCollisionWarned = new Set();
|
|
223
|
+
const generation = this._generation;
|
|
207
224
|
const outcome = await this._instance._sendMetricsBatch(this._buildPayload(window));
|
|
225
|
+
if (generation !== this._generation) return;
|
|
208
226
|
switch(outcome.kind){
|
|
209
227
|
case 'ok':
|
|
210
228
|
return;
|
|
@@ -288,7 +306,7 @@ class PostHogMetrics {
|
|
|
288
306
|
for (const [key, old] of window){
|
|
289
307
|
const current = this._series.get(key);
|
|
290
308
|
if (!current) {
|
|
291
|
-
this._series.set(key, old);
|
|
309
|
+
if (this._admitNewSeries()) this._series.set(key, old);
|
|
292
310
|
continue;
|
|
293
311
|
}
|
|
294
312
|
current.windowStartMs = Math.min(current.windowStartMs, old.windowStartMs);
|
|
@@ -315,11 +333,13 @@ exports.DEFAULT_HISTOGRAM_BOUNDS = __webpack_exports__.DEFAULT_HISTOGRAM_BOUNDS;
|
|
|
315
333
|
exports.PostHogMetrics = __webpack_exports__.PostHogMetrics;
|
|
316
334
|
exports.buildMetricsResourceAttributes = __webpack_exports__.buildMetricsResourceAttributes;
|
|
317
335
|
exports.buildOtlpMetricsPayload = __webpack_exports__.buildOtlpMetricsPayload;
|
|
336
|
+
exports.resolveMetricsConfig = __webpack_exports__.resolveMetricsConfig;
|
|
318
337
|
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
319
338
|
"DEFAULT_HISTOGRAM_BOUNDS",
|
|
320
339
|
"PostHogMetrics",
|
|
321
340
|
"buildMetricsResourceAttributes",
|
|
322
|
-
"buildOtlpMetricsPayload"
|
|
341
|
+
"buildOtlpMetricsPayload",
|
|
342
|
+
"resolveMetricsConfig"
|
|
323
343
|
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
324
344
|
Object.defineProperty(exports, '__esModule', {
|
|
325
345
|
value: true
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { isArray, safeSetTimeout } from "../utils/index.mjs";
|
|
2
2
|
import { toOtlpKeyValueList } from "../logs/logs-utils.mjs";
|
|
3
3
|
import { DEFAULT_HISTOGRAM_BOUNDS, bucketIndexFor, buildMetricsResourceAttributes, buildOtlpMetricsPayload, msToUnixNano, seriesKey } from "./metrics-utils.mjs";
|
|
4
|
+
import { resolveMetricsConfig } from "./config.mjs";
|
|
4
5
|
const OTLP_TEMPORALITY_DELTA = 1;
|
|
5
6
|
class PostHogMetrics {
|
|
6
7
|
constructor(_instance, _config, _logger){
|
|
@@ -12,6 +13,7 @@ class PostHogMetrics {
|
|
|
12
13
|
this._seriesCapWarned = false;
|
|
13
14
|
this._typeByName = new Map();
|
|
14
15
|
this._typeCollisionWarned = new Set();
|
|
16
|
+
this._generation = 0;
|
|
15
17
|
}
|
|
16
18
|
count(name, value = 1, options) {
|
|
17
19
|
this._capture({
|
|
@@ -62,6 +64,7 @@ class PostHogMetrics {
|
|
|
62
64
|
return this._buildPayload(window);
|
|
63
65
|
}
|
|
64
66
|
reset() {
|
|
67
|
+
this._generation++;
|
|
65
68
|
this._clearFlushTimer();
|
|
66
69
|
this._series = new Map();
|
|
67
70
|
this._flushPromise = null;
|
|
@@ -76,36 +79,46 @@ class PostHogMetrics {
|
|
|
76
79
|
if (!filtered.name || 'string' != typeof filtered.name) return void this._logger.warn('Dropping metric with empty name');
|
|
77
80
|
if ('number' != typeof filtered.value || !Number.isFinite(filtered.value)) return void this._logger.warn(`Dropping metric '${filtered.name}': value must be a finite number`);
|
|
78
81
|
if ('count' === filtered.type && filtered.value < 0) return void this._logger.warn(`Dropping count '${filtered.name}': counters are monotonic, value must be >= 0`);
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
let attributes;
|
|
83
|
+
let key;
|
|
84
|
+
try {
|
|
85
|
+
attributes = filtered.attributes ? {
|
|
86
|
+
...filtered.attributes
|
|
87
|
+
} : void 0;
|
|
88
|
+
key = seriesKey(filtered.type, filtered.name, filtered.unit, attributes);
|
|
89
|
+
} catch (e) {
|
|
90
|
+
this._logger.warn(`Dropping metric '${filtered.name}': attributes could not be serialized`, e);
|
|
91
|
+
return;
|
|
84
92
|
}
|
|
85
|
-
const key = seriesKey(filtered.type, filtered.name, filtered.unit, filtered.attributes);
|
|
86
93
|
let state = this._series.get(key);
|
|
87
94
|
if (!state) {
|
|
88
|
-
if (this.
|
|
89
|
-
if (!this._seriesCapWarned) {
|
|
90
|
-
this._seriesCapWarned = true;
|
|
91
|
-
this._logger.warn(`Metric series cap reached (${this._config.maxSeriesPerFlush} per flush window); dropping new series until the next flush. Reduce attribute cardinality.`);
|
|
92
|
-
}
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
+
if (!this._admitNewSeries()) return;
|
|
95
96
|
state = {
|
|
96
97
|
name: filtered.name,
|
|
97
98
|
type: filtered.type,
|
|
98
99
|
unit: filtered.unit,
|
|
99
|
-
attributes
|
|
100
|
-
...filtered.attributes
|
|
101
|
-
} : void 0,
|
|
100
|
+
attributes,
|
|
102
101
|
windowStartMs: Date.now()
|
|
103
102
|
};
|
|
104
103
|
this._series.set(key, state);
|
|
105
104
|
}
|
|
105
|
+
const seenType = this._typeByName.get(filtered.name);
|
|
106
|
+
if (void 0 === seenType) this._typeByName.set(filtered.name, filtered.type);
|
|
107
|
+
else if (seenType !== filtered.type && !this._typeCollisionWarned.has(filtered.name)) {
|
|
108
|
+
this._typeCollisionWarned.add(filtered.name);
|
|
109
|
+
this._logger.warn(`Metric name '${filtered.name}' is already used as a ${seenType}; recording it as a ${filtered.type} too will blend both series in charts. Use a distinct name.`);
|
|
110
|
+
}
|
|
106
111
|
this._fold(state, filtered.value);
|
|
107
112
|
this._armFlushTimer();
|
|
108
113
|
}
|
|
114
|
+
_admitNewSeries() {
|
|
115
|
+
if (this._series.size < this._config.maxSeriesPerFlush) return true;
|
|
116
|
+
if (!this._seriesCapWarned) {
|
|
117
|
+
this._seriesCapWarned = true;
|
|
118
|
+
this._logger.warn(`Metric series cap reached (${this._config.maxSeriesPerFlush} per flush window); dropping new series until the next flush. Reduce attribute cardinality.`);
|
|
119
|
+
}
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
109
122
|
_fold(state, value) {
|
|
110
123
|
switch(state.type){
|
|
111
124
|
case 'count':
|
|
@@ -157,7 +170,9 @@ class PostHogMetrics {
|
|
|
157
170
|
if (this._flushTimer) return;
|
|
158
171
|
this._flushTimer = safeSetTimeout(()=>{
|
|
159
172
|
this._flushTimer = void 0;
|
|
160
|
-
this.flush().catch(()=>{
|
|
173
|
+
this.flush().catch((e)=>{
|
|
174
|
+
this._logger.error('Metrics flush failed:', e);
|
|
175
|
+
});
|
|
161
176
|
}, this._config.flushIntervalMs);
|
|
162
177
|
}
|
|
163
178
|
_clearFlushTimer() {
|
|
@@ -173,7 +188,9 @@ class PostHogMetrics {
|
|
|
173
188
|
this._seriesCapWarned = false;
|
|
174
189
|
this._typeByName = new Map();
|
|
175
190
|
this._typeCollisionWarned = new Set();
|
|
191
|
+
const generation = this._generation;
|
|
176
192
|
const outcome = await this._instance._sendMetricsBatch(this._buildPayload(window));
|
|
193
|
+
if (generation !== this._generation) return;
|
|
177
194
|
switch(outcome.kind){
|
|
178
195
|
case 'ok':
|
|
179
196
|
return;
|
|
@@ -257,7 +274,7 @@ class PostHogMetrics {
|
|
|
257
274
|
for (const [key, old] of window){
|
|
258
275
|
const current = this._series.get(key);
|
|
259
276
|
if (!current) {
|
|
260
|
-
this._series.set(key, old);
|
|
277
|
+
if (this._admitNewSeries()) this._series.set(key, old);
|
|
261
278
|
continue;
|
|
262
279
|
}
|
|
263
280
|
current.windowStartMs = Math.min(current.windowStartMs, old.windowStartMs);
|
|
@@ -280,4 +297,4 @@ class PostHogMetrics {
|
|
|
280
297
|
}
|
|
281
298
|
}
|
|
282
299
|
}
|
|
283
|
-
export { DEFAULT_HISTOGRAM_BOUNDS, PostHogMetrics, buildMetricsResourceAttributes, buildOtlpMetricsPayload };
|
|
300
|
+
export { DEFAULT_HISTOGRAM_BOUNDS, PostHogMetrics, buildMetricsResourceAttributes, buildOtlpMetricsPayload, resolveMetricsConfig };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type { MetricAttributeValue, MetricAttributes, MetricType, CaptureMetricOptions, MetricSample, BeforeSendMetricFn, Metrics, OtlpNumberDataPoint, OtlpHistogramDataPoint, OtlpMetric, OtlpMetricsPayload, } from '@posthog/types';
|
|
1
|
+
export type { MetricAttributeValue, MetricAttributes, MetricType, MetricsConfig, CaptureMetricOptions, MetricSample, BeforeSendMetricFn, Metrics, OtlpNumberDataPoint, OtlpHistogramDataPoint, OtlpMetric, OtlpMetricsPayload, } from '@posthog/types';
|
|
2
2
|
import type { BeforeSendMetricFn, MetricAttributeValue, OtlpMetricsPayload } from '@posthog/types';
|
|
3
3
|
/** Same tagged outcome shape as `SendLogsBatchOutcome` — one policy for both signals. */
|
|
4
4
|
export type SendMetricsBatchOutcome = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/metrics/types.ts"],"names":[],"mappings":"AAEA,YAAY,EACV,oBAAoB,EACpB,gBAAgB,EAChB,UAAU,EACV,oBAAoB,EACpB,YAAY,EACZ,kBAAkB,EAClB,OAAO,EACP,mBAAmB,EACnB,sBAAsB,EACtB,UAAU,EACV,kBAAkB,GACnB,MAAM,gBAAgB,CAAA;AAEvB,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAElG,yFAAyF;AACzF,MAAM,MAAM,uBAAuB,GAC/B;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,GACd;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GACvC;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAA;AAErC;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;IAC5B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAA;IAChF,YAAY,IAAI,MAAM,CAAA;IACtB,iBAAiB,IAAI,MAAM,CAAA;CAC5B;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB,0DAA0D;IAC1D,cAAc,CAAC,EAAE,MAAM,CAAA;IAEvB,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAA;IAEzD;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IAExB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAE1B;;;OAGG;IACH,UAAU,CAAC,EAAE,kBAAkB,GAAG,kBAAkB,EAAE,CAAA;CACvD;AAID,MAAM,WAAW,4BAA6B,SAAQ,oBAAoB;IACxE,eAAe,EAAE,MAAM,CAAA;IACvB,iBAAiB,EAAE,MAAM,CAAA;CAC1B"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/metrics/types.ts"],"names":[],"mappings":"AAEA,YAAY,EACV,oBAAoB,EACpB,gBAAgB,EAChB,UAAU,EACV,aAAa,EACb,oBAAoB,EACpB,YAAY,EACZ,kBAAkB,EAClB,OAAO,EACP,mBAAmB,EACnB,sBAAsB,EACtB,UAAU,EACV,kBAAkB,GACnB,MAAM,gBAAgB,CAAA;AAEvB,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAElG,yFAAyF;AACzF,MAAM,MAAM,uBAAuB,GAC/B;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,GACd;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GACvC;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAA;AAErC;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;IAC5B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAA;IAChF,YAAY,IAAI,MAAM,CAAA;IACtB,iBAAiB,IAAI,MAAM,CAAA;CAC5B;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB,0DAA0D;IAC1D,cAAc,CAAC,EAAE,MAAM,CAAA;IAEvB,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAA;IAEzD;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IAExB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAE1B;;;OAGG;IACH,UAAU,CAAC,EAAE,kBAAkB,GAAG,kBAAkB,EAAE,CAAA;CACvD;AAID,MAAM,WAAW,4BAA6B,SAAQ,oBAAoB;IACxE,eAAe,EAAE,MAAM,CAAA;IACvB,iBAAiB,EAAE,MAAM,CAAA;CAC1B"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { OtlpLogsPayload } from '@posthog/types';
|
|
1
|
+
import type { OtlpLogsPayload, OtlpMetricsPayload } from '@posthog/types';
|
|
2
|
+
import type { SendMetricsBatchOutcome } from './metrics/types';
|
|
2
3
|
import { SimpleEventEmitter } from './eventemitter';
|
|
3
4
|
import { PostHogFlagsResponse, PostHogCoreOptions, PostHogEventProperties, PostHogCaptureOptions, JsonType, PostHogRemoteConfig, FeatureFlagValue, PostHogFeatureFlagDetails, FeatureFlagDetail, SurveyResponse, PostHogFetchResponse, PostHogFetchOptions, PostHogPersistedProperty, Logger, GetFlagsResult } from './types';
|
|
4
5
|
import { RetriableOptions } from './utils';
|
|
@@ -306,6 +307,13 @@ export declare abstract class PostHogCoreStateless {
|
|
|
306
307
|
* shrink `maxBatchRecordsPerPost` and retry the same records.
|
|
307
308
|
*/
|
|
308
309
|
_sendLogsBatch(payload: OtlpLogsPayload): Promise<SendLogsBatchOutcome>;
|
|
310
|
+
/**
|
|
311
|
+
* Sends a pre-built OTLP metrics payload to `/i/v1/metrics`. Same tagged
|
|
312
|
+
* outcome contract and error classification as `_sendLogsBatch` — this is
|
|
313
|
+
* the `MetricsHost._sendMetricsBatch` implementation, so `PostHogMetrics`
|
|
314
|
+
* can use any core-based SDK as its host.
|
|
315
|
+
*/
|
|
316
|
+
_sendMetricsBatch(payload: OtlpMetricsPayload): Promise<SendMetricsBatchOutcome>;
|
|
309
317
|
private fetchWithRetry;
|
|
310
318
|
_shutdown(shutdownTimeoutMs?: number): Promise<void>;
|
|
311
319
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"posthog-core-stateless.d.ts","sourceRoot":"","sources":["../src/posthog-core-stateless.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"posthog-core-stateless.d.ts","sourceRoot":"","sources":["../src/posthog-core-stateless.ts"],"names":[],"mappings":"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"}
|
|
@@ -555,7 +555,7 @@ class PostHogCoreStateless {
|
|
|
555
555
|
const queue = this.getPersistedProperty(queueKey) || [];
|
|
556
556
|
if (queue.length >= this.maxQueueSize) {
|
|
557
557
|
queue.shift();
|
|
558
|
-
this._logger.
|
|
558
|
+
this._logger.warn('Queue is full, the oldest event is dropped.');
|
|
559
559
|
}
|
|
560
560
|
queue.push({
|
|
561
561
|
message
|
|
@@ -803,6 +803,49 @@ class PostHogCoreStateless {
|
|
|
803
803
|
};
|
|
804
804
|
}
|
|
805
805
|
}
|
|
806
|
+
async _sendMetricsBatch(payload) {
|
|
807
|
+
if (this.disabled) return {
|
|
808
|
+
kind: 'fatal',
|
|
809
|
+
error: new Error('The client is disabled')
|
|
810
|
+
};
|
|
811
|
+
const serialized = JSON.stringify(payload);
|
|
812
|
+
const url = `${this.host}/i/v1/metrics?token=${encodeURIComponent(this.apiKey)}`;
|
|
813
|
+
const gzippedPayload = this.disableCompression ? null : await (0, external_gzip_js_namespaceObject.gzipCompress)(serialized, this.isDebug);
|
|
814
|
+
const fetchOptions = {
|
|
815
|
+
method: 'POST',
|
|
816
|
+
headers: {
|
|
817
|
+
...this.getCustomHeaders(),
|
|
818
|
+
'Content-Type': 'application/json',
|
|
819
|
+
...null !== gzippedPayload && {
|
|
820
|
+
'Content-Encoding': 'gzip'
|
|
821
|
+
}
|
|
822
|
+
},
|
|
823
|
+
body: gzippedPayload || serialized
|
|
824
|
+
};
|
|
825
|
+
try {
|
|
826
|
+
await this.fetchWithRetry(url, fetchOptions, {
|
|
827
|
+
retryCheck: (err)=>{
|
|
828
|
+
if (isPostHogFetchContentTooLargeError(err)) return false;
|
|
829
|
+
return isPostHogFetchRetryableError(err);
|
|
830
|
+
}
|
|
831
|
+
});
|
|
832
|
+
return {
|
|
833
|
+
kind: 'ok'
|
|
834
|
+
};
|
|
835
|
+
} catch (err) {
|
|
836
|
+
if (isPostHogFetchContentTooLargeError(err)) return {
|
|
837
|
+
kind: 'too-large'
|
|
838
|
+
};
|
|
839
|
+
if (isPostHogFetchRetryableError(err)) return {
|
|
840
|
+
kind: 'retry-later',
|
|
841
|
+
error: err
|
|
842
|
+
};
|
|
843
|
+
return {
|
|
844
|
+
kind: 'fatal',
|
|
845
|
+
error: err
|
|
846
|
+
};
|
|
847
|
+
}
|
|
848
|
+
}
|
|
806
849
|
async fetchWithRetry(url, options, retryOptions, requestTimeout) {
|
|
807
850
|
const body = options.body ? options.body : '';
|
|
808
851
|
let reqByteLength = -1;
|
|
@@ -522,7 +522,7 @@ class PostHogCoreStateless {
|
|
|
522
522
|
const queue = this.getPersistedProperty(queueKey) || [];
|
|
523
523
|
if (queue.length >= this.maxQueueSize) {
|
|
524
524
|
queue.shift();
|
|
525
|
-
this._logger.
|
|
525
|
+
this._logger.warn('Queue is full, the oldest event is dropped.');
|
|
526
526
|
}
|
|
527
527
|
queue.push({
|
|
528
528
|
message
|
|
@@ -770,6 +770,49 @@ class PostHogCoreStateless {
|
|
|
770
770
|
};
|
|
771
771
|
}
|
|
772
772
|
}
|
|
773
|
+
async _sendMetricsBatch(payload) {
|
|
774
|
+
if (this.disabled) return {
|
|
775
|
+
kind: 'fatal',
|
|
776
|
+
error: new Error('The client is disabled')
|
|
777
|
+
};
|
|
778
|
+
const serialized = JSON.stringify(payload);
|
|
779
|
+
const url = `${this.host}/i/v1/metrics?token=${encodeURIComponent(this.apiKey)}`;
|
|
780
|
+
const gzippedPayload = this.disableCompression ? null : await gzipCompress(serialized, this.isDebug);
|
|
781
|
+
const fetchOptions = {
|
|
782
|
+
method: 'POST',
|
|
783
|
+
headers: {
|
|
784
|
+
...this.getCustomHeaders(),
|
|
785
|
+
'Content-Type': 'application/json',
|
|
786
|
+
...null !== gzippedPayload && {
|
|
787
|
+
'Content-Encoding': 'gzip'
|
|
788
|
+
}
|
|
789
|
+
},
|
|
790
|
+
body: gzippedPayload || serialized
|
|
791
|
+
};
|
|
792
|
+
try {
|
|
793
|
+
await this.fetchWithRetry(url, fetchOptions, {
|
|
794
|
+
retryCheck: (err)=>{
|
|
795
|
+
if (isPostHogFetchContentTooLargeError(err)) return false;
|
|
796
|
+
return isPostHogFetchRetryableError(err);
|
|
797
|
+
}
|
|
798
|
+
});
|
|
799
|
+
return {
|
|
800
|
+
kind: 'ok'
|
|
801
|
+
};
|
|
802
|
+
} catch (err) {
|
|
803
|
+
if (isPostHogFetchContentTooLargeError(err)) return {
|
|
804
|
+
kind: 'too-large'
|
|
805
|
+
};
|
|
806
|
+
if (isPostHogFetchRetryableError(err)) return {
|
|
807
|
+
kind: 'retry-later',
|
|
808
|
+
error: err
|
|
809
|
+
};
|
|
810
|
+
return {
|
|
811
|
+
kind: 'fatal',
|
|
812
|
+
error: err
|
|
813
|
+
};
|
|
814
|
+
}
|
|
815
|
+
}
|
|
773
816
|
async fetchWithRetry(url, options, retryOptions, requestTimeout) {
|
|
774
817
|
const body = options.body ? options.body : '';
|
|
775
818
|
let reqByteLength = -1;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@posthog/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.42.1",
|
|
4
4
|
"bugs": {
|
|
5
5
|
"url": "https://github.com/PostHog/posthog-js/issues"
|
|
6
6
|
},
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
}
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
|
-
"@posthog/types": "^1.
|
|
73
|
+
"@posthog/types": "^1.395.0"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
76
|
"@rslib/core": "0.10.6",
|
|
@@ -45,6 +45,7 @@ export {
|
|
|
45
45
|
buildOtlpMetricsPayload,
|
|
46
46
|
buildMetricsResourceAttributes,
|
|
47
47
|
DEFAULT_HISTOGRAM_BOUNDS,
|
|
48
|
+
resolveMetricsConfig,
|
|
48
49
|
} from './metrics'
|
|
49
50
|
export type {
|
|
50
51
|
MetricsHost,
|
|
@@ -59,6 +60,8 @@ export type {
|
|
|
59
60
|
MetricAttributeValue,
|
|
60
61
|
MetricSample,
|
|
61
62
|
MetricType,
|
|
63
|
+
Metrics,
|
|
64
|
+
MetricsConfig,
|
|
62
65
|
} from './metrics/types'
|
|
63
66
|
export { uuidv7 } from './vendor/uuidv7'
|
|
64
67
|
export * from './cookie'
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { MetricsConfig } from '@posthog/types'
|
|
2
|
+
import type { ResolvedPostHogMetricsConfig } from './types'
|
|
3
|
+
|
|
4
|
+
const DEFAULT_FLUSH_INTERVAL_MS = 10000
|
|
5
|
+
const DEFAULT_MAX_SERIES_PER_FLUSH = 1000
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Resolves the public `metrics` config into the shape `PostHogMetrics`
|
|
9
|
+
* consumes. Same precedence rule as logs: OTLP keys in `resourceAttributes`
|
|
10
|
+
* win over the named config fields.
|
|
11
|
+
*/
|
|
12
|
+
export function resolveMetricsConfig(config: MetricsConfig | undefined): ResolvedPostHogMetricsConfig {
|
|
13
|
+
const resourceAttributes = config?.resourceAttributes
|
|
14
|
+
return {
|
|
15
|
+
serviceName: (resourceAttributes?.['service.name'] as string | undefined) ?? config?.serviceName,
|
|
16
|
+
serviceVersion: (resourceAttributes?.['service.version'] as string | undefined) ?? config?.serviceVersion,
|
|
17
|
+
environment: (resourceAttributes?.['deployment.environment'] as string | undefined) ?? config?.environment,
|
|
18
|
+
resourceAttributes,
|
|
19
|
+
beforeSend: config?.beforeSend,
|
|
20
|
+
flushIntervalMs: config?.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS,
|
|
21
|
+
maxSeriesPerFlush: config?.maxSeriesPerFlush ?? DEFAULT_MAX_SERIES_PER_FLUSH,
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -349,6 +349,34 @@ describe('PostHogMetrics', () => {
|
|
|
349
349
|
expect((logger.warn as jest.Mock).mock.calls.length).toBe(1)
|
|
350
350
|
})
|
|
351
351
|
|
|
352
|
+
it('re-applies the series cap when merging a failed window back', async () => {
|
|
353
|
+
let resolveSend!: (outcome: SendMetricsBatchOutcome) => void
|
|
354
|
+
mockInstance._sendMetricsBatch
|
|
355
|
+
.mockImplementationOnce(() => new Promise<SendMetricsBatchOutcome>((resolve) => (resolveSend = resolve)))
|
|
356
|
+
.mockResolvedValue({ kind: 'ok' })
|
|
357
|
+
|
|
358
|
+
const metrics = createMetrics({ maxSeriesPerFlush: 2 })
|
|
359
|
+
metrics.count('a', 1)
|
|
360
|
+
metrics.count('b', 1)
|
|
361
|
+
const inflight = metrics.flush()
|
|
362
|
+
// New series captured while the failing send is in flight fill the fresh window to the cap.
|
|
363
|
+
metrics.count('c', 1)
|
|
364
|
+
metrics.count('d', 1)
|
|
365
|
+
resolveSend({ kind: 'retry-later', error: new Error('offline') })
|
|
366
|
+
await inflight
|
|
367
|
+
|
|
368
|
+
await metrics.flush()
|
|
369
|
+
|
|
370
|
+
const payloads = sentPayloads()
|
|
371
|
+
expect(payloads).toHaveLength(2)
|
|
372
|
+
const dataPointCount = payloads[1].resourceMetrics[0].scopeMetrics[0].metrics.reduce(
|
|
373
|
+
(n, m) => n + (m.sum?.dataPoints.length ?? 0),
|
|
374
|
+
0
|
|
375
|
+
)
|
|
376
|
+
expect(dataPointCount).toBeLessThanOrEqual(2)
|
|
377
|
+
expect((logger.warn as jest.Mock).mock.calls.some((c) => String(c[0]).includes('series cap'))).toBe(true)
|
|
378
|
+
})
|
|
379
|
+
|
|
352
380
|
it('drops non-finite values and negative counts', async () => {
|
|
353
381
|
const metrics = createMetrics()
|
|
354
382
|
metrics.count('a', NaN)
|
|
@@ -365,6 +393,27 @@ describe('PostHogMetrics', () => {
|
|
|
365
393
|
expect(sent[0].gauge!.dataPoints[0].asDouble).toBe(-5)
|
|
366
394
|
})
|
|
367
395
|
|
|
396
|
+
it('drops samples with unserializable attributes instead of throwing', async () => {
|
|
397
|
+
const metrics = createMetrics()
|
|
398
|
+
const throwingAttrs = {}
|
|
399
|
+
Object.defineProperty(throwingAttrs, 'bad', {
|
|
400
|
+
enumerable: true,
|
|
401
|
+
get() {
|
|
402
|
+
throw new Error('boom')
|
|
403
|
+
},
|
|
404
|
+
})
|
|
405
|
+
|
|
406
|
+
expect(() => metrics.count('good', 1, { attributes: { plan: 'free' } })).not.toThrow()
|
|
407
|
+
expect(() => metrics.count('bigint_attr', 1, { attributes: { jobId: BigInt(1) } as any })).not.toThrow()
|
|
408
|
+
expect(() => metrics.count('throwing_attr', 1, { attributes: throwingAttrs as any })).not.toThrow()
|
|
409
|
+
await metrics.flush()
|
|
410
|
+
|
|
411
|
+
// Only the well-formed sample ships; the malformed ones are dropped with a warning.
|
|
412
|
+
expect(sentMetrics().map((m) => m.name)).toEqual(['good'])
|
|
413
|
+
const attrWarns = (logger.warn as jest.Mock).mock.calls.filter((c) => String(c[0]).includes('attributes'))
|
|
414
|
+
expect(attrWarns).toHaveLength(2)
|
|
415
|
+
})
|
|
416
|
+
|
|
368
417
|
it('drops samples with an empty name', async () => {
|
|
369
418
|
const metrics = createMetrics()
|
|
370
419
|
metrics.count('', 1)
|
|
@@ -73,6 +73,10 @@ export class PostHogMetrics {
|
|
|
73
73
|
// types under one name produces charts that blend both series.
|
|
74
74
|
private _typeByName = new Map<string, MetricType>()
|
|
75
75
|
private _typeCollisionWarned = new Set<string>()
|
|
76
|
+
// Bumped by reset(). A flush that was in flight when reset() ran (e.g. it
|
|
77
|
+
// lost a shutdown race) sees a stale generation when its send settles and
|
|
78
|
+
// discards its window instead of merging it back and re-arming the timer.
|
|
79
|
+
private _generation = 0
|
|
76
80
|
|
|
77
81
|
constructor(
|
|
78
82
|
private readonly _instance: MetricsHost,
|
|
@@ -129,8 +133,9 @@ export class PostHogMetrics {
|
|
|
129
133
|
return this._buildPayload(window)
|
|
130
134
|
}
|
|
131
135
|
|
|
132
|
-
/** Clears the flush timer
|
|
136
|
+
/** Clears the flush timer, drops the current window, and invalidates in-flight flushes. */
|
|
133
137
|
reset(): void {
|
|
138
|
+
this._generation++
|
|
134
139
|
this._clearFlushTimer()
|
|
135
140
|
this._series = new Map()
|
|
136
141
|
this._flushPromise = null
|
|
@@ -163,46 +168,70 @@ export class PostHogMetrics {
|
|
|
163
168
|
return
|
|
164
169
|
}
|
|
165
170
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
)
|
|
171
|
+
// Snapshot: the key is computed from these values, so a caller mutating
|
|
172
|
+
// the object after capture must not change the stored series. Reading and
|
|
173
|
+
// serializing the attributes can throw (BigInt values, throwing
|
|
174
|
+
// getters/proxies) — a malformed sample is dropped, never thrown.
|
|
175
|
+
let attributes: MetricAttributes | undefined
|
|
176
|
+
let key: string
|
|
177
|
+
try {
|
|
178
|
+
attributes = filtered.attributes ? { ...filtered.attributes } : undefined
|
|
179
|
+
key = seriesKey(filtered.type, filtered.name, filtered.unit, attributes)
|
|
180
|
+
} catch (e) {
|
|
181
|
+
this._logger.warn(`Dropping metric '${filtered.name}': attributes could not be serialized`, e)
|
|
182
|
+
return
|
|
175
183
|
}
|
|
176
184
|
|
|
177
|
-
const key = seriesKey(filtered.type, filtered.name, filtered.unit, filtered.attributes)
|
|
178
185
|
let state = this._series.get(key)
|
|
179
186
|
if (!state) {
|
|
180
|
-
if (this.
|
|
181
|
-
if (!this._seriesCapWarned) {
|
|
182
|
-
this._seriesCapWarned = true
|
|
183
|
-
this._logger.warn(
|
|
184
|
-
`Metric series cap reached (${this._config.maxSeriesPerFlush} per flush window); ` +
|
|
185
|
-
`dropping new series until the next flush. Reduce attribute cardinality.`
|
|
186
|
-
)
|
|
187
|
-
}
|
|
187
|
+
if (!this._admitNewSeries()) {
|
|
188
188
|
return
|
|
189
189
|
}
|
|
190
190
|
state = {
|
|
191
191
|
name: filtered.name,
|
|
192
192
|
type: filtered.type,
|
|
193
193
|
unit: filtered.unit,
|
|
194
|
-
|
|
195
|
-
// mutating the object after capture must not change the stored series.
|
|
196
|
-
attributes: filtered.attributes ? { ...filtered.attributes } : undefined,
|
|
194
|
+
attributes,
|
|
197
195
|
windowStartMs: Date.now(),
|
|
198
196
|
}
|
|
199
197
|
this._series.set(key, state)
|
|
200
198
|
}
|
|
201
199
|
|
|
200
|
+
// Bookkeeping only for admitted samples, so name-cardinality misuse (IDs
|
|
201
|
+
// interpolated into metric names) can't grow this map past the series cap.
|
|
202
|
+
const seenType = this._typeByName.get(filtered.name)
|
|
203
|
+
if (seenType === undefined) {
|
|
204
|
+
this._typeByName.set(filtered.name, filtered.type)
|
|
205
|
+
} else if (seenType !== filtered.type && !this._typeCollisionWarned.has(filtered.name)) {
|
|
206
|
+
this._typeCollisionWarned.add(filtered.name)
|
|
207
|
+
this._logger.warn(
|
|
208
|
+
`Metric name '${filtered.name}' is already used as a ${seenType}; ` +
|
|
209
|
+
`recording it as a ${filtered.type} too will blend both series in charts. Use a distinct name.`
|
|
210
|
+
)
|
|
211
|
+
}
|
|
212
|
+
|
|
202
213
|
this._fold(state, filtered.value)
|
|
203
214
|
this._armFlushTimer()
|
|
204
215
|
}
|
|
205
216
|
|
|
217
|
+
/**
|
|
218
|
+
* Cardinality gate for adding a series to the live window — warns once per
|
|
219
|
+
* window when the cap is hit. Applied on capture and on merge-back alike.
|
|
220
|
+
*/
|
|
221
|
+
private _admitNewSeries(): boolean {
|
|
222
|
+
if (this._series.size < this._config.maxSeriesPerFlush) {
|
|
223
|
+
return true
|
|
224
|
+
}
|
|
225
|
+
if (!this._seriesCapWarned) {
|
|
226
|
+
this._seriesCapWarned = true
|
|
227
|
+
this._logger.warn(
|
|
228
|
+
`Metric series cap reached (${this._config.maxSeriesPerFlush} per flush window); ` +
|
|
229
|
+
`dropping new series until the next flush. Reduce attribute cardinality.`
|
|
230
|
+
)
|
|
231
|
+
}
|
|
232
|
+
return false
|
|
233
|
+
}
|
|
234
|
+
|
|
206
235
|
private _fold(state: SeriesState, value: number): void {
|
|
207
236
|
switch (state.type) {
|
|
208
237
|
case 'count':
|
|
@@ -261,7 +290,9 @@ export class PostHogMetrics {
|
|
|
261
290
|
}
|
|
262
291
|
this._flushTimer = safeSetTimeout(() => {
|
|
263
292
|
this._flushTimer = undefined
|
|
264
|
-
this.flush().catch(() => {
|
|
293
|
+
this.flush().catch((e) => {
|
|
294
|
+
this._logger.error('Metrics flush failed:', e)
|
|
295
|
+
})
|
|
265
296
|
}, this._config.flushIntervalMs)
|
|
266
297
|
}
|
|
267
298
|
|
|
@@ -285,7 +316,13 @@ export class PostHogMetrics {
|
|
|
285
316
|
this._typeByName = new Map()
|
|
286
317
|
this._typeCollisionWarned = new Set()
|
|
287
318
|
|
|
319
|
+
const generation = this._generation
|
|
288
320
|
const outcome = await this._instance._sendMetricsBatch(this._buildPayload(window))
|
|
321
|
+
if (generation !== this._generation) {
|
|
322
|
+
// reset() ran while the send was in flight — the client was torn down or
|
|
323
|
+
// reconfigured, so this window is dropped whatever the outcome was.
|
|
324
|
+
return
|
|
325
|
+
}
|
|
289
326
|
switch (outcome.kind) {
|
|
290
327
|
case 'ok':
|
|
291
328
|
return
|
|
@@ -379,7 +416,11 @@ export class PostHogMetrics {
|
|
|
379
416
|
for (const [key, old] of window) {
|
|
380
417
|
const current = this._series.get(key)
|
|
381
418
|
if (!current) {
|
|
382
|
-
|
|
419
|
+
// The cap still applies here: an unbounded merge-back would let a
|
|
420
|
+
// failed flush reintroduce series past maxSeriesPerFlush.
|
|
421
|
+
if (this._admitNewSeries()) {
|
|
422
|
+
this._series.set(key, old)
|
|
423
|
+
}
|
|
383
424
|
continue
|
|
384
425
|
}
|
|
385
426
|
current.windowStartMs = Math.min(current.windowStartMs, old.windowStartMs)
|
|
@@ -411,4 +452,5 @@ export class PostHogMetrics {
|
|
|
411
452
|
}
|
|
412
453
|
|
|
413
454
|
export { buildOtlpMetricsPayload, buildMetricsResourceAttributes, DEFAULT_HISTOGRAM_BOUNDS } from './metrics-utils'
|
|
455
|
+
export { resolveMetricsConfig } from './config'
|
|
414
456
|
export type { MetricsHost, PostHogMetricsConfig, ResolvedPostHogMetricsConfig, SendMetricsBatchOutcome } from './types'
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { OtlpLogsPayload } from '@posthog/types'
|
|
1
|
+
import type { OtlpLogsPayload, OtlpMetricsPayload } from '@posthog/types'
|
|
2
|
+
import type { SendMetricsBatchOutcome } from './metrics/types'
|
|
2
3
|
import { SimpleEventEmitter } from './eventemitter'
|
|
3
4
|
import { getFeatureFlagValue, normalizeFlagsResponse } from './featureFlagUtils'
|
|
4
5
|
import { gzipCompress, isGzipSupported } from './gzip'
|
|
@@ -1092,7 +1093,7 @@ export abstract class PostHogCoreStateless {
|
|
|
1092
1093
|
|
|
1093
1094
|
if (queue.length >= this.maxQueueSize) {
|
|
1094
1095
|
queue.shift()
|
|
1095
|
-
this._logger.
|
|
1096
|
+
this._logger.warn('Queue is full, the oldest event is dropped.')
|
|
1096
1097
|
}
|
|
1097
1098
|
|
|
1098
1099
|
queue.push({ message })
|
|
@@ -1534,6 +1535,55 @@ export abstract class PostHogCoreStateless {
|
|
|
1534
1535
|
}
|
|
1535
1536
|
}
|
|
1536
1537
|
|
|
1538
|
+
/**
|
|
1539
|
+
* Sends a pre-built OTLP metrics payload to `/i/v1/metrics`. Same tagged
|
|
1540
|
+
* outcome contract and error classification as `_sendLogsBatch` — this is
|
|
1541
|
+
* the `MetricsHost._sendMetricsBatch` implementation, so `PostHogMetrics`
|
|
1542
|
+
* can use any core-based SDK as its host.
|
|
1543
|
+
*/
|
|
1544
|
+
async _sendMetricsBatch(payload: OtlpMetricsPayload): Promise<SendMetricsBatchOutcome> {
|
|
1545
|
+
if (this.disabled) {
|
|
1546
|
+
return { kind: 'fatal', error: new Error('The client is disabled') }
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1549
|
+
const serialized = JSON.stringify(payload)
|
|
1550
|
+
const url = `${this.host}/i/v1/metrics?token=${encodeURIComponent(this.apiKey)}`
|
|
1551
|
+
|
|
1552
|
+
const gzippedPayload = !this.disableCompression ? await gzipCompress(serialized, this.isDebug) : null
|
|
1553
|
+
const fetchOptions: PostHogFetchOptions = {
|
|
1554
|
+
method: 'POST',
|
|
1555
|
+
headers: {
|
|
1556
|
+
...this.getCustomHeaders(),
|
|
1557
|
+
'Content-Type': 'application/json',
|
|
1558
|
+
...(gzippedPayload !== null && { 'Content-Encoding': 'gzip' }),
|
|
1559
|
+
},
|
|
1560
|
+
body: gzippedPayload || serialized,
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
try {
|
|
1564
|
+
await this.fetchWithRetry(url, fetchOptions, {
|
|
1565
|
+
retryCheck: (err) => {
|
|
1566
|
+
if (isPostHogFetchContentTooLargeError(err)) {
|
|
1567
|
+
return false
|
|
1568
|
+
}
|
|
1569
|
+
return isPostHogFetchRetryableError(err)
|
|
1570
|
+
},
|
|
1571
|
+
})
|
|
1572
|
+
return { kind: 'ok' }
|
|
1573
|
+
} catch (err) {
|
|
1574
|
+
if (isPostHogFetchContentTooLargeError(err)) {
|
|
1575
|
+
return { kind: 'too-large' }
|
|
1576
|
+
}
|
|
1577
|
+
// Exhausted retries on a retryable failure (network error, 408/429/5xx)
|
|
1578
|
+
// still classify as retry-later so the window rides the next flush; only
|
|
1579
|
+
// non-retryable HTTP errors (and 413 above) drop the batch.
|
|
1580
|
+
if (isPostHogFetchRetryableError(err)) {
|
|
1581
|
+
return { kind: 'retry-later', error: err }
|
|
1582
|
+
}
|
|
1583
|
+
return { kind: 'fatal', error: err }
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
|
|
1537
1587
|
private async fetchWithRetry(
|
|
1538
1588
|
url: string,
|
|
1539
1589
|
options: PostHogFetchOptions,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zuplo/cli",
|
|
3
|
-
"version": "6.72.
|
|
3
|
+
"version": "6.72.11",
|
|
4
4
|
"repository": "https://github.com/zuplo/zuplo",
|
|
5
5
|
"author": "Zuplo, Inc.",
|
|
6
6
|
"type": "module",
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
"@opentelemetry/api": "1.9.0",
|
|
28
28
|
"@opentelemetry/api-logs": "0.201.1",
|
|
29
29
|
"@swc/core": "1.10.18",
|
|
30
|
-
"@zuplo/core": "6.72.
|
|
30
|
+
"@zuplo/core": "6.72.11",
|
|
31
31
|
"@zuplo/editor": "1.0.20821740935",
|
|
32
|
-
"@zuplo/openapi-tools": "6.72.
|
|
33
|
-
"@zuplo/runtime": "6.72.
|
|
32
|
+
"@zuplo/openapi-tools": "6.72.11",
|
|
33
|
+
"@zuplo/runtime": "6.72.11",
|
|
34
34
|
"chalk": "5.4.1",
|
|
35
35
|
"chokidar": "3.5.3",
|
|
36
36
|
"cookie": "1.0.2",
|
|
@@ -61,8 +61,8 @@
|
|
|
61
61
|
"workerd": "1.20241230.0",
|
|
62
62
|
"yargs": "17.7.2",
|
|
63
63
|
"zod": "3.25.76",
|
|
64
|
-
"@zuplo/graphql": "6.72.
|
|
65
|
-
"@zuplo/otel": "6.72.
|
|
64
|
+
"@zuplo/graphql": "6.72.11",
|
|
65
|
+
"@zuplo/otel": "6.72.11"
|
|
66
66
|
},
|
|
67
67
|
"bundleDependencies": [
|
|
68
68
|
"@inquirer/prompts",
|