mirror of
https://github.com/OneUptime/oneuptime
synced 2024-11-21 22:59:07 +00:00
refactor: Update Telemetry class to add gauge and histogram metrics
This code change updates the Telemetry class in the CommonServer/Utils directory to include methods for creating gauge and histogram metrics. The getGauge and getHistogram methods are added, allowing for the creation of observable gauges and histograms with specified names and descriptions. This change enhances the telemetry capabilities of the application by providing more options for metric tracking and analysis.
This commit is contained in:
parent
47bf8f9c89
commit
77f1262ff5
@ -45,6 +45,16 @@ export default class StatusAPI {
|
||||
description: 'Live check counter',
|
||||
});
|
||||
|
||||
public static statusGuage = Telemetry.getGauge({
|
||||
name: 'status.guage',
|
||||
description: 'Status guage',
|
||||
});
|
||||
|
||||
public static stausHistogram = Telemetry.getHistogram({
|
||||
name: 'status.histogram',
|
||||
description: 'Status histogram',
|
||||
});
|
||||
|
||||
public static init(options: StatusAPIOptions): ExpressRouter {
|
||||
const router: ExpressRouter = Express.getRouter();
|
||||
|
||||
@ -59,6 +69,14 @@ export default class StatusAPI {
|
||||
router.get('/status', (req: ExpressRequest, res: ExpressResponse) => {
|
||||
this.statusCheckSuccessCounter.add(1);
|
||||
|
||||
this.statusGuage.addCallback((observableResult)=>{
|
||||
console.log(observableResult);
|
||||
observableResult.observe(1.354);
|
||||
});
|
||||
|
||||
|
||||
this.stausHistogram.record(1.354);
|
||||
|
||||
logger.info('Status check: ok');
|
||||
|
||||
Response.sendJsonObjectResponse(req, res, {
|
||||
|
@ -2,7 +2,9 @@ import OpenTelemetryAPI, { Meter } from '@opentelemetry/api';
|
||||
import { Logger, logs } from '@opentelemetry/api-logs';
|
||||
import {
|
||||
Counter,
|
||||
Histogram,
|
||||
MetricOptions,
|
||||
ObservableGauge,
|
||||
} from '@opentelemetry/api/build/src/metrics/Metric';
|
||||
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
|
||||
import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';
|
||||
@ -232,6 +234,52 @@ export default class Telemetry {
|
||||
|
||||
return counter;
|
||||
}
|
||||
|
||||
// guage
|
||||
|
||||
public static getGauge(data: {
|
||||
name: string;
|
||||
description: string;
|
||||
unit?: string;
|
||||
}): ObservableGauge {
|
||||
const { name, description } = data;
|
||||
|
||||
const metricOptions: MetricOptions = {
|
||||
description: description,
|
||||
};
|
||||
|
||||
if (data.unit) {
|
||||
metricOptions.unit = data.unit;
|
||||
}
|
||||
|
||||
const guage: ObservableGauge<opentelemetry.api.Attributes> =
|
||||
this.getMeter().createObservableGauge(name, metricOptions);
|
||||
|
||||
return guage;
|
||||
}
|
||||
|
||||
// histogram
|
||||
|
||||
public static getHistogram(data: {
|
||||
name: string;
|
||||
description: string;
|
||||
unit?: string;
|
||||
}): Histogram {
|
||||
const { name, description } = data;
|
||||
|
||||
const metricOptions: MetricOptions = {
|
||||
description: description,
|
||||
};
|
||||
|
||||
if (data.unit) {
|
||||
metricOptions.unit = data.unit;
|
||||
}
|
||||
|
||||
const histogram: Histogram<opentelemetry.api.Attributes> =
|
||||
this.getMeter().createHistogram(name, metricOptions);
|
||||
|
||||
return histogram;
|
||||
}
|
||||
}
|
||||
|
||||
Telemetry.init({
|
||||
|
@ -19,7 +19,7 @@ import Express, {
|
||||
import logger from 'CommonServer/Utils/Logger';
|
||||
import Response from 'CommonServer/Utils/Response';
|
||||
import Log, { LogSeverity } from 'Model/AnalyticsModels/Log';
|
||||
import Metric, { MetricPointType } from 'Model/AnalyticsModels/Metric';
|
||||
import Metric, { AggregationTemporality, MetricPointType } from 'Model/AnalyticsModels/Metric';
|
||||
import Span, { SpanKind, SpanStatus } from 'Model/AnalyticsModels/Span';
|
||||
import protobuf from 'protobufjs';
|
||||
|
||||
@ -134,18 +134,18 @@ router.post(
|
||||
if (
|
||||
resourceSpan['resource'] &&
|
||||
(resourceSpan['resource'] as JSONObject)[
|
||||
'attributes'
|
||||
'attributes'
|
||||
] &&
|
||||
(
|
||||
(resourceSpan['resource'] as JSONObject)[
|
||||
'attributes'
|
||||
'attributes'
|
||||
] as JSONArray
|
||||
).length > 0
|
||||
) {
|
||||
attributesObject['resource'] =
|
||||
OTelIngestService.getAttributes(
|
||||
(resourceSpan['resource'] as JSONObject)[
|
||||
'attributes'
|
||||
'attributes'
|
||||
] as JSONArray
|
||||
);
|
||||
}
|
||||
@ -193,7 +193,7 @@ router.post(
|
||||
span['status'] &&
|
||||
(span['status'] as JSONObject)?.['code'] &&
|
||||
typeof (span['status'] as JSONObject)?.['code'] ===
|
||||
'number'
|
||||
'number'
|
||||
) {
|
||||
spanStatusCode = (span['status'] as JSONObject)?.[
|
||||
'code'
|
||||
@ -204,7 +204,7 @@ router.post(
|
||||
span['status'] &&
|
||||
(span['status'] as JSONObject)?.['code'] &&
|
||||
typeof (span['status'] as JSONObject)?.['code'] ===
|
||||
'string'
|
||||
'string'
|
||||
) {
|
||||
if (
|
||||
(span['status'] as JSONObject)?.['code'] ===
|
||||
@ -388,14 +388,14 @@ router.post(
|
||||
if (
|
||||
resourceMetric['resource'] &&
|
||||
(resourceMetric['resource'] as JSONObject)[
|
||||
'attributes'
|
||||
'attributes'
|
||||
] &&
|
||||
((resourceMetric['resource'] as JSONObject)[
|
||||
'attributes'
|
||||
] as JSONArray) instanceof Array &&
|
||||
(
|
||||
(resourceMetric['resource'] as JSONObject)[
|
||||
'attributes'
|
||||
'attributes'
|
||||
] as JSONArray
|
||||
).length > 0
|
||||
) {
|
||||
@ -403,7 +403,7 @@ router.post(
|
||||
...attributesObject,
|
||||
resource: OTelIngestService.getAttributes(
|
||||
(resourceMetric['resource'] as JSONObject)[
|
||||
'attributes'
|
||||
'attributes'
|
||||
] as JSONArray
|
||||
),
|
||||
};
|
||||
@ -428,7 +428,7 @@ router.post(
|
||||
(metric['sum'] as JSONObject)['dataPoints'] &&
|
||||
(
|
||||
(metric['sum'] as JSONObject)[
|
||||
'dataPoints'
|
||||
'dataPoints'
|
||||
] as JSONArray
|
||||
).length > 0
|
||||
) {
|
||||
@ -436,10 +436,12 @@ router.post(
|
||||
metric['sum'] as JSONObject
|
||||
)['dataPoints'] as JSONArray) {
|
||||
const sumMetric: Metric =
|
||||
OTelIngestService.getMetricFromDatapoint(
|
||||
dbMetric,
|
||||
datapoint
|
||||
);
|
||||
OTelIngestService.getMetricFromDatapoint({
|
||||
dbMetric: dbMetric,
|
||||
datapoint: datapoint,
|
||||
aggregationTemporality: (metric['sum'] as JSONObject)['aggregationTemporality'] as AggregationTemporality,
|
||||
isMonotonic: (metric['sum'] as JSONObject)['isMonotonic'] as boolean | undefined
|
||||
});
|
||||
|
||||
sumMetric.metricPointType = MetricPointType.Sum;
|
||||
|
||||
@ -450,7 +452,7 @@ router.post(
|
||||
(metric['gauge'] as JSONObject)['dataPoints'] &&
|
||||
(
|
||||
(metric['gauge'] as JSONObject)[
|
||||
'dataPoints'
|
||||
'dataPoints'
|
||||
] as JSONArray
|
||||
).length > 0
|
||||
) {
|
||||
@ -458,10 +460,12 @@ router.post(
|
||||
metric['gauge'] as JSONObject
|
||||
)['dataPoints'] as JSONArray) {
|
||||
const guageMetric: Metric =
|
||||
OTelIngestService.getMetricFromDatapoint(
|
||||
dbMetric,
|
||||
datapoint
|
||||
);
|
||||
OTelIngestService.getMetricFromDatapoint({
|
||||
dbMetric: dbMetric,
|
||||
datapoint: datapoint,
|
||||
aggregationTemporality: (metric['gauge'] as JSONObject)['aggregationTemporality'] as AggregationTemporality,
|
||||
isMonotonic: (metric['gauge'] as JSONObject)['isMonotonic'] as boolean | undefined
|
||||
});
|
||||
|
||||
guageMetric.metricPointType =
|
||||
MetricPointType.Gauge;
|
||||
@ -473,7 +477,7 @@ router.post(
|
||||
(metric['histogram'] as JSONObject)['dataPoints'] &&
|
||||
(
|
||||
(metric['histogram'] as JSONObject)[
|
||||
'dataPoints'
|
||||
'dataPoints'
|
||||
] as JSONArray
|
||||
).length > 0
|
||||
) {
|
||||
@ -481,10 +485,12 @@ router.post(
|
||||
metric['histogram'] as JSONObject
|
||||
)['dataPoints'] as JSONArray) {
|
||||
const histogramMetric: Metric =
|
||||
OTelIngestService.getMetricFromDatapoint(
|
||||
dbMetric,
|
||||
datapoint
|
||||
);
|
||||
OTelIngestService.getMetricFromDatapoint({
|
||||
dbMetric: dbMetric,
|
||||
datapoint: datapoint,
|
||||
aggregationTemporality: (metric['histogram'] as JSONObject)['aggregationTemporality'] as AggregationTemporality,
|
||||
isMonotonic: (metric['histogram'] as JSONObject)['isMonotonic'] as boolean | undefined
|
||||
});
|
||||
|
||||
histogramMetric.metricPointType =
|
||||
MetricPointType.Histogram;
|
||||
@ -576,11 +582,11 @@ router.post(
|
||||
if (
|
||||
resourceLog['resource'] &&
|
||||
(resourceLog['resource'] as JSONObject)[
|
||||
'attributes'
|
||||
'attributes'
|
||||
] &&
|
||||
(
|
||||
(resourceLog['resource'] as JSONObject)[
|
||||
'attributes'
|
||||
'attributes'
|
||||
] as JSONArray
|
||||
).length > 0
|
||||
) {
|
||||
@ -588,7 +594,7 @@ router.post(
|
||||
...attributesObject,
|
||||
resource: OTelIngestService.getAttributes(
|
||||
(resourceLog['resource'] as JSONObject)[
|
||||
'attributes'
|
||||
'attributes'
|
||||
] as JSONArray
|
||||
),
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
import OneUptimeDate from 'Common/Types/Date';
|
||||
import { JSONArray, JSONObject, JSONValue } from 'Common/Types/JSON';
|
||||
import JSONFunctions from 'Common/Types/JSONFunctions';
|
||||
import Metric from 'Model/AnalyticsModels/Metric';
|
||||
import Metric, { AggregationTemporality } from 'Model/AnalyticsModels/Metric';
|
||||
|
||||
export default class OTelIngestService {
|
||||
public static getAttributes(items: JSONArray): JSONObject {
|
||||
@ -28,10 +28,16 @@ export default class OTelIngestService {
|
||||
return JSONFunctions.flattenObject(finalObj);
|
||||
}
|
||||
|
||||
public static getMetricFromDatapoint(
|
||||
public static getMetricFromDatapoint(data: {
|
||||
dbMetric: Metric,
|
||||
datapoint: JSONObject
|
||||
datapoint: JSONObject,
|
||||
aggregationTemporality: AggregationTemporality,
|
||||
isMonotonic: boolean | undefined
|
||||
}
|
||||
): Metric {
|
||||
|
||||
const { dbMetric, datapoint, aggregationTemporality, isMonotonic } = data;
|
||||
|
||||
const newDbMetric: Metric = Metric.fromJSON(
|
||||
dbMetric.toJSON(),
|
||||
Metric
|
||||
@ -85,6 +91,17 @@ export default class OTelIngestService {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// aggregationTemporality
|
||||
|
||||
if (aggregationTemporality) {
|
||||
newDbMetric.aggregationTemporality = aggregationTemporality;
|
||||
}
|
||||
|
||||
if(isMonotonic !== undefined) {
|
||||
newDbMetric.isMonotonic = isMonotonic;
|
||||
}
|
||||
|
||||
return newDbMetric;
|
||||
}
|
||||
}
|
||||
|
@ -336,6 +336,30 @@ export default class Metric extends AnalyticsBaseModel {
|
||||
},
|
||||
}),
|
||||
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: 'isMonotonic',
|
||||
title: 'Is Monotonic',
|
||||
description: 'Is Monotonic',
|
||||
required: false,
|
||||
type: TableColumnType.Boolean,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: 'count',
|
||||
title: 'Count',
|
||||
@ -559,6 +583,14 @@ export default class Metric extends AnalyticsBaseModel {
|
||||
this.setColumnValue('unit', v);
|
||||
}
|
||||
|
||||
public get isMonotonic(): boolean | undefined {
|
||||
return this.getColumnValue('isMonotonic') as boolean | undefined;
|
||||
}
|
||||
|
||||
public set isMonotonic(v: boolean | undefined) {
|
||||
this.setColumnValue('isMonotonic', v);
|
||||
}
|
||||
|
||||
public set serviceId(v: ObjectID | undefined) {
|
||||
this.setColumnValue('serviceId', v);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user