Skip to content

Commit

Permalink
DEV: regen
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael O'Brien committed Aug 20, 2023
1 parent 779b52b commit 13e93c5
Show file tree
Hide file tree
Showing 6 changed files with 219 additions and 252 deletions.
13 changes: 8 additions & 5 deletions dist/cjs/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Schema, Version } from './schema';
import { Schema } from './schema';
import { Entity, Table } from 'dynamodb-onetable';
type SpanDef = {
period: number;
Expand Down Expand Up @@ -60,7 +60,6 @@ export type MetricEmitOptions = {
ttl?: number;
};
export type MetricListOptions = {
fields?: string[];
log?: boolean;
limit?: number;
next?: object;
Expand Down Expand Up @@ -92,8 +91,9 @@ export declare class CustomMetrics {
private ttl;
constructor(options?: MetricOptions);
emit(namespace: string, metricName: string, value: number, dimensionsList?: MetricDimensionsList, options?: MetricEmitOptions): Promise<Metric>;
private emitDimensionMetric;
bufferMetric(namespace: string, metricName: string, value: number, dimensionsList: MetricDimensionsList, options: MetricBufferOptions): Point;
private emitDimensions;
private emitDimensionedMetric;
bufferMetric(namespace: string, metricName: string, value: number, dimensionsList: MetricDimensionsList, options: MetricEmitOptions): Promise<Metric>;
static terminate(): Promise<void>;
static flushAll(): Promise<void>;
flush(): Promise<void>;
Expand All @@ -115,5 +115,8 @@ export declare class CustomMetrics {
static getCache(): InstanceMap;
private getTimestamp;
private assert;
private info;
private error;
private nop;
}
export { Schema, Version };
export {};
146 changes: 63 additions & 83 deletions dist/cjs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Version = exports.Schema = exports.CustomMetrics = exports.DefaultSpans = void 0;
exports.CustomMetrics = exports.DefaultSpans = void 0;
const process_1 = __importDefault(require("process"));
const schema_1 = require("./schema");
Object.defineProperty(exports, "Schema", { enumerable: true, get: function () { return schema_1.Schema; } });
Object.defineProperty(exports, "Version", { enumerable: true, get: function () { return schema_1.Version; } });
const dynamodb_onetable_1 = require("dynamodb-onetable");
const Assert = true;
const Buffering = true;
Expand All @@ -31,25 +29,16 @@ class CustomMetrics {
constructor(options = {}) {
this.buffers = {};
if (options.log == true) {
this.log = {
info: (message, context) => null,
error: (message, context) => console.log('ERROR: ' + message, context),
};
this.log = { info: this.nop, error: this.error };
}
else if (options.log == 'verbose') {
this.log.info = (message, context) => console.log('INFO: ' + message, context);
this.log = { info: this.info, error: this.error };
}
else if (options.log) {
this.log = options.log;
}
else {
this.log = {
info: (message, context) => null,
error: (message, context) => null,
};
}
if (!options.owner) {
throw new Error('Missing required "owner" in options');
this.log = { info: this.nop, error: this.nop };
}
if (options.ttl && typeof options.ttl != 'number') {
throw new Error('Bad type for "ttl" option');
Expand Down Expand Up @@ -131,29 +120,20 @@ class CustomMetrics {
let point;
let buffer = options.buffer || this.buffer;
if (buffer && Buffering) {
point = this.bufferMetric(namespace, metricName, value, dimensionsList, buffer);
if (point.timestamp === 0) {
let result = {
spans: [{ points: [point] }],
metric: metricName,
namespace: namespace,
owner: options.owner || this.owner,
version: schema_1.Version,
};
return result;
}
}
else {
point = { count: 1, sum: value };
return await this.bufferMetric(namespace, metricName, value, dimensionsList, options);
}
point = { count: 1, sum: value };
return await this.emitDimensions(namespace, metricName, point, dimensionsList, options);
}
async emitDimensions(namespace, metricName, point, dimensionsList, options) {
let result;
for (let dimensions of dimensionsList) {
let dimString = this.makeDimensionString(dimensions);
result = await this.emitDimensionMetric(namespace, metricName, point, dimString, options);
result = await this.emitDimensionedMetric(namespace, metricName, point, dimString, options);
}
return result;
}
async emitDimensionMetric(namespace, metricName, point, dimensions, options = {}) {
async emitDimensionedMetric(namespace, metricName, point, dimensions, options = {}) {
let ttl = options.ttl != undefined ? options.ttl : this.ttl;
let retries = MaxRetries;
let metric;
Expand Down Expand Up @@ -194,35 +174,40 @@ class CustomMetrics {
} while (retries-- > 0);
return metric;
}
bufferMetric(namespace, metricName, value, dimensionsList, options) {
async bufferMetric(namespace, metricName, value, dimensionsList, options) {
let buffer = options.buffer || this.buffer;
let interval = this.spans[0].period / this.spans[0].samples;
let key = `${namespace}|${metricName}|${JSON.stringify(dimensionsList)}`;
let elt = (this.buffers[key] = this.buffers[key] || {
count: 0,
sum: 0,
timestamp: this.timestamp + (options.elapsed || interval),
timestamp: this.timestamp + (buffer.elapsed || interval),
namespace: namespace,
metric: metricName,
dimensions: dimensionsList,
});
elt.sum += value;
elt.count++;
if (options.force ||
(options.sum && elt.sum >= options.sum) ||
(options.count && elt.count >= options.count) ||
if (buffer.force ||
(buffer.sum && elt.sum >= buffer.sum) ||
(buffer.count && elt.count >= buffer.count) ||
this.timestamp >= elt.timestamp) {
delete this.buffers[key];
this.log.info(`Emit buffered metric ${namespace}/${metricName} = ${value}, sum ${elt.sum} count ${elt.count} remaining ${elt.timestamp - this.timestamp}`, { elt, buffers: this.buffers });
return { count: elt.count, sum: elt.sum, timestamp: elt.timestamp };
this.log.info(`Emit buffered metric ${namespace}/${metricName} = ${value}, sum ${elt.sum} count ${elt.count} remaining ${elt.timestamp - this.timestamp}`);
let point = { count: elt.count, sum: elt.sum, timestamp: elt.timestamp };
await this.emitDimensions(namespace, metricName, point, dimensionsList, options);
}
CustomMetrics.saveInstance({ key }, this);
elt.count++;
elt.sum += value;
this.log.info(`Buffer metric ${namespace}/${metricName} = ${value}, sum ${elt.sum} count ${elt.count}, remaining ${elt.timestamp - this.timestamp}`);
return { count: elt.count, sum: elt.sum, timestamp: 0 };
CustomMetrics.saveInstance({ key }, this);
return {
spans: [{ points: [{ count: elt.count, sum: elt.sum }] }],
metric: metricName,
namespace: namespace,
owner: options.owner || this.owner,
version: schema_1.Version,
};
}
static async terminate() {
let start = Date.now();
await CustomMetrics.flushAll();
console.log(`Lambda terminating, metric flush took ${(Date.now() - start) / 1000} ms`);
}
static async flushAll() {
for (let [key, instance] of Object.entries(Instances)) {
Expand All @@ -235,7 +220,7 @@ class CustomMetrics {
for (let elt of Object.values(this.buffers)) {
let point = { count: elt.count, sum: elt.sum };
for (let dimensions of elt.dimensions) {
await this.emitDimensionMetric(elt.namespace, elt.metric, point, this.makeDimensionString(dimensions));
await this.emitDimensionedMetric(elt.namespace, elt.metric, point, this.makeDimensionString(dimensions));
}
}
this.buffers = {};
Expand Down Expand Up @@ -281,7 +266,7 @@ class CustomMetrics {
else {
result = { dimensions, metric: metricName, namespace, period, points: [], owner };
}
this.log.info(`Metric query ${namespace}, ${metricName}, ${this.makeDimensionString(dimensions)}, ` +
this.log.info(`Metric query ${namespace}, ${metricName}, ${this.makeDimensionString(dimensions) || '[]'}, ` +
`period ${period}, statistic "${statistic}"`, { result });
return result;
}
Expand Down Expand Up @@ -323,19 +308,17 @@ class CustomMetrics {
}
else if (statistic == 'sum') {
value += point.sum;
count += point.count;
}
else if (statistic == 'count') {
value += point.count;
count += point.count;
}
else if (statistic.match(/^p[0-9]+/)) {
pvalues = pvalues.concat(point.pvalues || []);
pvalues = pvalues.concat(point.pvalues);
}
else {
value += point.sum;
count += point.count;
}
count += point.count;
}
if (statistic.match(/^p[0-9]+/)) {
let p = parseInt(statistic.slice(1));
Expand All @@ -344,7 +327,7 @@ class CustomMetrics {
value = pvalues[nth];
}
else if (statistic == 'avg') {
value /= count || 1;
value /= Math.max(count, 1);
}
return {
dimensions: this.makeDimensionObject(metric.dimensions),
Expand All @@ -359,9 +342,9 @@ class CustomMetrics {
let points = [];
let interval = span.period / span.samples;
let timestamp = span.end - span.points.length * interval;
let value;
let i = 0;
for (let point of span.points) {
let value;
if (point.count > 0) {
if (statistic == 'max') {
if (point.max != undefined) {
Expand Down Expand Up @@ -391,13 +374,13 @@ class CustomMetrics {
}
else if (statistic.match(/^p[0-9]+/)) {
let p = parseInt(statistic.slice(1));
let pvalues = point.pvalues || [];
let pvalues = point.pvalues;
pvalues.sort((a, b) => a - b);
let nth = Math.min(Math.round((pvalues.length * p) / 100 + 1), pvalues.length - 1);
value = pvalues[nth];
}
else {
value = point.sum / (point.count || 1);
value = point.sum / point.count;
}
}
timestamp += interval;
Expand All @@ -416,10 +399,7 @@ class CustomMetrics {
}
makeDimensionString(dimensions) {
let result = [];
for (let [name, value] of Object.entries(dimensions || {})) {
if (Array.isArray(value)) {
this.log.error(`Dimension is an array`, { value, dimensions });
}
for (let [name, value] of Object.entries(dimensions)) {
result.push(`${name}=${value}`);
}
return result.join(',');
Expand All @@ -442,35 +422,37 @@ class CustomMetrics {
let interval = span.period / span.samples;
let points = span.points;
let start = span.end - points.length * interval;
let period = span.period < queryPeriod ? queryPeriod : 0;
let aggregate = !queryPeriod || span.period < queryPeriod ? true : false;
while (points.length > span.samples) {
points.shift();
}
if (points.length) {
if (timestamp < start) {
this.log.error('Bad span', { metric, point, timestamp, start, span });
this.log.error('Bad metric span', { metric, point, timestamp, start, span });
return;
}
let shift = 0;
if (queryPeriod) {
if (period) {
shift = points.length;
}
if (queryPeriod && aggregate) {
shift = points.length;
}
else if (point.count) {
shift = (timestamp - start) / interval - span.samples + 1;
shift = Math.floor((timestamp - start) / interval) - span.samples + 1;
}
else if (queryPeriod) {
shift = Math.floor((timestamp - start) / interval) - span.samples;
}
shift = Math.max(0, Math.min(shift, points.length));
this.assert(0 <= shift && shift <= points.length);
while (shift-- > 0) {
let p = points.shift();
if (p.count && si + 1 < metric.spans.length) {
this.addValue(metric, start, p, si + 1, period);
if (aggregate && p.count && si + 1 < metric.spans.length) {
this.addValue(metric, start, p, si + 1, queryPeriod);
}
start += interval;
}
}
if (period) {
if (si + 1 < metric.spans.length) {
this.addValue(metric, timestamp, point, si + 1, period);
}
if (aggregate && queryPeriod && si + 1 < metric.spans.length) {
this.addValue(metric, timestamp, point, si + 1, queryPeriod);
}
else if (point.count) {
if (points.length == 0) {
Expand Down Expand Up @@ -516,7 +498,7 @@ class CustomMetrics {
if (this.pResolution) {
point.pvalues = point.pvalues || [];
if (add.pvalues) {
point.pvalues.push(...(add.pvalues || [add.sum / add.count]));
point.pvalues.push(...add.pvalues);
}
else {
point.pvalues.push(add.sum / add.count);
Expand Down Expand Up @@ -549,17 +531,8 @@ class CustomMetrics {
stats,
where,
});
let size = JSON.stringify(result).length;
this.log.info(`Emit metric: ${metric.namespace}/${metric.metric}/${metric.dimensions} = ${point.sum}, msize ${size}`, {
metric,
point,
stats,
});
}
async getMetricList(namespace = undefined, metric = undefined, options = { fields: ['pk', 'sk'], limit: MetricListLimit }) {
if (!options.fields) {
options.fields = ['pk', 'sk'];
}
async getMetricList(namespace = undefined, metric = undefined, options = { limit: MetricListLimit }) {
let map = {};
let next;
let owner = options.owner || this.owner;
Expand Down Expand Up @@ -655,5 +628,12 @@ class CustomMetrics {
this.log.error(`Assertion failed ${msg.stack}`);
}
}
info(message, context = {}) {
console.log('INFO: ' + message, context);
}
error(message, context = {}) {
console.log('ERROR: ' + message, context);
}
nop() { }
}
exports.CustomMetrics = CustomMetrics;
13 changes: 8 additions & 5 deletions dist/mjs/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Schema, Version } from './schema';
import { Schema } from './schema';
import { Entity, Table } from 'dynamodb-onetable';
type SpanDef = {
period: number;
Expand Down Expand Up @@ -60,7 +60,6 @@ export type MetricEmitOptions = {
ttl?: number;
};
export type MetricListOptions = {
fields?: string[];
log?: boolean;
limit?: number;
next?: object;
Expand Down Expand Up @@ -92,8 +91,9 @@ export declare class CustomMetrics {
private ttl;
constructor(options?: MetricOptions);
emit(namespace: string, metricName: string, value: number, dimensionsList?: MetricDimensionsList, options?: MetricEmitOptions): Promise<Metric>;
private emitDimensionMetric;
bufferMetric(namespace: string, metricName: string, value: number, dimensionsList: MetricDimensionsList, options: MetricBufferOptions): Point;
private emitDimensions;
private emitDimensionedMetric;
bufferMetric(namespace: string, metricName: string, value: number, dimensionsList: MetricDimensionsList, options: MetricEmitOptions): Promise<Metric>;
static terminate(): Promise<void>;
static flushAll(): Promise<void>;
flush(): Promise<void>;
Expand All @@ -115,5 +115,8 @@ export declare class CustomMetrics {
static getCache(): InstanceMap;
private getTimestamp;
private assert;
private info;
private error;
private nop;
}
export { Schema, Version };
export {};
Loading

0 comments on commit 13e93c5

Please sign in to comment.