From d64bbb1fdb634cafe13c0a19886550332d08f683 Mon Sep 17 00:00:00 2001 From: Ivan Topolnjak Date: Sat, 10 Feb 2018 01:12:36 +0100 Subject: add support for environment tags, fixes #510 --- .../src/test/scala/kamon/EnvironmentSpec.scala | 21 ++++++++++++++++++++- kamon-core/src/main/resources/reference.conf | 12 ++++++++++++ kamon-core/src/main/scala/kamon/Environment.scala | 7 ++++--- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/kamon-core-tests/src/test/scala/kamon/EnvironmentSpec.scala b/kamon-core-tests/src/test/scala/kamon/EnvironmentSpec.scala index 82eed862..dadab5af 100644 --- a/kamon-core-tests/src/test/scala/kamon/EnvironmentSpec.scala +++ b/kamon-core-tests/src/test/scala/kamon/EnvironmentSpec.scala @@ -27,7 +27,7 @@ class EnvironmentSpec extends WordSpec with Matchers { | instance = auto |} """.stripMargin - ) + ).withFallback(ConfigFactory.defaultReference()) "the Kamon environment" should { "assign a host and instance name when they are set to 'auto'" in { @@ -36,6 +36,7 @@ class EnvironmentSpec extends WordSpec with Matchers { env.host shouldNot be("auto") env.instance shouldNot be("auto") env.instance shouldBe s"environment-spec@${env.host}" + env.tags shouldBe empty } "use the configured host and instance, if provided" in { @@ -51,6 +52,24 @@ class EnvironmentSpec extends WordSpec with Matchers { env.host should be("spec-host") env.instance should be("spec-instance") + env.tags shouldBe empty + } + + "read all environment tags, if provided" in { + val customConfig = ConfigFactory.parseString( + """ + |kamon.environment.tags { + | custom1 = "test1" + | env = staging + |} + """.stripMargin) + + val env = Environment.fromConfig(customConfig.withFallback(baseConfig)) + + env.tags should contain allOf( + ("custom1" -> "test1"), + ("env" -> "staging") + ) } "always return the same incarnation name" in { diff --git a/kamon-core/src/main/resources/reference.conf b/kamon-core/src/main/resources/reference.conf index 659114ca..b3fd3b17 100644 --- a/kamon-core/src/main/resources/reference.conf +++ b/kamon-core/src/main/resources/reference.conf @@ -11,6 +11,18 @@ kamon { # Identifier for a particular instance of this service. If set to `auto` Kamon will use the pattern service@host. instance = "auto" + + # Arbitraty key-value pairs that further identify the environment where this service instance is running. Typically + # these tags will be used by the reporting modules as additional tags for all metrics or spans. Take a look at each + # reporter module's configuration to ensure these tags are supported and included in the reported data. Example: + # + # kamon.environment.tags { + # env = "staging" + # region = "us-east-1" + # } + tags { + + } } # FQCN of the reporter instances that should be loaded when calling `Kamon.reporters.loadReportersFromConfig()`. All diff --git a/kamon-core/src/main/scala/kamon/Environment.scala b/kamon-core/src/main/scala/kamon/Environment.scala index 80833352..1c00679d 100644 --- a/kamon-core/src/main/scala/kamon/Environment.scala +++ b/kamon-core/src/main/scala/kamon/Environment.scala @@ -21,15 +21,16 @@ import java.util.concurrent.ThreadLocalRandom import com.typesafe.config.Config import kamon.util.HexCodec -case class Environment(host: String, service: String, instance: String, incarnation: String) +case class Environment(host: String, service: String, instance: String, incarnation: String, tags: Map[String, String]) object Environment { private val incarnation = HexCodec.toLowerHex(ThreadLocalRandom.current().nextLong()) def fromConfig(config: Config): Environment = { val environmentConfig = config.getConfig("kamon.environment") - val service = environmentConfig.getString("service") + val tagsConfig = environmentConfig.getConfig("tags") + val tags = tagsConfig.topLevelKeys.map(tag => (tag -> tagsConfig.getString(tag))).toMap val host = readValueOrGenerate( environmentConfig.getString("host"), @@ -41,7 +42,7 @@ object Environment { s"$service@$host" ) - Environment(host, service, instance, incarnation) + Environment(host, service, instance, incarnation, tags) } private def readValueOrGenerate(configuredValue: String, generator: => String): String = -- cgit v1.2.3