Skip to content
This repository has been archived by the owner on Mar 29, 2020. It is now read-only.

Commit

Permalink
minor code formatting and organization changes
Browse files Browse the repository at this point in the history
  • Loading branch information
ivantopo committed Dec 2, 2019
1 parent 5d58a31 commit adba1ae
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 32 deletions.
16 changes: 9 additions & 7 deletions src/main/resources/reference.conf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

kamon {
statsd {
# Hostname and port in which your dogstatsd is running (if not using the API). Remember that Datadog packets are sent using UDP and

# Hostname and port in which your StatsD is running. Remember that StatsD packets are sent using UDP and
# setting unreachable hosts and/or not open ports wont be warned by the Kamon, your data wont go anywhere.
hostname = "127.0.0.1"
port = 8125
Expand All @@ -13,7 +14,7 @@ kamon {
max-packet-size = 1024 bytes

# All time values are collected in nanoseconds,
# to scale before sending to statsd set "time-units" to "s" or "ms" or "µs".
# to scale before sending to StatsD set "time-units" to "s" or "ms" or "µs".
# Value "n" is equivalent to omitting the setting
time-unit = "ms"

Expand All @@ -27,9 +28,10 @@ kamon {
metric-key-generator = kamon.statsd.SimpleMetricKeyGenerator

simple-metric-key-generator {
# Includes the name of the hostname in the generated metric. When set to false, the scheme for the metrics
# will look as follows:
# application.entity.entity-name.metric-name

# Indicates whether to include the hostname in the generated metric name. The generated metric names follow this
# format:
# service-name[.host-name].metric-name[.tag1-key.tag1-value][.tag2-key.tag2-value]...
include-hostname = true

# When the sections that make up the metric names have special characters like dots (very common in dispatcher
Expand All @@ -44,11 +46,11 @@ kamon {
}

modules {
statsd {
statsd-reporter {
enabled = true
name = "StatsD Reporter"
description = "StatsD Reporter"
factory = "kamon.statsd.StatsDReporterFactory"
factory = "kamon.statsd.StatsDReporter$Factory"
}
}
}
6 changes: 3 additions & 3 deletions src/main/scala/kamon/statsd/SimpleMetricKeyGenerator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ class SimpleMetricKeyGenerator(statsDConfig: Config) extends MetricKeyGenerator
type Normalizer = String => String

val configSettings: Config = statsDConfig.getConfig("simple-metric-key-generator")
val application: String = Kamon.environment.service
val serviceName: String = Kamon.environment.service
val includeHostname: Boolean = configSettings.getBoolean("include-hostname")
val hostname: String = Kamon.environment.host
val normalizer: Normalizer = createNormalizer(configSettings.getString("metric-name-normalization-strategy"))
val normalizedHostname: String = normalizer(hostname)

val baseName: String =
if (includeHostname) s"$application.$normalizedHostname"
else application
if (includeHostname) s"$serviceName.$normalizedHostname"
else serviceName

private def createNormalizer(strategy: String): Normalizer = strategy match {
case "percent-encode" => PercentEncoder.encode
Expand Down
52 changes: 30 additions & 22 deletions src/main/scala/kamon/statsd/StatsDReporter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,14 @@ import kamon.statsd.StatsDReporter.MetricDataPacketBuffer
import kamon.util.DynamicAccess
import org.slf4j.LoggerFactory

class StatsDReporterFactory extends ModuleFactory {
override def create(settings: ModuleFactory.Settings): StatsDReporter = new StatsDReporter()
}

class StatsDReporter(configPath: String) extends MetricReporter {
private val logger = LoggerFactory.getLogger(classOf[StatsDReporter])
@volatile private var reporterConfiguration = StatsDReporter.Settings.readSettings(Kamon.config().getConfig(configPath))

val symbols: DecimalFormatSymbols = DecimalFormatSymbols.getInstance(Locale.US)
symbols.setDecimalSeparator('.') // Just in case there is some weird locale config we are not aware of.

// Absurdly high number of decimal digits, let the other end lose precision if it needs to.
// Absurdly high number of decimal digits, let the other end loose precision if it needs to.
val samplingRateFormat = new DecimalFormat("#.################################################################", symbols)
val clientChannel: DatagramChannel = DatagramChannel.open()

Expand All @@ -61,35 +57,41 @@ class StatsDReporter(configPath: String) extends MetricReporter {
val keyGenerator = reporterConfiguration.keyGenerator
val packetBuffer = new MetricDataPacketBuffer(reporterConfiguration.maxPacketSize, clientChannel, reporterConfiguration.agentAddress)

for (
counter <- snapshot.counters;
instrument <- counter.instruments
) {
packetBuffer.appendMeasurement(keyGenerator.generateKey(counter.name, instrument.tags), encodeStatsDCounter(reporterConfiguration, instrument.value, counter.settings.unit))
for {
counter <- snapshot.counters
instrument <- counter.instruments
} {
packetBuffer.appendMeasurement(
key = keyGenerator.generateKey(counter.name, instrument.tags),
measurementData = encodeStatsDCounter(reporterConfiguration, instrument.value, counter.settings.unit))
}

for (
gauge <- snapshot.gauges;
instrument <- gauge.instruments
) {
packetBuffer.appendMeasurement(keyGenerator.generateKey(gauge.name, instrument.tags), encodeStatsDGauge(reporterConfiguration, instrument.value, gauge.settings.unit))
for {
gauge <- snapshot.gauges
instrument <- gauge.instruments
} {
packetBuffer.appendMeasurement(
key = keyGenerator.generateKey(gauge.name, instrument.tags),
measurementData = encodeStatsDGauge(reporterConfiguration, instrument.value, gauge.settings.unit))
}

for (
metric <- snapshot.histograms ++ snapshot.rangeSamplers ++ snapshot.timers;
instrument <- metric.instruments;
bucket <- instrument.value.bucketsIterator
) {
for {
metric <- snapshot.histograms ++ snapshot.rangeSamplers ++ snapshot.timers
instrument <- metric.instruments
bucket <- instrument.value.bucketsIterator
} {
val bucketData = encodeStatsDTimer(reporterConfiguration, bucket.value, bucket.frequency, metric.settings.unit)
packetBuffer.appendMeasurement(keyGenerator.generateKey(metric.name, instrument.tags), bucketData)
}

packetBuffer.flush()
}

private def encodeStatsDCounter(config: StatsDReporter.Settings, count: Long, unit: MeasurementUnit): String = s"${scale(config, count, unit)}|c"
private def encodeStatsDCounter(config: StatsDReporter.Settings, count: Long, unit: MeasurementUnit): String =
s"${scale(config, count, unit)}|c"

private def encodeStatsDGauge(config: StatsDReporter.Settings, value: Double, unit: MeasurementUnit): String = s"${scale(config, value.toLong, unit)}|g"
private def encodeStatsDGauge(config: StatsDReporter.Settings, value: Double, unit: MeasurementUnit): String =
s"${scale(config, value.toLong, unit)}|g"

private def encodeStatsDTimer(config: StatsDReporter.Settings, level: Long, count: Long, unit: MeasurementUnit): String = {
val samplingRate: Double = 1D / count
Expand All @@ -105,6 +107,12 @@ class StatsDReporter(configPath: String) extends MetricReporter {
}

object StatsDReporter {

class Factory extends ModuleFactory {
override def create(settings: ModuleFactory.Settings): StatsDReporter =
new StatsDReporter()
}

case class Settings(
agentAddress: InetSocketAddress,
maxPacketSize: Long,
Expand Down

0 comments on commit adba1ae

Please sign in to comment.