diff --git a/README.md b/README.md
index 2673e60..bc81403 100644
--- a/README.md
+++ b/README.md
@@ -12,69 +12,55 @@ want to turn the massive amounts of data produced by their apps, tools and servi
### Getting Started
-Kamon datadog module is currently available for Scala 2.10, 2.11 and 2.12.
-
Supported releases and dependencies are shown below.
-| kamon-datadog | status | jdk | scala | akka |
-|:------:|:------:|:----:|------------------|:------:|
-| 0.6.7 | stable | 1.7+, 1.8+ | 2.10, 2.11, 2.12 | 2.3.x, 2.4.x |
+| kamon-datadog | status | jdk | scala |
+|:--------------:|:------:|:----:|------------------|
+| 1.0.0 | stable | 1.8+ | 2.10, 2.11, 2.12 |
-To get started with SBT, simply add the following to your `build.sbt`
-file:
+To get started with SBT, simply add the following to your `build.sbt` file:
```scala
-libraryDependencies += "io.kamon" %% "kamon-datadog" % "0.6.7"
+libraryDependencies += "io.kamon" %% "kamon-datadog" % "1.0.0"
```
-Configuration
--------------
-
-By default, this module assumes that you have an instance of the Datadog Agent running in localhost and listening on
-port 8125. If that is not the case the you can use the `kamon.datadog.hostname` and `kamon.datadog.port` configuration
-keys to point the module at your Datadog Agent installation.
-
-The Datadog module subscribes itself to the entities included in the `kamon.datadog.subscriptions` key. By default, the
-following subscriptions are included:
+And add the Agent or API reporter to Kamon:
```
-kamon.datadog {
- subscriptions {
- histogram = [ "**" ]
- min-max-counter = [ "**" ]
- gauge = [ "**" ]
- counter = [ "**" ]
- trace = [ "**" ]
- trace-segment = [ "**" ]
- akka-actor = [ "**" ]
- akka-dispatcher = [ "**" ]
- akka-router = [ "**" ]
- system-metric = [ "**" ]
- http-server = [ "**" ]
- }
-}
+Kamon.addReporter(new DatadogAgentReporter())
+// OR
+Kamon.addReporter(new DatadogAPIReporter())
```
-If you are interested in reporting additional entities to Datadog please ensure that you include the categories and name
-patterns accordingly.
+Configuration
+-------------
+#### Agent Reporter
-### Metric Naming Conventions ###
+By default, the Agent reporter assumes that you have an instance of the Datadog Agent running in localhost and listening on
+port 8125. If that is not the case the you can use the `kamon.datadog.agent.hostname` and `kamon.datadog.agent.port` configuration
+keys to point the module at your Datadog Agent installation.
-For all single instrument entities (those tracking counters, histograms, gaugues and min-max-counters) the generated
-metric key will follow the `application.instrument-type.entity-name` pattern. Additionaly all tags supplied when
-creating the instrument will also be reported.
+#### API Reporter
-For all other entities the pattern is a little different: `application.entity-category.entity-name` and a identification
-tag using the category and entity name will be used. For example, all mailbox size measurements for Akka actors are
-reported under the `application.akka-actor.mailbox-size` metric and a identification tag similar to
-`actor:/user/example-actor` is included as well.
+When using the API reporter you must configure your API key using the `kamon.datadog.http.api-key` configuration setting.
+Since Kamon has access to the entire distribution of values for a given period, the API reporter can directly post the
+data that would otherwise be summarized and sent by the Datadog Agent. Gauges andAll histogram-backed metrics will be reported as
+follows:
+ - metric.avg
+ - metric.count
+ - metric.median
+ - metric.95percentile
+ - metric.max
+ - metric.min
-Finally, the application name can be changed by setting the `kamon.datadog.application-name` configuration key.
+You can refer to the [Datadog documentation](https://docs.datadoghq.com/developers/metrics/#histograms) for more details.
### Metric Units ###
-Kamon keeps all timing measurements in nanoseconds and memory measurements in bytes. In order to scale those to other units before sending to datadog, set `time-units` and `memory-units` config keys to desired units. Supported units are:
+Kamon keeps all timing measurements in nanoseconds and memory measurements in bytes. In order to scale those to other
+units before sending to datadog set the `time-units` and `memory-units` config keys to desired units. Supported units are:
+
```
n - nanoseconds
µs - microseconds
@@ -86,30 +72,31 @@ kb - kilobytes
mb - megabytes
gb - gigabytes
```
+
For example,
+
```
kamon.datadog.time-units = "ms"
```
+
will scale all timing measurements to milliseconds right before sending to datadog.
+
Integration Notes
-----------------
* Contrary to other Datadog client implementations, we don't flush the metrics data as soon as the measurements are
taken but instead, all metrics data is buffered by the `kamon-datadog` module and flushed periodically using the
- configured `kamon.datadog.flush-interval` and `kamon.datadog.max-packet-size` settings.
-* It is advisable to experiment with the `kamon.datadog.flush-interval` and `kamon.datadog.max-packet-size` settings to
+ configured `kamon.metric.tick-interval` and `kamon.datadog.max-packet-size` settings.
+* It is advisable to experiment with the `kamon.metric.tick-interval` and `kamon.datadog.agent.max-packet-size` settings to
find the right balance between network bandwidth utilisation and granularity on your metrics data.
-
-
Visualization and Fun
---------------------
-Creating a dashboard in the Datadog user interface is really simple, just start typing the application name ("kamon" by
-default) in the metric selector and all metric names will start to show up. You can also break it down based on the entity
-names. Here is a very simple example of a dashboard created with metrics reported by Kamon:
+Creating a dashboard in the Datadog user interface is really simple, all metric names will match the Kamon metric names
+with the additional "qualifier" suffix. Here is a very simple example of a dashboard created with metrics reported by Kamon:
diff --git a/src/main/scala/kamon/datadog/DatadogAPIReporter.scala b/src/main/scala/kamon/datadog/DatadogAPIReporter.scala
index 7310d97..8723951 100644
--- a/src/main/scala/kamon/datadog/DatadogAPIReporter.scala
+++ b/src/main/scala/kamon/datadog/DatadogAPIReporter.scala
@@ -37,15 +37,11 @@ class DatadogAPIReporter extends MetricReporter {
private val logger = LoggerFactory.getLogger(classOf[DatadogAPIReporter])
private val symbols = DecimalFormatSymbols.getInstance(Locale.US)
-
- private val jsonType = MediaType.parse("application/json; charset=utf-8")
-
symbols.setDecimalSeparator('.') // Just in case there is some weird locale config we are not aware of.
+ private val jsonType = MediaType.parse("application/json; charset=utf-8")
private val valueFormat = new DecimalFormat("#0.#########", symbols)
-
private var configuration = readConfiguration(Kamon.config())
-
private var httpClient: OkHttpClient = createHttpClient(configuration)
override def start(): Unit = {
@@ -78,6 +74,7 @@ class DatadogAPIReporter extends MetricReporter {
val timestamp = snapshot.from.getEpochSecond.toString
val host = Kamon.environment.host
+ val interval = Math.round(Duration.between(snapshot.from, snapshot.to).toMillis() / 1000D)
val seriesBuilder = new StringBuilder()
def addDistribution(metric: MetricDistribution): Unit = {
@@ -86,7 +83,7 @@ class DatadogAPIReporter extends MetricReporter {
val average = if (distribution.count > 0L) (distribution.sum / distribution.count) else 0L
addMetric(name + ".avg", valueFormat.format(scale(average, unit)), gauge, metric.tags)
addMetric(name + ".count", valueFormat.format(distribution.count), count, metric.tags)
- addMetric(name + ".median", valueFormat.format(distribution.percentile(50D).value), gauge, metric.tags)
+ addMetric(name + ".median", valueFormat.format(scale(distribution.percentile(50D).value, unit)), gauge, metric.tags)
addMetric(name + ".95percentile", valueFormat.format(scale(distribution.percentile(95D).value, unit)), gauge, metric.tags)
addMetric(name + ".max", valueFormat.format(scale(distribution.max, unit)), gauge, metric.tags)
addMetric(name + ".min", valueFormat.format(scale(distribution.min, unit)), gauge, metric.tags)
@@ -99,7 +96,7 @@ class DatadogAPIReporter extends MetricReporter {
if (seriesBuilder.length() > 0) seriesBuilder.append(",")
seriesBuilder
- .append(s"""{"metric":"$metricName","points":[[$timestamp,$value]],"type":"$metricType","host":"$host","tags":$allTagsString}""")
+ .append(s"""{"metric":"$metricName","interval":$interval,"points":[[$timestamp,$value]],"type":"$metricType","host":"$host","tags":$allTagsString}""")
}
def add(metric: MetricValue, metricType: String): Unit =
@@ -117,9 +114,13 @@ class DatadogAPIReporter extends MetricReporter {
}
private def scale(value: Long, unit: MeasurementUnit): Double = unit.dimension match {
- case Time if unit.magnitude != time.seconds.magnitude => MeasurementUnit.scale(value, unit, time.seconds)
- case Information if unit.magnitude != information.bytes.magnitude => MeasurementUnit.scale(value, unit, information.bytes)
- case _ => value.toDouble
+ case Time if unit.magnitude != configuration.timeUnit.magnitude =>
+ MeasurementUnit.scale(value, unit, configuration.timeUnit)
+
+ case Information if unit.magnitude != configuration.informationUnit.magnitude =>
+ MeasurementUnit.scale(value, unit, configuration.informationUnit)
+
+ case _ => value.toDouble
}
// Apparently okhttp doesn't require explicit closing of the connection
@@ -149,7 +150,6 @@ class DatadogAPIReporter extends MetricReporter {
private object DatadogAPIReporter {
val apiUrl = "https://app.datadoghq.com/api/v1/series?api_key="
-
val count = "count"
val gauge = "gauge"