From a3e36ee7fb11a7dc46d6bfe98fadcf4c752b13df Mon Sep 17 00:00:00 2001 From: Brian Harrington Date: Mon, 12 Feb 2024 11:03:26 -0600 Subject: [PATCH] add time series id to v2.json output Update v2.json output to include the id for a time series. This can be useful when matching without output from other sources such as streaming data. For consistency also updates the LWC/fetch output to include the offset dimension. --- .../main/scala/com/netflix/atlas/chart/JsonCodec.scala | 5 +++++ .../scala/com/netflix/atlas/eval/graph/Grapher.scala | 2 +- .../com/netflix/atlas/eval/model/TimeSeriesMessage.scala | 9 +++++++-- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/atlas-chart/src/main/scala/com/netflix/atlas/chart/JsonCodec.scala b/atlas-chart/src/main/scala/com/netflix/atlas/chart/JsonCodec.scala index 23a62d412..647195860 100644 --- a/atlas-chart/src/main/scala/com/netflix/atlas/chart/JsonCodec.scala +++ b/atlas-chart/src/main/scala/com/netflix/atlas/chart/JsonCodec.scala @@ -30,6 +30,7 @@ import com.netflix.atlas.chart.util.PngImage import com.netflix.atlas.core.model.ArrayTimeSeq import com.netflix.atlas.core.model.CollectorStats import com.netflix.atlas.core.model.DsType +import com.netflix.atlas.core.model.TaggedItem import com.netflix.atlas.core.model.TimeSeries import com.netflix.atlas.core.util.Streams import com.netflix.atlas.core.util.Strings @@ -281,6 +282,10 @@ private[chart] object JsonCodec { ): Unit = { gen.writeStartObject() gen.writeStringField("type", "timeseries") + line.query.foreach { q => + val id = TaggedItem.computeId(line.data.tags + ("atlas.query" -> q)).toString + gen.writeStringField("id", id) + } gen.writeNumberField("plot", plot) gen.writeStringField("label", line.data.label) gen.writeFieldName("color") diff --git a/atlas-eval/src/main/scala/com/netflix/atlas/eval/graph/Grapher.scala b/atlas-eval/src/main/scala/com/netflix/atlas/eval/graph/Grapher.scala index d7b54b580..2f842e005 100644 --- a/atlas-eval/src/main/scala/com/netflix/atlas/eval/graph/Grapher.scala +++ b/atlas-eval/src/main/scala/com/netflix/atlas/eval/graph/Grapher.scala @@ -390,7 +390,7 @@ case class Grapher(settings: DefaultSettings) { LineDef( data = t, - query = Some(s.expr.toString), + query = Some(s.toString), groupByKeys = s.expr.finalGrouping, color = color, lineStyle = s.lineStyle.fold(dfltStyle)(s => LineStyle.valueOf(s.toUpperCase)), diff --git a/atlas-eval/src/main/scala/com/netflix/atlas/eval/model/TimeSeriesMessage.scala b/atlas-eval/src/main/scala/com/netflix/atlas/eval/model/TimeSeriesMessage.scala index 00f79a1cc..6d307d91f 100644 --- a/atlas-eval/src/main/scala/com/netflix/atlas/eval/model/TimeSeriesMessage.scala +++ b/atlas-eval/src/main/scala/com/netflix/atlas/eval/model/TimeSeriesMessage.scala @@ -17,8 +17,11 @@ package com.netflix.atlas.eval.model import com.fasterxml.jackson.core.JsonGenerator import com.netflix.atlas.core.model.* +import com.netflix.atlas.core.util.Strings import com.netflix.atlas.json.JsonSupport +import java.time.Duration + /** * Message type use for emitting time series data in LWC and fetch responses. * @@ -110,7 +113,9 @@ object TimeSeriesMessage { */ def apply(expr: StyleExpr, context: EvalContext, ts: TimeSeries): TimeSeriesMessage = { val query = expr.toString - val id = TaggedItem.computeId(ts.tags + ("atlas.query" -> query)).toString + val offset = Strings.toString(Duration.ofMillis(expr.offset)) + val outputTags = ts.tags ++ Map(TagKey.offset -> offset, "atlas.query" -> query) + val id = TaggedItem.computeId(outputTags).toString val data = ts.data.bounded(context.start, context.end) TimeSeriesMessage( id, @@ -120,7 +125,7 @@ object TimeSeriesMessage { context.end, context.step, ts.label, - ts.tags, + outputTags, ArrayData(data.data) ) }