From d2db875a38c0d94915f4dbcefd869760e79a3dd9 Mon Sep 17 00:00:00 2001 From: Takayuki Takagi Date: Tue, 10 Oct 2023 16:29:41 +0900 Subject: [PATCH] Add Datadog specific error tags (#1228) --- .../kamon/datadog/DatadogSpanReporter.scala | 10 ++++++++- .../datadog/DatadogSpanReporterSpec.scala | 21 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/reporters/kamon-datadog/src/main/scala/kamon/datadog/DatadogSpanReporter.scala b/reporters/kamon-datadog/src/main/scala/kamon/datadog/DatadogSpanReporter.scala index cdd013850..de07f31e9 100644 --- a/reporters/kamon-datadog/src/main/scala/kamon/datadog/DatadogSpanReporter.scala +++ b/reporters/kamon-datadog/src/main/scala/kamon/datadog/DatadogSpanReporter.scala @@ -25,6 +25,7 @@ import kamon.{ ClassLoading, Kamon } import kamon.datadog.DatadogSpanReporter.Configuration import kamon.module.{ ModuleFactory, SpanReporter } import kamon.tag.{ Lookups, Tag, TagSet } +import kamon.trace.Span.TagKeys import kamon.util.{ EnvironmentTags, Filter } import org.slf4j.LoggerFactory @@ -52,7 +53,14 @@ object KamonDataDogTranslatorDefault extends KamonDataDogTranslator { val start = from.getEpochNano val duration = Duration.between(from, span.to) val marks = span.marks.map { m => m.key -> m.instant.getEpochNano.toString }.toMap - val tags = (span.tags.all() ++ span.metricTags.all() ++ additionalTags.all()).map { t => + val errorTags = if (span.hasError) { + val builder = TagSet.builder() + span.tags.get(Lookups.option(TagKeys.ErrorMessage)).foreach(msg => builder.add("error.msg", msg)) + span.tags.get(Lookups.option(TagKeys.ErrorStacktrace)).foreach(st => builder.add("error.stack", st)) + builder.build() + } else TagSet.Empty + + val tags = (span.tags.all() ++ span.metricTags.all() ++ errorTags.all() ++ additionalTags.all()).map { t => t.key -> Tag.unwrapValue(t).toString } val meta = (marks ++ tags).filterKeys(tagFilter.accept(_)).toMap diff --git a/reporters/kamon-datadog/src/test/scala/kamon/datadog/DatadogSpanReporterSpec.scala b/reporters/kamon-datadog/src/test/scala/kamon/datadog/DatadogSpanReporterSpec.scala index 896b68e46..2257fa0ae 100644 --- a/reporters/kamon-datadog/src/test/scala/kamon/datadog/DatadogSpanReporterSpec.scala +++ b/reporters/kamon-datadog/src/test/scala/kamon/datadog/DatadogSpanReporterSpec.scala @@ -90,6 +90,26 @@ trait TestData { "error" -> 1 ) + val spanWithErrorTags = span.copy(tags = TagSet.from(Map( + "error" -> true, + "error.type" -> "RuntimeException", + "error.message" -> "Error message", + "error.stacktrace" -> "Error stacktrace" + )), hasError = true) + + val jsonWithErrorTags = json ++ Json.obj( + "meta" -> Json.obj( + "error" -> "true", + "env" -> "staging", + "error.type" -> "RuntimeException", + "error.message" -> "Error message", + "error.msg" -> "Error message", + "error.stacktrace" -> "Error stacktrace", + "error.stack" -> "Error stacktrace" + ), + "error" -> 1 + ) + val spanWithTags = span.copy(metricTags = TagSet.from( Map( @@ -152,6 +172,7 @@ trait TestData { "span with marks" -> (Seq(spanWithMarks), Json.arr(Json.arr(jsonWithMarks))), "span with meta and marks" -> (Seq(spanWithTagsAndMarks), Json.arr(Json.arr(jsonWithTagsAndMarks))), "span with error" -> (Seq(spanWithError), Json.arr(Json.arr(jsonWithError))), + "span with error tags" -> (Seq(spanWithErrorTags), Json.arr(Json.arr(jsonWithErrorTags))), "multiple spans with same trace" -> (Seq(span, spanWithTags), Json.arr(Json.arr(json, jsonWithTags))) // "multiple spans with two traces" -> (Seq(span, spanWithTags, otherTraceSpan, span), Json.arr(Json.arr(json, jsonWithTags, json), Json.arr(otherTraceJson)))