Skip to content

Commit

Permalink
Trace SDK: introduce span limits support
Browse files Browse the repository at this point in the history
  • Loading branch information
bio-aeon committed Aug 25, 2024
1 parent 2604ca7 commit 3a88831
Show file tree
Hide file tree
Showing 32 changed files with 1,384 additions and 162 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ trait Gens {
attributes <- Gen.listOf(attribute)
} yield attributes.to(Attributes)

def attributes(n: Int): Gen[Attributes] =
for {
attributes <- Gen.listOfN(n, attribute)
} yield attributes.to(Attributes)

}

object Gens extends Gens
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ private object SpansProtoEncoder {
SpanProto.Event(
timeUnixNano = data.timestamp.toNanos,
name = data.name,
attributes = ProtoEncoder.encode(data.attributes)
attributes = ProtoEncoder.encode(data.attributes.elements),
droppedAttributesCount = data.attributes.dropped
)
}

Expand All @@ -113,7 +114,8 @@ private object SpansProtoEncoder {
traceId = ByteString.copyFrom(data.spanContext.traceId.toArray),
spanId = ByteString.copyFrom(data.spanContext.spanId.toArray),
traceState = traceState,
attributes = ProtoEncoder.encode(data.attributes),
attributes = ProtoEncoder.encode(data.attributes.elements),
droppedAttributesCount = data.attributes.dropped,
flags = data.spanContext.traceFlags.toByte.toInt
)
}
Expand All @@ -135,9 +137,12 @@ private object SpansProtoEncoder {
kind = ProtoEncoder.encode(span.kind),
startTimeUnixNano = span.startTimestamp.toNanos,
endTimeUnixNano = span.endTimestamp.map(_.toNanos).getOrElse(0L),
attributes = ProtoEncoder.encode(span.attributes),
events = span.events.map(event => ProtoEncoder.encode(event)),
links = span.links.map(link => ProtoEncoder.encode(link)),
attributes = ProtoEncoder.encode(span.attributes.elements),
droppedAttributesCount = span.attributes.dropped,
events = span.events.elements.map(ProtoEncoder.encode(_)),
droppedEventsCount = span.events.dropped,
links = span.links.elements.map(ProtoEncoder.encode(_)),
droppedLinksCount = span.links.dropped,
status = Some(ProtoEncoder.encode(span.status))
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,15 @@ class OtlpHttpSpanExporterSuite
startTimestamp = now,
endTimestamp = Some(now.plus(5.seconds)),
status = sd.status,
attributes = adaptAttributes(sd.attributes),
events = sd.events.map { event =>
EventData(
event.name,
now.plus(2.seconds),
adaptAttributes(event.attributes)
)
attributes = sd.attributes.map(adaptAttributes),
events = sd.events.map {
_.map { event =>
EventData(
event.name,
now.plus(2.seconds),
event.attributes.map(adaptAttributes)
)
}
},
links = sd.links,
instrumentationScope = sd.instrumentationScope,
Expand All @@ -118,7 +120,7 @@ class OtlpHttpSpanExporterSuite
)
}

