From dfef9dce52782fb4939556adb926d7ff531d72b3 Mon Sep 17 00:00:00 2001 From: Diego Date: Sun, 27 Jul 2014 19:02:23 -0300 Subject: kamon-system-metrics: add system metrics to datadog and statsd modules --- kamon-datadog/src/main/resources/reference.conf | 4 +++ .../src/main/scala/kamon/datadog/Datadog.scala | 19 ++++++++++--- .../src/main/resources/application.conf | 2 +- kamon-statsd/src/main/resources/reference.conf | 4 +++ .../src/main/scala/kamon/statsd/StatsD.scala | 9 ++++++ .../src/main/java/kamon/system/SigarHolder.java | 29 ------------------- .../kamon/system/SystemMetricsCollector.scala | 9 +++--- .../scala/kamon/system/sigar/SigarLoader.scala | 33 +++++++++++++--------- 8 files changed, 58 insertions(+), 51 deletions(-) delete mode 100644 kamon-system-metrics/src/main/java/kamon/system/SigarHolder.java diff --git a/kamon-datadog/src/main/resources/reference.conf b/kamon-datadog/src/main/resources/reference.conf index 231eaf7d..4de24526 100644 --- a/kamon-datadog/src/main/resources/reference.conf +++ b/kamon-datadog/src/main/resources/reference.conf @@ -24,6 +24,10 @@ kamon { dispatcher = [ "*" ] } + # Enable system metrics + # In order to not get a ClassNotFoundException, we must register the kamon-sytem-metrics module + report-system-metrics = false + # Application prefix for all metrics pushed to Datadog. The default namespacing scheme for metrics follows # this pattern: # application.entity-name.metric-name diff --git a/kamon-datadog/src/main/scala/kamon/datadog/Datadog.scala b/kamon-datadog/src/main/scala/kamon/datadog/Datadog.scala index 1803b833..6498f851 100644 --- a/kamon-datadog/src/main/scala/kamon/datadog/Datadog.scala +++ b/kamon-datadog/src/main/scala/kamon/datadog/Datadog.scala @@ -16,14 +16,17 @@ package kamon.datadog +import java.net.InetSocketAddress +import java.util.concurrent.TimeUnit.MILLISECONDS + import akka.actor._ +import akka.event.Logging import kamon.Kamon import kamon.metric._ -import scala.concurrent.duration._ +import kamon.metrics._ + import scala.collection.JavaConverters._ -import akka.event.Logging -import java.net.InetSocketAddress -import java.util.concurrent.TimeUnit.MILLISECONDS +import scala.concurrent.duration._ object Datadog extends ExtensionId[DatadogExtension] with ExtensionIdProvider { override def lookup(): ExtensionId[_ <: Extension] = Datadog @@ -65,6 +68,14 @@ class DatadogExtension(system: ExtendedActorSystem) extends Kamon.Extension { Kamon(Metrics)(system).subscribe(DispatcherMetrics, dispatcherPathPattern, datadogMetricsListener, permanently = true) } + // Subscribe to SystemMetrics + val includeSystemMetrics = datadogConfig.getBoolean("report-system-metrics") + if (includeSystemMetrics) { + List(CPUMetrics, ProcessCPUMetrics, MemoryMetrics, NetworkMetrics, GCMetrics, HeapMetrics) foreach { metric ⇒ + Kamon(Metrics)(system).subscribe(metric, "*", datadogMetricsListener, permanently = true) + } + } + def buildMetricsListener(tickInterval: Long, flushInterval: Long): ActorRef = { assert(flushInterval >= tickInterval, "Datadog flush-interval needs to be equal or greater to the tick-interval") diff --git a/kamon-playground/src/main/resources/application.conf b/kamon-playground/src/main/resources/application.conf index af85207f..d827731a 100644 --- a/kamon-playground/src/main/resources/application.conf +++ b/kamon-playground/src/main/resources/application.conf @@ -1,7 +1,7 @@ akka { loglevel = INFO - extensions = ["kamon.system.SystemMetrics"] + extensions = ["kamon.statsd.StatsD", "kamon.system.SystemMetrics"] actor { debug { diff --git a/kamon-statsd/src/main/resources/reference.conf b/kamon-statsd/src/main/resources/reference.conf index fd6293d9..eac5eade 100644 --- a/kamon-statsd/src/main/resources/reference.conf +++ b/kamon-statsd/src/main/resources/reference.conf @@ -24,6 +24,10 @@ kamon { dispatcher = [ "*" ] } + # Enable system metrics + # In order to not get a ClassNotFoundException, we must register the kamon-sytem-metrics module + report-system-metrics = false + simple-metric-key-generator { # Application prefix for all metrics pushed to StatsD. The default namespacing scheme for metrics follows # this pattern: diff --git a/kamon-statsd/src/main/scala/kamon/statsd/StatsD.scala b/kamon-statsd/src/main/scala/kamon/statsd/StatsD.scala index 299b1acc..e9350fae 100644 --- a/kamon-statsd/src/main/scala/kamon/statsd/StatsD.scala +++ b/kamon-statsd/src/main/scala/kamon/statsd/StatsD.scala @@ -19,6 +19,7 @@ package kamon.statsd import akka.actor._ import kamon.Kamon import kamon.metric._ +import kamon.metrics._ import scala.concurrent.duration._ import scala.collection.JavaConverters._ import com.typesafe.config.Config @@ -69,6 +70,14 @@ class StatsDExtension(system: ExtendedActorSystem) extends Kamon.Extension { Kamon(Metrics)(system).subscribe(DispatcherMetrics, dispatcherPathPattern, statsDMetricsListener, permanently = true) } + // Subscribe to SystemMetrics + val includeSystemMetrics = statsDConfig.getBoolean("report-system-metrics") + if (includeSystemMetrics) { + List(CPUMetrics, ProcessCPUMetrics, MemoryMetrics, NetworkMetrics, GCMetrics, HeapMetrics) foreach { metric ⇒ + Kamon(Metrics)(system).subscribe(metric, "*", statsDMetricsListener, permanently = true) + } + } + def buildMetricsListener(tickInterval: Long, flushInterval: Long): ActorRef = { assert(flushInterval >= tickInterval, "StatsD flush-interval needs to be equal or greater to the tick-interval") val defaultMetricKeyGenerator = new SimpleMetricKeyGenerator(system.settings.config) diff --git a/kamon-system-metrics/src/main/java/kamon/system/SigarHolder.java b/kamon-system-metrics/src/main/java/kamon/system/SigarHolder.java deleted file mode 100644 index 7c8cd695..00000000 --- a/kamon-system-metrics/src/main/java/kamon/system/SigarHolder.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * ========================================================================================= - * 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.system; - -import kamon.system.sigar.SigarLoader; -import org.hyperic.sigar.SigarProxy; - -public class SigarHolder { - private static class LazySigarHolder { - static final SigarProxy instance = SigarLoader.sigarProxy(); - } - - public static SigarProxy instance() { - return LazySigarHolder.instance; - } -} diff --git a/kamon-system-metrics/src/main/scala/kamon/system/SystemMetricsCollector.scala b/kamon-system-metrics/src/main/scala/kamon/system/SystemMetricsCollector.scala index fde9820a..a5a2f411 100644 --- a/kamon-system-metrics/src/main/scala/kamon/system/SystemMetricsCollector.scala +++ b/kamon-system-metrics/src/main/scala/kamon/system/SystemMetricsCollector.scala @@ -15,20 +15,21 @@ */ package kamon.system -import akka.actor.{ Props, Actor } +import akka.actor.{ Actor, Props } import kamon.Kamon import kamon.metric.Metrics import kamon.metrics.CPUMetrics.CPUMetricRecorder import kamon.metrics.MemoryMetrics.MemoryMetricRecorder import kamon.metrics.NetworkMetrics.NetworkMetricRecorder import kamon.metrics.ProcessCPUMetrics.ProcessCPUMetricsRecorder -import kamon.metrics.{ NetworkMetrics, MemoryMetrics, ProcessCPUMetrics, CPUMetrics } -import org.hyperic.sigar.{ NetInterfaceStat, SigarProxy, Mem } +import kamon.metrics.{ CPUMetrics, MemoryMetrics, NetworkMetrics, ProcessCPUMetrics } +import kamon.system.sigar.SigarHolder +import org.hyperic.sigar.{ Mem, NetInterfaceStat, SigarProxy } import scala.concurrent.duration.FiniteDuration class SystemMetricsCollector(collectInterval: FiniteDuration) extends Actor with SigarExtensionProvider { - import SystemMetricsCollector._ + import kamon.system.SystemMetricsCollector._ import kamon.system.SystemMetricsExtension._ val collectSchedule = context.system.scheduler.schedule(collectInterval, collectInterval, self, Collect)(context.dispatcher) diff --git a/kamon-system-metrics/src/main/scala/kamon/system/sigar/SigarLoader.scala b/kamon-system-metrics/src/main/scala/kamon/system/sigar/SigarLoader.scala index 0d6c2410..d138ec8f 100644 --- a/kamon-system-metrics/src/main/scala/kamon/system/sigar/SigarLoader.scala +++ b/kamon-system-metrics/src/main/scala/kamon/system/sigar/SigarLoader.scala @@ -19,14 +19,19 @@ package kamon.system.sigar import java.io._ import java.util import java.util.logging.Logger -import java.util.{ Date, ArrayList, List } +import java.util.{ ArrayList, Date, List } -import org.hyperic.sigar.{ OperatingSystem, CpuPerc, Sigar, SigarProxy } +import org.hyperic.sigar.{ OperatingSystem, Sigar, SigarProxy } import scala.annotation.tailrec import scala.collection.JavaConversions._ import scala.io.Source +object SigarHolder { + private lazy val sigarProxy = SigarLoader.sigarProxy + def instance() = sigarProxy +} + object SigarLoader { val Version = "1.6.4" @@ -138,6 +143,7 @@ object SigarLoader { val now = System.currentTimeMillis() new Date(now - (uptime.getUptime() * 1000).toLong) } + def osInfo() = { val NewLine = "\n" val os = OperatingSystem.getInstance @@ -149,17 +155,18 @@ object SigarLoader { .toString() } - val message = """ - | - | _____ _ __ __ _ _ _ _ _ - | / ____| | | | \/ | | | (_) | | | | | | - || (___ _ _ ___| |_ ___ _ __ ___ | \ / | ___| |_ _ __ _ ___ ___| | ___ __ _ __| | ___ __| | - | \___ \| | | / __| __/ _ \ '_ ` _ \| |\/| |/ _ \ __| '__| |/ __/ __| | / _ \ / _` |/ _` |/ _ \/ _` | - | ____) | |_| \__ \ || __/ | | | | | | | | __/ |_| | | | (__\__ \ |___| (_) | (_| | (_| | __/ (_| | - ||_____/ \__, |___/\__\___|_| |_| |_|_| |_|\___|\__|_| |_|\___|___/______\___/ \__,_|\__,_|\___|\__,_| - | __/ | - | |___/ - """.stripMargin + s"\nBoot Time: ${uptime(sigar)} \nLoad Average: ${loadAverage(sigar)} \n${osInfo()}" + val message = + """ + | + | _____ _ __ __ _ _ _ _ _ + | / ____| | | | \/ | | | (_) | | | | | | + || (___ _ _ ___| |_ ___ _ __ ___ | \ / | ___| |_ _ __ _ ___ ___| | ___ __ _ __| | ___ __| | + | \___ \| | | / __| __/ _ \ '_ ` _ \| |\/| |/ _ \ __| '__| |/ __/ __| | / _ \ / _` |/ _` |/ _ \/ _` | + | ____) | |_| \__ \ || __/ | | | | | | | | __/ |_| | | | (__\__ \ |___| (_) | (_| | (_| | __/ (_| | + ||_____/ \__, |___/\__\___|_| |_| |_|_| |_|\___|\__|_| |_|\___|___/______\___/ \__,_|\__,_|\___|\__,_| + | __/ | + | |___/ + """.stripMargin + s"\nBoot Time: ${uptime(sigar)} \nLoad Average: ${loadAverage(sigar)} \n${osInfo()}" log.info(message) } class Loader private[sigar] -- cgit v1.2.3