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..da0d9e815 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 + (TagKey.offset -> offset) + val id = TaggedItem.computeId(outputTags + ("atlas.query" -> query)).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) ) } diff --git a/atlas-eval/src/test/scala/com/netflix/atlas/eval/stream/EvaluatorSuite.scala b/atlas-eval/src/test/scala/com/netflix/atlas/eval/stream/EvaluatorSuite.scala index 919be76f5..128ce42a0 100644 --- a/atlas-eval/src/test/scala/com/netflix/atlas/eval/stream/EvaluatorSuite.scala +++ b/atlas-eval/src/test/scala/com/netflix/atlas/eval/stream/EvaluatorSuite.scala @@ -587,7 +587,7 @@ class EvaluatorSuite extends FunSuite { assertEquals(msgs.count(_.message.isInstanceOf[TimeSeriesMessage]), 1) val ts = timeSeriesMessages(msgs).head - assertEquals(ts.tags, Map("name" -> "foo")) + assertEquals(ts.tags, Map("atlas.offset" -> "0w", "name" -> "foo")) assertEquals(ts.data, ArrayData(Array(expected))) }