From 7bfc8d29253316289dba6d791126a6d95a0628fb Mon Sep 17 00:00:00 2001 From: Diego Date: Wed, 14 May 2014 00:09:46 -0300 Subject: ! datadog: first functional implementation of DatadogMetricsSender --- .../scala/kamon/datadog/DatadogMetricsSender.scala | 39 ++++++++++------------ .../kamon/datadog/DatadogMetricSenderSpec.scala | 27 ++++----------- 2 files changed, 23 insertions(+), 43 deletions(-) (limited to 'kamon-datadog') diff --git a/kamon-datadog/src/main/scala/kamon/datadog/DatadogMetricsSender.scala b/kamon-datadog/src/main/scala/kamon/datadog/DatadogMetricsSender.scala index 50911093..eb19ae81 100644 --- a/kamon-datadog/src/main/scala/kamon/datadog/DatadogMetricsSender.scala +++ b/kamon-datadog/src/main/scala/kamon/datadog/DatadogMetricsSender.scala @@ -62,10 +62,16 @@ class DatadogMetricsSender(remote: InetSocketAddress, maxPacketSizeInBytes: Long dataBuilder.flush() } - def encodeMeasurement(measurement: Measurement, instrumentType: InstrumentType): String = { - def dataDogDMetricFormat(value: String, metricType: String, samplingRate: Double = 1D): String = - value + "|" + metricType + (if (samplingRate != 1D) "|@" + samplingRateFormat.format(samplingRate) else "") + + def processTags(tags: Seq[String]): String = { + if (tags.isEmpty) "" else { + tags.foldLeft(new StringBuilder("|#")) { (sb, s) ⇒ if (sb.length > 2) sb ++= "," else sb ++= s }.toString() + } + } + + def dataDogDMetricFormat(value: String, metricType: String, samplingRate: Double = 1D, tags: Seq[String] = Nil): String = + value + "|" + metricType + (if (samplingRate != 1D) "|@" + samplingRateFormat.format(samplingRate) else "" + processTags(tags)) instrumentType match { case Histogram ⇒ dataDogDMetricFormat(measurement.value.toString, "ms", (1D / measurement.count)) @@ -91,26 +97,15 @@ class MetricDataPacketBuilder(maxPacketSizeInBytes: Long, udpSender: ActorRef, r var buffer = new StringBuilder() def appendMeasurement(key: String, measurementData: String): Unit = { - if (key == lastKey) { - val dataWithoutKey = measurementSeparator + measurementData - if (fitsOnBuffer(dataWithoutKey)) - buffer.append(dataWithoutKey) - else { - flushToUDP(buffer.toString()) - buffer.clear() - buffer.append(key).append(dataWithoutKey) - } + val data = key + measurementSeparator + measurementData + + if (fitsOnBuffer(metricSeparator + data)) { + val mSeparator = if (buffer.length > 0) metricSeparator else "" + buffer.append(mSeparator).append(data) } else { - lastKey = key - val dataWithoutSeparator = key + measurementSeparator + measurementData - if (fitsOnBuffer(metricSeparator + dataWithoutSeparator)) { - val mSeparator = if (buffer.length > 0) metricSeparator else "" - buffer.append(mSeparator).append(dataWithoutSeparator) - } else { - flushToUDP(buffer.toString()) - buffer.clear() - buffer.append(dataWithoutSeparator) - } + flushToUDP(buffer.toString()) + buffer.clear() + buffer.append(data) } } diff --git a/kamon-datadog/src/test/scala/kamon/datadog/DatadogMetricSenderSpec.scala b/kamon-datadog/src/test/scala/kamon/datadog/DatadogMetricSenderSpec.scala index 781a73c5..98b36159 100644 --- a/kamon-datadog/src/test/scala/kamon/datadog/DatadogMetricSenderSpec.scala +++ b/kamon-datadog/src/test/scala/kamon/datadog/DatadogMetricSenderSpec.scala @@ -1,6 +1,6 @@ /* * ========================================================================================= - * Copyright © 2013 the kamon project + * Copyright © 2013-2014 the kamon project * * 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 @@ -45,20 +45,6 @@ class DatadogMetricSenderSpec extends TestKitBase with WordSpecLike with Matcher data.utf8String should be(s"$testMetricKey:10|ms") } - "render several measurements of the same key under a single (key + multiple measurements) packet" in new UdpListenerFixture { - val testMetricName = "test-metric" - val testMetricKey = buildMetricKey(testMetricName) - val testRecorder = HdrRecorder(1000L, 2, Scale.Unit) - testRecorder.record(10L) - testRecorder.record(11L) - testRecorder.record(12L) - - val udp = setup(Map(testMetricName -> testRecorder.collect())) - val Udp.Send(data, _, _) = udp.expectMsgType[Udp.Send] - - data.utf8String should be(s"$testMetricKey:10|ms:11|ms:12|ms") - } - "include the correspondent sampling rate when rendering multiple occurrences of the same value" in new UdpListenerFixture { val testMetricName = "test-metric" val testMetricKey = buildMetricKey(testMetricName) @@ -77,12 +63,12 @@ class DatadogMetricSenderSpec extends TestKitBase with WordSpecLike with Matcher val testMetricKey = buildMetricKey(testMetricName) val testRecorder = HdrRecorder(testMaxPacketSize, 3, Scale.Unit) - var bytes = testMetricKey.length + var bytes = 0//testMetricKey.length var level = 0 while (bytes <= testMaxPacketSize) { level += 1 testRecorder.record(level) - bytes += s":$level|ms".length + bytes += s"$testMetricKey:$level|ms".length } val udp = setup(Map(testMetricName -> testRecorder.collect())) @@ -106,9 +92,7 @@ class DatadogMetricSenderSpec extends TestKitBase with WordSpecLike with Matcher firstTestRecorder.record(10L) firstTestRecorder.record(10L) - firstTestRecorder.record(11L) - secondTestRecorder.record(20L) secondTestRecorder.record(21L) thirdTestRecorder.record(1L) @@ -116,13 +100,14 @@ class DatadogMetricSenderSpec extends TestKitBase with WordSpecLike with Matcher thirdTestRecorder.record(1L) thirdTestRecorder.record(1L) + val t = thirdTestRecorder.collect() val udp = setup(Map( firstTestMetricName -> firstTestRecorder.collect(), secondTestMetricName -> secondTestRecorder.collect(), - thirdTestMetricName -> thirdTestRecorder.collect())) + thirdTestMetricName -> t)) val Udp.Send(data, _, _) = udp.expectMsgType[Udp.Send] - data.utf8String should be(s"$firstTestMetricKey:10|ms|@0.5:11|ms\n$secondTestMetricKey:20|ms:21|ms\n$thirdTestMetricKey:4|c") + data.utf8String should be(s"$firstTestMetricKey:10|ms|@0.5\n$secondTestMetricKey:21|ms\n$thirdTestMetricKey:4|c") } } -- cgit v1.2.3