From 85c4a95c65c36b3cf60a8c9f0b68f489ce3ee3b5 Mon Sep 17 00:00:00 2001 From: Angelo Di Paolo Date: Thu, 12 Dec 2024 09:20:21 -0800 Subject: [PATCH] Synchronize access race in HistogramMetric (#609) --- .../Metrics/HistogramMetricSdk.swift | 14 +++++++++----- .../OpenTelemetrySdk/Metrics/MeterSdk.swift | 18 +++++++++++------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/Sources/OpenTelemetrySdk/Metrics/HistogramMetricSdk.swift b/Sources/OpenTelemetrySdk/Metrics/HistogramMetricSdk.swift index 795ec44e..76e8a0c6 100644 --- a/Sources/OpenTelemetrySdk/Metrics/HistogramMetricSdk.swift +++ b/Sources/OpenTelemetrySdk/Metrics/HistogramMetricSdk.swift @@ -10,6 +10,7 @@ internal class HistogramMetricSdk: HistogramMetri public private(set) var boundInstruments = [LabelSet: BoundHistogramMetricSdkBase]() let metricName: String let explicitBoundaries: Array? + let bindUnbindLock = Lock() init(name: String, explicitBoundaries: Array? = nil) { metricName = name @@ -17,12 +18,15 @@ internal class HistogramMetricSdk: HistogramMetri } func bind(labelset: LabelSet) -> BoundHistogramMetric { - var boundInstrument = boundInstruments[labelset] - if boundInstrument == nil { - boundInstrument = createMetric() - boundInstruments[labelset] = boundInstrument! + bindUnbindLock.withLock { + var boundInstrument = boundInstruments[labelset] + if boundInstrument == nil { + boundInstrument = createMetric() + boundInstruments[labelset] = boundInstrument! + } + + return boundInstrument! } - return boundInstrument! } func bind(labels: [String: String]) -> BoundHistogramMetric { diff --git a/Sources/OpenTelemetrySdk/Metrics/MeterSdk.swift b/Sources/OpenTelemetrySdk/Metrics/MeterSdk.swift index 2d2d92d7..e75a54c1 100644 --- a/Sources/OpenTelemetrySdk/Metrics/MeterSdk.swift +++ b/Sources/OpenTelemetrySdk/Metrics/MeterSdk.swift @@ -195,14 +195,18 @@ class MeterSdk: Meter { let metricName = histogram.key let measureInstrument = histogram.value var metric = Metric(namespace: meterName, name: metricName, desc: meterName + metricName, type: AggregationType.doubleHistogram, resource: resource, instrumentationScopeInfo: instrumentationScopeInfo) - measureInstrument.boundInstruments.forEach { boundInstrument in - let labelSet = boundInstrument.key - let aggregator = boundInstrument.value.getAggregator() - aggregator.checkpoint() - var metricData = aggregator.toMetricData() - metricData.labels = labelSet.labels - metric.data.append(metricData) + + measureInstrument.bindUnbindLock.withLock { + measureInstrument.boundInstruments.forEach { boundInstrument in + let labelSet = boundInstrument.key + let aggregator = boundInstrument.value.getAggregator() + aggregator.checkpoint() + var metricData = aggregator.toMetricData() + metricData.labels = labelSet.labels + metric.data.append(metricData) + } } + metricProcessor.process(metric: metric) }