Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adding new metric: up down sum observer #1272

Merged
merged 17 commits into from
Jul 10, 2020
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion examples/metrics/metrics/observer.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ const meter = new MeterProvider({

meter.createValueObserver('cpu_core_usage', {
description: 'Example of a sync value observer with callback',
}, (observerResult) => { // this callback is called once per each interval
}, async (observerResult) => { // this callback is called once per each interval
await new Promise((resolve) => {
setTimeout(()=> {resolve()}, 50);
});
observerResult.observe(getRandomValue(), { core: '1' });
observerResult.observe(getRandomValue(), { core: '2' });
});
Expand Down
5 changes: 4 additions & 1 deletion packages/opentelemetry-api/src/metrics/Metric.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,12 @@ export interface BaseObserver extends UnboundMetric<BoundBaseObserver> {
};
}

/** Base interface for the Value Observer metrics. */
/** Base interface for the ValueObserver metrics. */
export type ValueObserver = BaseObserver;

/** Base interface for the UpDownSumObserver metrics. */
export type UpDownSumObserver = BaseObserver;

/** Base interface for the Batch Observer metrics. */
export type BatchObserver = Metric;

Expand Down
3 changes: 3 additions & 0 deletions packages/opentelemetry-api/src/metrics/NoopMeter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,4 +202,7 @@ export const NOOP_BOUND_BASE_OBSERVER = new NoopBoundBaseObserver();
export const NOOP_VALUE_OBSERVER_METRIC = new NoopBaseObserverMetric(
NOOP_BOUND_BASE_OBSERVER
);
export const NOOP_UP_DOWN_SUM_OBSERVER_METRIC = new NoopBaseObserverMetric(
NOOP_BOUND_BASE_OBSERVER
);
export const NOOP_BATCH_OBSERVER_METRIC = new NoopBatchObserverMetric();
67 changes: 62 additions & 5 deletions packages/opentelemetry-metrics/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,18 +76,75 @@ boundCounter.add(Math.random() > 0.5 ? 1 : -1);

### Value Observer

Choose this kind of metric when only last value is important without worry about aggregation
Choose this kind of metric when only last value is important without worry about aggregation.
The callback can be sync or async.

```js
const { MeterProvider } = require('@opentelemetry/metrics');

const meter = new MeterProvider().getMeter('your-meter-name');

meter.createValueObserver('cpu_core_usage', {
description: 'Example of a sync observer with callback',

// async callback - for operation that needs to wait for value
meter.createValueObserver('your_metric_name', {
description: 'Example of a async observer with callback',
obecny marked this conversation as resolved.
Show resolved Hide resolved
}, async (observerResult) => {
const value = await getAsyncValue();
observerResult.observe(value, { label: '1' });
obecny marked this conversation as resolved.
Show resolved Hide resolved
});

function getAsyncValue() {
return new Promise((resolve) => {
setTimeout(()=> {
resolve(Math.random());
}, 100);
});
}

// sync callback in case you don't need to wait for value
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍
Great to provide both examples.

meter.createValueObserver('your_metric_name', {
description: 'Example of a async observer with callback',
}, (observerResult) => {
observerResult.observe(getRandomValue(), { label: '1' });
observerResult.observe(getRandomValue(), { label: '2' });
});

function getRandomValue() {
return Math.random();
}
```

### UpDownSumObserver

Choose this kind of metric when sum is important and you want to capture any value that starts at zero and rises or falls throughout the process lifetime.
The callback can be sync or async.

```js
const { MeterProvider } = require('@opentelemetry/metrics');

const meter = new MeterProvider().getMeter('your-meter-name');

// async callback - for operation that needs to wait for value
naseemkullah marked this conversation as resolved.
Show resolved Hide resolved
meter.createUpDownSumObserver('your_metric_name', {
description: 'Example of an async observer with callback',
}, async (observerResult) => {
const value = await getAsyncValue();
observerResult.observe(value, { label: '1' });
obecny marked this conversation as resolved.
Show resolved Hide resolved
});

function getAsyncValue() {
return new Promise((resolve) => {
setTimeout(()=> {
resolve(Math.random());
}, 100);
});
}

// sync callback in case you don't need to wait for value
meter.createUpDownSumObserver('your_metric_name', {
description: 'Example of an async observer with callback',
}, (observerResult) => {
observerResult.observe(getRandomValue(), { core: '1' });
observerResult.observe(getRandomValue(), { core: '2' });
observerResult.observe(getRandomValue(), { label: '1' });
});

function getRandomValue() {
Expand Down
8 changes: 4 additions & 4 deletions packages/opentelemetry-metrics/src/BaseObserverMetric.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const NOOP_CALLBACK = () => {};
*/
export abstract class BaseObserverMetric extends Metric<BoundObserver>
implements api.BaseObserver {
protected _callback: (observerResult: api.ObserverResult) => void;
protected _callback: (observerResult: api.ObserverResult) => unknown;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure why you changed the void to a unknown ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because this might or not return something


constructor(
name: string,
Expand All @@ -39,7 +39,7 @@ export abstract class BaseObserverMetric extends Metric<BoundObserver>
resource: Resource,
metricKind: MetricKind,
instrumentationLibrary: InstrumentationLibrary,
callback?: (observerResult: api.ObserverResult) => void
callback?: (observerResult: api.ObserverResult) => unknown
) {
super(name, options, metricKind, resource, instrumentationLibrary);
this._callback = callback || NOOP_CALLBACK;
Expand All @@ -55,9 +55,9 @@ export abstract class BaseObserverMetric extends Metric<BoundObserver>
);
}

getMetricRecord(): Promise<MetricRecord[]> {
async getMetricRecord(): Promise<MetricRecord[]> {
const observerResult = new ObserverResult();
this._callback(observerResult);
await this._callback(observerResult);
observerResult.values.forEach((value, labels) => {
const instrument = this.bind(labels);
instrument.update(value);
Expand Down
39 changes: 37 additions & 2 deletions packages/opentelemetry-metrics/src/Meter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { BaseBoundInstrument } from './BoundInstrument';
import { UpDownCounterMetric } from './UpDownCounterMetric';
import { CounterMetric } from './CounterMetric';
import { MetricRecord } from './export/types';
import { UpDownSumObserverMetric } from './UpDownSumObserverMetric';
import { ValueRecorderMetric } from './ValueRecorderMetric';
import { Metric } from './Metric';
import { ValueObserverMetric } from './ValueObserverMetric';
Expand Down Expand Up @@ -157,15 +158,15 @@ export class Meter implements api.Meter {
}

/**
* Creates a new value observer metric.
* Creates a new `ValueObserver` metric.
* @param name the name of the metric.
* @param [options] the metric options.
* @param [callback] the value observer callback
*/
createValueObserver(
name: string,
options: api.MetricOptions = {},
callback?: (observerResult: api.ObserverResult) => void
callback?: (observerResult: api.ObserverResult) => unknown
): api.ValueObserver {
if (!this._isValidName(name)) {
this._logger.warn(
Expand All @@ -190,6 +191,40 @@ export class Meter implements api.Meter {
return valueObserver;
}

/**
* Creates a new `UpDownSumObserver` metric.
* @param name the name of the metric.
* @param [options] the metric options.
* @param [callback] the value observer callback
*/
createUpDownSumObserver(
name: string,
options: api.MetricOptions = {},
callback?: (observerResult: api.ObserverResult) => unknown
): api.ValueObserver {
obecny marked this conversation as resolved.
Show resolved Hide resolved
if (!this._isValidName(name)) {
obecny marked this conversation as resolved.
Show resolved Hide resolved
this._logger.warn(
`Invalid metric name ${name}. Defaulting to noop metric implementation.`
);
return api.NOOP_UP_DOWN_SUM_OBSERVER_METRIC;
}
const opt: api.MetricOptions = {
logger: this._logger,
...DEFAULT_METRIC_OPTIONS,
...options,
};
const upDownSumObserver = new UpDownSumObserverMetric(
name,
opt,
this._batcher,
this._resource,
this._instrumentationLibrary,
callback
);
this._registerMetric(name, upDownSumObserver);
return upDownSumObserver;
}

/**
* Creates a new batch observer metric.
* @param name the name of the metric.
Expand Down
45 changes: 45 additions & 0 deletions packages/opentelemetry-metrics/src/UpDownSumObserverMetric.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import * as api from '@opentelemetry/api';
import { InstrumentationLibrary } from '@opentelemetry/core';
import { Resource } from '@opentelemetry/resources';
import { BaseObserverMetric } from './BaseObserverMetric';
import { Batcher } from './export/Batcher';
import { MetricKind } from './export/types';

/** This is a SDK implementation of UpDownSumObserver Metric. */
export class UpDownSumObserverMetric extends BaseObserverMetric
implements api.UpDownSumObserver {
constructor(
name: string,
options: api.MetricOptions,
batcher: Batcher,
resource: Resource,
instrumentationLibrary: InstrumentationLibrary,
callback?: (observerResult: api.ObserverResult) => unknown
) {
super(
name,
options,
batcher,
resource,
MetricKind.UP_DOWN_SUM_OBSERVER,
instrumentationLibrary,
callback
);
}
}
2 changes: 1 addition & 1 deletion packages/opentelemetry-metrics/src/ValueObserverMetric.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export class ValueObserverMetric extends BaseObserverMetric
batcher: Batcher,
resource: Resource,
instrumentationLibrary: InstrumentationLibrary,
callback?: (observerResult: api.ObserverResult) => void
callback?: (observerResult: api.ObserverResult) => unknown
) {
super(
name,
Expand Down
Loading