val links = span.links.map { d =>
val links = span.links.elements.map { d =>
JaegerRef(
"FOLLOWS_FROM",
d.spanContext.traceIdHex,
Expand Down Expand Up @@ -155,12 +157,14 @@ class OtlpHttpSpanExporterSuite
List(Attribute("internal.span.format", "otlp"))
).flatten

span.attributes.map(a => toJaegerTag(a)).toList ++
span.attributes.elements.map(a => toJaegerTag(a)).toList ++
extra.map(a => toJaegerTag(a))
}

val events =
span.events.map(d => JaegerLog(d.timestamp.toMicros)).toList
span.events.elements
.map(d => JaegerLog(d.timestamp.toMicros))
.toList

val jaegerSpan = JaegerSpan(
span.spanContext.traceIdHex,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ private object SpansJsonCodecs extends JsonCodecs {
.obj(
"timeUnixNano" := eventData.timestamp.toNanos.toString,
"name" := eventData.name,
"attributes" := eventData.attributes
"attributes" := eventData.attributes.elements,
"droppedAttributesCount" := eventData.attributes.dropped
)
.dropEmptyValues
}
Expand All @@ -91,7 +92,8 @@ private object SpansJsonCodecs extends JsonCodecs {
"traceId" := link.spanContext.traceIdHex,
"spanId" := link.spanContext.spanIdHex,
"traceState" := link.spanContext.traceState,
"attributes" := link.attributes,
"attributes" := link.attributes.elements,
"droppedAttributesCount" := link.attributes.dropped,
"flags" := encodeFlags(link.spanContext.traceFlags)
)
.dropNullValues
Expand All @@ -111,9 +113,12 @@ private object SpansJsonCodecs extends JsonCodecs {
"kind" := span.kind,
"startTimeUnixNano" := span.startTimestamp.toNanos.toString,
"endTimeUnixNano" := span.endTimestamp.map(_.toNanos.toString),
"attributes" := span.attributes,
"events" := span.events,
"links" := span.links
"attributes" := span.attributes.elements,
"droppedAttributesCount" := span.attributes.dropped,
"events" := span.events.elements,
"droppedEventsCount" := span.events.dropped,
"links" := span.links.elements,
"droppedLinksCount" := span.links.dropped
)
.dropNullValues
.dropEmptyValues
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import org.scalacheck.Arbitrary
import org.scalacheck.Prop
import org.scalacheck.Test
import org.typelevel.otel4s.sdk.trace.data.EventData
import org.typelevel.otel4s.sdk.trace.data.LimitedData
import org.typelevel.otel4s.sdk.trace.data.LinkData
import org.typelevel.otel4s.sdk.trace.data.SpanData
import org.typelevel.otel4s.sdk.trace.data.StatusData
Expand Down Expand Up @@ -93,7 +94,8 @@ class SpansProtoEncoderSuite extends ScalaCheckSuite {
.obj(
"timeUnixNano" := eventData.timestamp.toNanos.toString,
"name" := eventData.name,
"attributes" := eventData.attributes
"attributes" := eventData.attributes.elements,
"droppedAttributesCount" := eventData.attributes.dropped,
)
.dropNullValues
.dropEmptyValues
Expand All @@ -107,13 +109,23 @@ class SpansProtoEncoderSuite extends ScalaCheckSuite {

assertEquals(
ProtoEncoder
.toJson(EventData("name", 1.nanos, Attributes.empty))
.toJson(
EventData("name", 1.nanos, LimitedData.attributes(100, Int.MaxValue))
)
.noSpaces,
"""{"timeUnixNano":"1","name":"name"}"""
)

assertEquals(
ProtoEncoder.toJson(EventData("name", 1.nanos, attrs)).noSpaces,
ProtoEncoder
.toJson(
EventData(
"name",
1.nanos,
LimitedData.attributes(attrs.size, Int.MaxValue).appendAll(attrs)
)
)
.noSpaces,
"""{"timeUnixNano":"1","name":"name","attributes":[{"key":"key","value":{"stringValue":"value"}}]}"""
)
}
Expand All @@ -125,7 +137,8 @@ class SpansProtoEncoderSuite extends ScalaCheckSuite {
"traceId" := link.spanContext.traceIdHex,
"spanId" := link.spanContext.spanIdHex,
"traceState" := link.spanContext.traceState,
"attributes" := link.attributes,
"attributes" := link.attributes.elements,
"droppedAttributesCount" := link.attributes.dropped,
"flags" := encodeFlags(link.spanContext.traceFlags)
)
.dropNullValues
Expand Down Expand Up @@ -155,17 +168,28 @@ class SpansProtoEncoderSuite extends ScalaCheckSuite {
)

assertEquals(
ProtoEncoder.toJson(LinkData(ctx)).noSpaces,
ProtoEncoder
.toJson(LinkData(ctx, LimitedData.attributes(100, Int.MaxValue)))
.noSpaces,
"""{"traceId":"aae6750d58ff8148fa33894599afaaf2","spanId":"f676d76b0b3d4324","traceState":"k2=v2,k=v","flags":1}"""
)

assertEquals(
ProtoEncoder.toJson(LinkData(ctx, attrs)).noSpaces,
ProtoEncoder
.toJson(
LinkData(
ctx,
LimitedData.attributes(attrs.size, Int.MaxValue).appendAll(attrs)
)
)
.noSpaces,
"""{"traceId":"aae6750d58ff8148fa33894599afaaf2","spanId":"f676d76b0b3d4324","traceState":"k2=v2,k=v","attributes":[{"key":"key","value":{"stringValue":"value"}}],"flags":1}"""
)

assertEquals(
ProtoEncoder.toJson(LinkData(ctx2)).noSpaces,
ProtoEncoder
.toJson(LinkData(ctx2, LimitedData.attributes(100, Int.MaxValue)))
.noSpaces,
"""{"traceId":"aae6750d58ff8148fa33894599afaaf2","spanId":"f676d76b0b3d4324"}"""
)
}
Expand All @@ -186,9 +210,12 @@ class SpansProtoEncoderSuite extends ScalaCheckSuite {
"kind" := span.kind,
"startTimeUnixNano" := span.startTimestamp.toNanos.toString,
"endTimeUnixNano" := span.endTimestamp.map(_.toNanos.toString),
"attributes" := span.attributes,
"events" := span.events,
"links" := span.links
"attributes" := span.attributes.elements,
"droppedAttributesCount" := span.attributes.dropped,
"events" := span.events.elements,
"droppedEventsCount" := span.events.dropped,
"links" := span.links.elements,
"droppedLinksCount" := span.links.dropped
)
.dropNullValues
.dropEmptyValues
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import org.typelevel.otel4s.sdk.metrics.exporter.MetricExporter
import org.typelevel.otel4s.sdk.metrics.view.InstrumentSelector
import org.typelevel.otel4s.sdk.metrics.view.View
import org.typelevel.otel4s.sdk.test.NoopConsole
import org.typelevel.otel4s.sdk.trace.SpanLimits
import org.typelevel.otel4s.sdk.trace.context.propagation.W3CBaggagePropagator
import org.typelevel.otel4s.sdk.trace.context.propagation.W3CTraceContextPropagator
import org.typelevel.otel4s.sdk.trace.data.LinkData
Expand All @@ -55,7 +56,7 @@ class OpenTelemetrySdkSuite extends CatsEffectSuite {
private val DefaultSdk =
sdkToString(
TelemetryResource.default,
Sampler.parentBased(Sampler.AlwaysOn)
sampler = Sampler.parentBased(Sampler.AlwaysOn)
)

private val NoopSdk =
Expand Down Expand Up @@ -391,6 +392,7 @@ class OpenTelemetrySdkSuite extends CatsEffectSuite {

private def sdkToString(
resource: TelemetryResource = TelemetryResource.default,
spanLimits: SpanLimits = SpanLimits.default,
sampler: Sampler = Sampler.parentBased(Sampler.AlwaysOn),
propagators: ContextPropagators[Context] = ContextPropagators.of(
W3CTraceContextPropagator.default,
Expand All @@ -402,7 +404,7 @@ class OpenTelemetrySdkSuite extends CatsEffectSuite {
"OpenTelemetrySdk.AutoConfigured{sdk=" +
s"OpenTelemetrySdk{meterProvider=$meterProvider, " +
"tracerProvider=" +
s"SdkTracerProvider{resource=$resource, sampler=$sampler, " +
s"SdkTracerProvider{resource=$resource, spanLimits=$spanLimits, sampler=$sampler, " +
"spanProcessor=SpanProcessor.Multi(" +
s"BatchSpanProcessor{exporter=$exporter, scheduleDelay=5 seconds, exporterTimeout=30 seconds, maxQueueSize=2048, maxExportBatchSize=512}, " +
"SpanStorage)}, " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import org.typelevel.otel4s.sdk.context.Context
import org.typelevel.otel4s.sdk.testkit.trace.TracesTestkit
import org.typelevel.otel4s.sdk.trace.context.propagation.W3CTraceContextPropagator
import org.typelevel.otel4s.sdk.trace.data.EventData
import org.typelevel.otel4s.sdk.trace.data.LimitedData
import org.typelevel.otel4s.sdk.trace.data.StatusData
import org.typelevel.otel4s.sdk.trace.samplers.Sampler
import org.typelevel.otel4s.trace.BaseTracerSuite
Expand Down Expand Up @@ -76,7 +77,7 @@ class SdkTracerSuite extends BaseTracerSuite[Context, Context.Key] {
spans.map(_.underlying.status),
List(StatusData(StatusCode.Error, "canceled"))
)
assertEquals(spans.map(_.underlying.events.isEmpty), List(true))
assertEquals(spans.map(_.underlying.events.elements.isEmpty), List(true))
}
}

Expand All @@ -91,7 +92,11 @@ class SdkTracerSuite extends BaseTracerSuite[Context, Context.Key] {
EventData.fromException(
timestamp = timestamp,
exception = exception,
attributes = Attributes.empty,
attributes = LimitedData
.attributes(
SpanLimits.default.maxNumberOfAttributesPerEvent,
SpanLimits.default.maxAttributeValueLength
),
escaped = false
)

Expand All @@ -107,7 +112,7 @@ class SdkTracerSuite extends BaseTracerSuite[Context, Context.Key] {
List(StatusData.Error(None))
)
assertEquals(
spans.map(_.underlying.events),
spans.map(_.underlying.events.elements),
List(Vector(expected(now)))
)
}
Expand Down Expand Up @@ -167,7 +172,7 @@ class SdkTracerSuite extends BaseTracerSuite[Context, Context.Key] {
def name: String = sd.name
def spanContext: SpanContext = sd.spanContext
def parentSpanContext: Option[SpanContext] = sd.parentSpanContext
def attributes: Attributes = sd.attributes
def attributes: Attributes = sd.attributes.elements
def startTimestamp: FiniteDuration = sd.startTimestamp
def endTimestamp: Option[FiniteDuration] = sd.endTimestamp
}
Expand Down
Loading

0 comments on commit 3a88831

Please sign in to comment.