Skip to content

Commit

Permalink
Prom client in mock prom metrics (#3613)
Browse files Browse the repository at this point in the history
This PR makes the following changes:

- add `teraslice_` prefix to `promMetrics.init()` for master so all
metric names match what was in `teraslice-exporter` package.
- update `mockPrommetrics` to use `prom-client`. This allows `collect()`
functions to be used in `TestContext`.
  • Loading branch information
busma13 authored May 15, 2024
1 parent 67d0d2c commit d79ff05
Show file tree
Hide file tree
Showing 15 changed files with 201 additions and 130 deletions.
6 changes: 3 additions & 3 deletions docs/development/k8s.md
Original file line number Diff line number Diff line change
Expand Up @@ -409,15 +409,15 @@ this.context.apis.foundation.promMetrics.inc(
Example Gauge using collect() callback:
```typescript
const self = this; // rename `this` to use inside collect()
const { context, getSlicesDispatched } = this;
await this.context.apis.foundation.promMetrics.addGauge(
'slices_dispatched', // name
'number of slices a slicer has dispatched', // help or description
['class'], // label names specific to this metric
function collect() { // callback fn updates value only when '/metrics' endpoint is hit
const slicesFinished = self.getSlicesDispatched(); // get current value from local momory
const slicesFinished = getSlicesDispatched(); // get current value from local momory
const labels = { // 'set()' needs both default labels and labels specific to metric to match the correct gauge
...self.context.apis.foundation.promMetrics.getDefaultLabels(),
...context.apis.foundation.promMetrics.getDefaultLabels(),
class: 'SlicerExecutionContext'
};
this.set(labels, slicesFinished); // this refers to the Gauge
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "teraslice-workspace",
"displayName": "Teraslice",
"version": "1.5.1",
"version": "1.5.2",
"private": true,
"homepage": "https://github.com/terascope/teraslice",
"bugs": {
Expand Down
3 changes: 2 additions & 1 deletion packages/job-components/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@terascope/job-components",
"displayName": "Job Components",
"version": "0.74.1",
"version": "0.74.2",
"description": "A teraslice library for validating jobs schemas, registering apis, and defining and running new Job APIs",
"homepage": "https://github.com/terascope/teraslice/tree/master/packages/job-components#readme",
"bugs": {
Expand Down Expand Up @@ -36,6 +36,7 @@
"convict-format-with-moment": "^6.2.0",
"convict-format-with-validator": "^6.2.0",
"datemath-parser": "^1.0.6",
"prom-client": "^15.1.2",
"uuid": "^9.0.1"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/job-components/src/interfaces/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export interface FoundationApis {
getSystemEvents(): EventEmitter;
getConnection(config: ConnectionConfig): { client: any };
createClient(config: ConnectionConfig): Promise<{ client: any }>;
promMetrics: tf.PromMetrics
promMetrics: tf.PromMetrics;
}

export interface LegacyFoundationApis {
Expand Down
235 changes: 149 additions & 86 deletions packages/job-components/src/test-helpers.ts

Large diffs are not rendered by default.

31 changes: 20 additions & 11 deletions packages/job-components/test/test-helpers-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ describe('Test Helpers', () => {
const context = new TestContext('test-prom-metrics');
context.sysconfig.teraslice.cluster_manager_type = 'kubernetes';
const config = {
assignment: 'cluster-master',
assignment: 'master',
logger: debugLogger('test-helpers-spec-logger'),
tf_prom_metrics_enabled: true,
tf_prom_metrics_port: 3333,
Expand All @@ -203,20 +203,22 @@ describe('Test Helpers', () => {
});

it('should add, inc and delete counter', async () => {
await context.apis.foundation.promMetrics.addCounter('test_counter', 'test_counter help string', ['uuid'], function collect() {
this.inc();
await context.apis.foundation.promMetrics.addCounter('test_counter', 'test_counter help string', ['uuid', 'name', 'assignment'], function collect() {
this.inc({ uuid: 'e&vgv%56' }, 1);
});
context.apis.foundation.promMetrics.inc('test_counter', {}, 1);
context.apis.foundation.promMetrics.inc('test_counter', { uuid: 'e&vgv%56' }, 1);
expect(context.apis.foundation.promMetrics.hasMetric('test_counter')).toBe(true);
expect(await context.apis.foundation.promMetrics.deleteMetric('test_counter')).toBe(true);
});

it('should inc, dec, and set gauge', async () => {
await context.apis.foundation.promMetrics.addGauge('test_gauge', 'test_gauge help string', ['uuid']);
await context.apis.foundation.promMetrics.addGauge('test_gauge', 'help string', ['uuid', 'name', 'assignment']);
context.apis.foundation.promMetrics.set('test_gauge', { uuid: '437Ev89h' }, 10);
context.apis.foundation.promMetrics.inc('test_gauge', { uuid: '437Ev89h' }, 1);
context.apis.foundation.promMetrics.dec('test_gauge', { uuid: '437Ev89h' }, 2);
expect(context.mockPromMetrics?.test_gauge.labels['uuid:437Ev89h,'].value).toBe(9);
const metrics: string = await context.apis.scrapePromMetrics();
const sum = metrics.split('\n').filter((line) => line.includes('437Ev89h'))[0].split(' ')[1];
expect(sum).toBe('9');
});

it('should throw if inc called on metric that doesn\'t exist', async () => {
Expand All @@ -234,20 +236,27 @@ describe('Test Helpers', () => {
.toThrow('Metric missing_test_gauge is not setup');
});
it('should add and observe summary', async () => {
await context.apis.foundation.promMetrics.addSummary('test_summary', 'test_summary help string', ['uuid']);
await context.apis.foundation.promMetrics.addSummary('test_summary', 'test_summary help string', ['uuid', 'name', 'assignment']);
context.apis.foundation.promMetrics.observe('test_summary', { uuid: '34rhEqrX' }, 12);
context.apis.foundation.promMetrics.observe('test_summary', { uuid: '34rhEqrX' }, 5);
context.apis.foundation.promMetrics.observe('test_summary', { uuid: '34rhEqrX' }, 18);
expect(context.mockPromMetrics?.test_summary?.labels['uuid:34rhEqrX,']).toEqual({ sum: 35, count: 3, value: 0 });
const metrics: string = await context.apis.scrapePromMetrics();
const sum = metrics.split('\n').filter((line) => line.includes('test_summary_sum'))[0].split(' ')[1];
const count = metrics.split('\n').filter((line) => line.includes('test_summary_count'))[0].split(' ')[1];
expect(sum).toBe('35');
expect(count).toBe('3');
});

it('should add and observe histogram', async () => {
await context.apis.foundation.promMetrics.addHistogram('test_histogram', 'test_histogram help string', ['uuid']);
await context.apis.foundation.promMetrics.addHistogram('test_histogram', 'test_histogram help string', ['uuid', 'name', 'assignment']);
context.apis.foundation.promMetrics.observe('test_histogram', { uuid: 'dEF4Kby6' }, 10);
context.apis.foundation.promMetrics.observe('test_histogram', { uuid: 'dEF4Kby6' }, 30);
context.apis.foundation.promMetrics.observe('test_histogram', { uuid: 'dEF4Kby6' }, 2);
expect(context.mockPromMetrics?.test_histogram?.labels['uuid:dEF4Kby6,'])
.toEqual({ sum: 42, count: 3, value: 0 });
const metrics: string = await context.apis.scrapePromMetrics();
const sum = metrics.split('\n').filter((line) => line.includes('test_histogram_sum'))[0].split(' ')[1];
const count = metrics.split('\n').filter((line) => line.includes('test_histogram_count'))[0].split(' ')[1];
expect(sum).toBe('42');
expect(count).toBe('3');
});

it('should throw if observe called on metric that doesn\'t exist', async () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/terafoundation/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "terafoundation",
"displayName": "Terafoundation",
"version": "0.63.1",
"version": "0.63.2",
"description": "A Clustering and Foundation tool for Terascope Tools",
"homepage": "https://github.com/terascope/teraslice/tree/master/packages/terafoundation#readme",
"bugs": {
Expand Down
12 changes: 6 additions & 6 deletions packages/terafoundation/test/apis/prom-metrics-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ describe('promMetrics foundation API', () => {
tf_prom_metrics_port: terafoundation.prom_metrics_port,
tf_prom_metrics_add_default: terafoundation.prom_metrics_add_default,
logger: debugLogger('prom-metrics-spec-logger'),
assignment: 'cluster-master',
assignment: 'master',
labels: {},
prefix: 'foundation_test_'
};
Expand Down Expand Up @@ -372,7 +372,7 @@ describe('promMetrics foundation API', () => {
tf_prom_metrics_port: terafoundation.prom_metrics_port,
tf_prom_metrics_add_default: terafoundation.prom_metrics_add_default,
logger: debugLogger('prom-metrics-spec-logger'),
assignment: 'cluster-master',
assignment: 'master',
labels: {},
prefix: 'foundation_test_'
};
Expand Down Expand Up @@ -466,7 +466,7 @@ describe('promMetrics foundation API', () => {
tf_prom_metrics_port: terafoundation.prom_metrics_port,
tf_prom_metrics_add_default: terafoundation.prom_metrics_add_default,
logger: debugLogger('prom-metrics-spec-logger'),
assignment: 'cluster-master',
assignment: 'master',
prefix: 'foundation_test_'
};

Expand Down Expand Up @@ -546,7 +546,7 @@ describe('promMetrics foundation API', () => {
tf_prom_metrics_port: terafoundation.prom_metrics_port,
tf_prom_metrics_add_default: terafoundation.prom_metrics_add_default,
logger: debugLogger('prom-metrics-spec-logger'),
assignment: 'cluster-master',
assignment: 'master',
prefix: 'foundation_test_'
};
beforeAll(async () => {
Expand Down Expand Up @@ -625,7 +625,7 @@ describe('promMetrics foundation API', () => {
tf_prom_metrics_port: terafoundation.prom_metrics_port,
tf_prom_metrics_add_default: terafoundation.prom_metrics_add_default,
logger: debugLogger('prom-metrics-spec-logger'),
assignment: 'cluster-master',
assignment: 'master',
prefix: 'foundation_test_',
labels: { default1: 'value1' }
};
Expand All @@ -642,7 +642,7 @@ describe('promMetrics foundation API', () => {
it('should get all the default labels', () => {
expect(context.apis.foundation.promMetrics.getDefaultLabels()).toEqual({
name: 'tera-test-labels',
assignment: 'cluster-master',
assignment: 'master',
default1: 'value1'
});
});
Expand Down
2 changes: 1 addition & 1 deletion packages/terafoundation/test/test-context-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ describe('TestContext', () => {
tf_prom_metrics_port: 3333,
tf_prom_metrics_add_default: false,
logger: context.logger,
assignment: 'cluster-master'
assignment: 'master'
};
expect(await context.apis.foundation.promMetrics.init(config)).toBe(true);
});
Expand Down
4 changes: 2 additions & 2 deletions packages/teraslice-op-test-harness/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@
"bluebird": "^3.7.2"
},
"devDependencies": {
"@terascope/job-components": "^0.74.1"
"@terascope/job-components": "^0.74.2"
},
"peerDependencies": {
"@terascope/job-components": ">=0.74.1"
"@terascope/job-components": ">=0.74.2"
},
"engines": {
"node": ">=14.17.0",
Expand Down
4 changes: 2 additions & 2 deletions packages/teraslice-test-harness/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@
"fs-extra": "^11.2.0"
},
"devDependencies": {
"@terascope/job-components": "^0.74.1"
"@terascope/job-components": "^0.74.2"
},
"peerDependencies": {
"@terascope/job-components": ">=0.74.1"
"@terascope/job-components": ">=0.74.2"
},
"engines": {
"node": ">=14.17.0",
Expand Down
6 changes: 3 additions & 3 deletions packages/teraslice/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "teraslice",
"displayName": "Teraslice",
"version": "1.5.1",
"version": "1.5.2",
"description": "Distributed computing platform for processing JSON data",
"homepage": "https://github.com/terascope/teraslice#readme",
"bugs": {
Expand Down Expand Up @@ -39,7 +39,7 @@
},
"dependencies": {
"@terascope/elasticsearch-api": "^3.20.1",
"@terascope/job-components": "^0.74.1",
"@terascope/job-components": "^0.74.2",
"@terascope/teraslice-messaging": "^0.42.1",
"@terascope/types": "^0.17.1",
"@terascope/utils": "^0.59.1",
Expand All @@ -64,7 +64,7 @@
"semver": "^7.6.1",
"socket.io": "^1.7.4",
"socket.io-client": "^1.7.4",
"terafoundation": "^0.63.1",
"terafoundation": "^0.63.2",
"uuid": "^9.0.1"
},
"devDependencies": {
Expand Down
7 changes: 4 additions & 3 deletions packages/teraslice/src/lib/cluster/cluster_master.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@ export class ClusterMaster {
tf_prom_metrics_enabled: terafoundation.prom_metrics_enabled,
tf_prom_metrics_port: terafoundation.prom_metrics_port,
logger: this.logger,
assignment: 'cluster_master'
assignment: 'master',
prefix: 'teraslice_'
});

await this.setupPromMetrics();
Expand Down Expand Up @@ -229,7 +230,7 @@ export class ClusterMaster {
*/
await Promise.all([
this.context.apis.foundation.promMetrics.addGauge(
'info',
'master_info',
'Information about Teraslice cluster master',
['arch', 'clustering_type', 'name', 'node_version', 'platform', 'teraslice_version']
),
Expand Down Expand Up @@ -338,7 +339,7 @@ export class ClusterMaster {
]);

this.context.apis.foundation.promMetrics.set(
'info',
'master_info',
{
arch: this.context.arch,
clustering_type: this.context.sysconfig.teraslice.cluster_manager_type,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1113,9 +1113,7 @@ export class ExecutionController {
* @link https://terascope.github.io/teraslice/docs/development/k8s#prometheus-metrics-api
*/
async setupPromMetrics() {
this.logger.info(`adding ${this.context.assignment} prom metrics...`);
// eslint-disable-next-line @typescript-eslint/no-this-alias
const self = this;
const { context, executionAnalytics } = this;
await Promise.all([
this.context.apis.foundation.promMetrics.addGauge(
'info',
Expand All @@ -1127,9 +1125,9 @@ export class ExecutionController {
'Number of slices processed by all workers',
[],
function collect() {
const slicesProcessed = self.executionAnalytics.get('processed');
const slicesProcessed = executionAnalytics.get('processed');
const defaultLabels = {
...self.context.apis.foundation.promMetrics.getDefaultLabels()
...context.apis.foundation.promMetrics.getDefaultLabels()
};
this.set(defaultLabels, slicesProcessed);
}
Expand Down
7 changes: 3 additions & 4 deletions packages/teraslice/src/lib/workers/worker/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -411,8 +411,7 @@ export class Worker {
*/
async setupPromMetrics() {
this.logger.info(`adding ${this.context.assignment} prom metrics...`);
// eslint-disable-next-line @typescript-eslint/no-this-alias
const self = this;
const { context, getSlicesProcessed } = this;
await Promise.all([
this.context.apis.foundation.promMetrics.addGauge(
'info',
Expand All @@ -424,9 +423,9 @@ export class Worker {
'Number of slices the worker has processed',
[],
function collect() {
const slicesProcessed = self.getSlicesProcessed();
const slicesProcessed = getSlicesProcessed();
const defaultLabels = {
...self.context.apis.foundation.promMetrics.getDefaultLabels()
...context.apis.foundation.promMetrics.getDefaultLabels()
};
this.set(defaultLabels, slicesProcessed);
}
Expand Down

0 comments on commit d79ff05

Please sign in to comment.