From d76d5a6f445278e686fc7484edbdb61483971b23 Mon Sep 17 00:00:00 2001 From: Diego Date: Wed, 2 Apr 2014 18:16:09 -0300 Subject: refactor --- .../scala/kamon/statsd/StatsdMetricsSender.scala | 70 ++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 kamon-statsd/src/main/scala/kamon/statsd/StatsdMetricsSender.scala (limited to 'kamon-statsd/src/main/scala/kamon/statsd/StatsdMetricsSender.scala') diff --git a/kamon-statsd/src/main/scala/kamon/statsd/StatsdMetricsSender.scala b/kamon-statsd/src/main/scala/kamon/statsd/StatsdMetricsSender.scala new file mode 100644 index 00000000..1ccf5397 --- /dev/null +++ b/kamon-statsd/src/main/scala/kamon/statsd/StatsdMetricsSender.scala @@ -0,0 +1,70 @@ +/* + * ========================================================================================= + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * ========================================================================================= + */ + +package kamon.statsd + +import akka.actor.{ActorLogging, Props, ActorRef, Actor} +import akka.io.{Udp, IO} +import java.net.InetSocketAddress +import akka.util.ByteString + +class StatsdMetricsSender(statPrefix:String, remote: InetSocketAddress) extends Actor with ActorLogging { + import StatsdMetricsSender._ + import context.system + + IO(Udp) ! Udp.SimpleSender + + def receive = { + case Udp.SimpleSenderReady => + context.become(ready(sender)) + } + + def ready(send: ActorRef): Receive = { + case metric: StatsdMetric => + send ! Udp.Send(toByteString(statPrefix, metric), remote) + + case _ => log.error("Unknown Metric") + } +} + +object StatsdMetricsSender { + + sealed trait StatsdMetric + case class Counter(key: String, value: Long = 1, suffix:String = "c", samplingRate: Double = 1.0) extends StatsdMetric + case class Timing(key: String, millis: Long, suffix:String = "ms", samplingRate: Double = 1.0) extends StatsdMetric + case class Gauge(key: String, value: Long, suffix:String = "g", samplingRate: Double = 1.0) extends StatsdMetric + + def props(statPrefix:String, remote: InetSocketAddress): Props = Props(new StatsdMetricsSender(statPrefix, remote)) + + def toByteString(statPrefix:String, metric:StatsdMetric) : ByteString = metric match { + case Counter(key, value, suffix, samplingRate) => statFor(statPrefix, key, value, suffix, samplingRate) + case Timing(key, value, suffix, samplingRate) => statFor(statPrefix, key, value, suffix, samplingRate) + case Gauge(key, value, suffix, samplingRate) => statFor(statPrefix, key, value, suffix, samplingRate) + } + + /* + * Creates the stat string to send to statsd. + * For counters, it provides something like {@code key:value|c}. + * For timing, it provides something like {@code key:millis|ms}. + * If sampling rate is less than 1, it provides something like {@code key:value|type|@rate} + */ + private[this] def statFor(statPrefix:String, key: String, value: Long, suffix: String, samplingRate: Double): ByteString = { + samplingRate match { + case x if x >= 1.0 => ByteString(s"${statPrefix}.${key}:${value}|$suffix") + case _ => ByteString(s"${statPrefix}.${key}:${value}|${suffix}|@$samplingRate") + } + } +} \ No newline at end of file -- cgit v1.2.3