Skip to content

Commit

Permalink
initial implementation of actual conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
hughsimpson committed Aug 4, 2023
1 parent 391fcdf commit e07a3bb
Showing 1 changed file with 83 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,95 @@
*/
package kamon.otel

import io.opentelemetry.sdk.metrics.data.MetricData
import io.opentelemetry.sdk.common.InstrumentationScopeInfo
import io.opentelemetry.sdk.metrics.data._
import io.opentelemetry.sdk.metrics.internal.data._
import io.opentelemetry.sdk.resources.Resource
import kamon.metric.PeriodSnapshot
import kamon.metric.Instrument.Snapshot
import kamon.metric.{Distribution, MeasurementUnit, MetricSnapshot, PeriodSnapshot}
import kamon.tag.Lookups
import kamon.trace.Span.TagKeys

import java.lang.{Double => JDouble, Long => JLong}
import java.time.Instant
import java.util.{Collection => JCollection}
import scala.collection.JavaConverters._

class WithResourceMetricsConverter(resource: Resource, kamonVersion: String, from: Instant, to: Instant) {
private val fromNs = from.toEpochMilli * 1000000
private val toNs = to.toEpochMilli * 1000000

private def instrumentationScopeInfo(snapshot: MetricSnapshot[_, _]): InstrumentationScopeInfo = {
// logic for looking up the component doesn't really seem to make sense - to be compliant we should probably be grouping the metrics by component before calling this
InstrumentationScopeInfo.create(snapshot.instruments.headOption.flatMap(_.tags.get(Lookups.option(TagKeys.Component))) getOrElse "kamon-instrumentation", kamonVersion, null)
}

private def toString(unit: MeasurementUnit): String = unit.magnitude.name

def toGaugeDatum(g: Snapshot[Double]): DoublePointData = ImmutableDoublePointData.create(fromNs, toNs, SpanConverter.toAttributes(g.tags), g.value)

def toGaugeData(g: Seq[Snapshot[Double]]): GaugeData[DoublePointData] = ImmutableGaugeData.create(g.map(toGaugeDatum).asJava)

def convertGauge(gauge: MetricSnapshot.Values[Double]): MetricData =
ImmutableMetricData.createDoubleGauge(
resource,
instrumentationScopeInfo(gauge),
gauge.name,
gauge.description,
toString(gauge.settings.unit),
toGaugeData(gauge.instruments))

def toHistogramDatum(s: Snapshot[Distribution]): HistogramPointData =
ImmutableHistogramPointData.create(
fromNs,
toNs,
SpanConverter.toAttributes(s.tags),
JDouble valueOf s.value.sum.toDouble,
JDouble valueOf s.value.min.toDouble,
JDouble valueOf s.value.max.toDouble,
s.value.buckets.map(JDouble valueOf _.value.toDouble).asJava,
s.value.buckets.map(JLong valueOf _.frequency).asJava
)

def toHistogramData(any: Seq[Snapshot[Distribution]]): HistogramData =
ImmutableHistogramData.create(AggregationTemporality.CUMULATIVE, any.map(toHistogramDatum).asJava)

def convertHistogram(histogram: MetricSnapshot.Distributions): MetricData =
ImmutableMetricData.createDoubleHistogram(
resource,
instrumentationScopeInfo(histogram),
histogram.name,
histogram.description,
toString(histogram.settings.unit),
toHistogramData(histogram.instruments))

def toCounterDatum(g: Snapshot[Long]): LongPointData =
ImmutableLongPointData.create(fromNs, toNs, SpanConverter.toAttributes(g.tags), g.value)

def toCounterData(g: Seq[Snapshot[Long]]): SumData[LongPointData] =
ImmutableSumData.create(false, AggregationTemporality.CUMULATIVE, g.map(toCounterDatum).asJava)

def convertCounter(counter: MetricSnapshot.Values[Long]): MetricData =
ImmutableMetricData.createLongSum(
resource,
instrumentationScopeInfo(counter),
counter.name,
counter.description,
toString(counter.settings.unit),
toCounterData(counter.instruments))

}

/**
* Converts Kamon metrics to OpenTelemetry [[MetricData]]s
*/
private[otel] object MetricsConverter {
def convert(resource: Resource, kamonVersion: String)(metrics: PeriodSnapshot): JCollection[MetricData] =
???
def convert(resource: Resource, kamonVersion: String)(metrics: PeriodSnapshot): JCollection[MetricData] = {
val converter = new WithResourceMetricsConverter(resource, kamonVersion, metrics.from, metrics.to)
val gauges = metrics.gauges.map(converter.convertGauge)
val histograms = (metrics.histograms ++ metrics.timers ++ metrics.rangeSamplers).map(converter.convertHistogram)
val counters = metrics.counters.map(converter.convertCounter)

(gauges ++ histograms ++ counters).asJava
}
}

0 comments on commit e07a3bb

Please sign in to comment.