Skip to content

Commit f3962ff

Browse files
committed
feat: add support overriding nodejs buckets using .spec.nodejs.histogramBuckets
1 parent 4e2c5fd commit f3962ff

File tree

5 files changed

+94
-2
lines changed

5 files changed

+94
-2
lines changed

apis/v1alpha1/instrumentation_types.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,15 @@ type NodeJS struct {
217217
// Resources describes the compute resource requirements.
218218
// +optional
219219
Resources corev1.ResourceRequirements `json:"resourceRequirements,omitempty"`
220+
221+
// HistogramBuckets defines the histogram buckets for metrics generated by the NodeJS SDK.
222+
// +optional
223+
HistogramBuckets []HistogramBucketsItem `json:"histogramBuckets,omitempty"`
224+
}
225+
226+
type HistogramBucketsItem struct {
227+
Name string `json:"instrumentName"`
228+
Buckets []float64 `json:"buckets"`
220229
}
221230

222231
// Python defines Python SDK and instrumentation configuration.

apis/v1alpha1/zz_generated.deepcopy.go

Lines changed: 27 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

autoinstrumentation/nodejs/src/autoinstrumentation.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { OTLPTraceExporter as OTLPHttpTraceExporter } from '@opentelemetry/expor
44
import { OTLPTraceExporter as OTLPGrpcTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc';
55
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-grpc';
66
import { PrometheusExporter } from '@opentelemetry/exporter-prometheus';
7-
import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
7+
import { ExplicitBucketHistogramAggregation, PeriodicExportingMetricReader, View } from "@opentelemetry/sdk-metrics";
88
import { alibabaCloudEcsDetector } from '@opentelemetry/resource-detector-alibaba-cloud';
99
import { awsEc2Detector, awsEksDetector } from '@opentelemetry/resource-detector-aws';
1010
import { containerDetector } from '@opentelemetry/resource-detector-container';
@@ -50,11 +50,39 @@ function getMetricReader() {
5050
}
5151
}
5252

53+
function getViews() {
54+
const histogramBuckets = process.env.OTEL_OPERATOR_NODEJS_HISTOGRAM_BUCKETS;
55+
if (histogramBuckets) {
56+
try {
57+
let views = [];
58+
for (const viewCfg of JSON.parse(histogramBuckets)) {
59+
views.push(
60+
new View({
61+
instrumentName: viewCfg["instrumentName"],
62+
aggregation: new ExplicitBucketHistogramAggregation(
63+
viewCfg["buckets"],
64+
),
65+
}),
66+
);
67+
}
68+
return views;
69+
} catch (error) {
70+
diag.error(
71+
"Failed to parse OTEL_OPERATOR_NODEJS_HISTOGRAM_BUCKETS:",
72+
error,
73+
);
74+
}
75+
return [];
76+
}
77+
return [];
78+
}
79+
5380
const sdk = new NodeSDK({
5481
autoDetectResources: true,
5582
instrumentations: [getNodeAutoInstrumentations()],
5683
traceExporter: getTraceExporter(),
5784
metricReader: getMetricReader(),
85+
views: getViews(),
5886
resourceDetectors:
5987
[
6088
// Standard resource detectors.
@@ -75,3 +103,4 @@ const sdk = new NodeSDK({
75103
});
76104

77105
sdk.start();
106+

config/crd/bases/opentelemetry.io_instrumentations.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1393,6 +1393,17 @@ spec:
13931393
type: object
13941394
nodejs:
13951395
properties:
1396+
histogramBuckets:
1397+
type: array
1398+
items:
1399+
type: object
1400+
properties:
1401+
instrumentName:
1402+
type: string
1403+
buckets:
1404+
type: array
1405+
items:
1406+
type: number
13961407
env:
13971408
items:
13981409
properties:

pkg/instrumentation/nodejs.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ package instrumentation
1616

1717
import (
1818
corev1 "k8s.io/api/core/v1"
19-
19+
"encoding/json"
2020
"github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1"
2121
)
2222

@@ -26,9 +26,25 @@ const (
2626
nodejsInitContainerName = initContainerName + "-nodejs"
2727
nodejsVolumeName = volumeName + "-nodejs"
2828
nodejsInstrMountPath = "/otel-auto-instrumentation-nodejs"
29+
histogramBucketsEnvVarName = "OTEL_OPERATOR_NODEJS_HISTOGRAM_BUCKETS"
2930
)
3031

3132
func injectNodeJSSDK(nodeJSSpec v1alpha1.NodeJS, pod corev1.Pod, index int) (corev1.Pod, error) {
33+
if len(nodeJSSpec.HistogramBuckets) > 0 {
34+
bucketsJSON, err := json.Marshal(nodeJSSpec.HistogramBuckets)
35+
if err != nil {
36+
// handle error, possibly log and skip injection for this resource
37+
return pod, err
38+
}
39+
40+
// Inject as an environment variable in the pod
41+
bucketsJSONEnvVar := corev1.EnvVar{
42+
Name: histogramBucketsEnvVarName,
43+
Value: string(bucketsJSON),
44+
}
45+
nodeJSSpec.Env = append(nodeJSSpec.Env, bucketsJSONEnvVar)
46+
}
47+
3248
volume := instrVolume(nodeJSSpec.VolumeClaimTemplate, nodejsVolumeName, nodeJSSpec.VolumeSizeLimit)
3349

3450
// caller checks if there is at least one container.

0 commit comments

Comments
 (0)