Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

parametric: avoids sending non-null default values to trace/otel/start_span #3515

Merged
merged 7 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ private static async Task<string> OtelStartSpan(HttpRequest request)
ActivityContext? remoteParentContext = null;

// try getting parent context from parent id (local parent)
if (requestBodyObject!.TryGetValue("parent_id", out var parentId))
if (requestBodyObject!.TryGetValue("parent_id", out var parentId) && parentId is not null)
{
var stringParentId = parentId.ToString();

Expand All @@ -56,16 +56,16 @@ private static async Task<string> OtelStartSpan(HttpRequest request)
}

DateTimeOffset startTime = default;
if (requestBodyObject.TryGetValue("timestamp", out var timestamp) && Convert.ToInt64(timestamp) is long timestampInMicroseconds && timestampInMicroseconds > 0)
if (requestBodyObject.TryGetValue("timestamp", out var timestamp) && timestamp is not null)
{
startTime = new DateTime(1970, 1, 1) + TimeSpan.FromMicroseconds(timestampInMicroseconds);
startTime = new DateTime(1970, 1, 1) + TimeSpan.FromMicroseconds(Convert.ToInt64(timestamp));
}

var parentContext = localParentContext ?? remoteParentContext ?? default;

var kind = ActivityKind.Internal;

if (requestBodyObject.TryGetValue("span_kind", out var spanKind))
if (requestBodyObject.TryGetValue("span_kind", out var spanKind) && spanKind is not null)
{
switch (Convert.ToInt64(spanKind))
{
Expand Down
34 changes: 15 additions & 19 deletions utils/build/docker/golang/parametric/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,20 @@ type GetTraceConfigReturn struct {
}

type StartSpanArgs struct {
Name string `json:"name,omitempty"`
Service string `json:"service,omitempty"`
ParentId uint64 `json:"parent_id,omitempty"`
Resource string `json:"resource,omitempty"`
Type string `json:"type,omitempty"`
Origin string `json:"origin,omitempty"`
SpanTags []Tuple `json:"span_tags,omitempty"`
SpanLinks []SpanLink `json:"span_links,omitempty"`
Name string `json:"name,omitempty"`
Service string `json:"service,omitempty"`
ParentId uint64 `json:"parent_id,omitempty"`
Resource string `json:"resource,omitempty"`
Type string `json:"type,omitempty"`
SpanTags []Tuple `json:"span_tags,omitempty"`
SpanLinks []SpanLink `json:"span_links,omitempty"`
}

type Tuple []string

type SpanLink struct {
ParentId uint64 `json:"parent_id"`
Attributes AttributeKeyVals `json:"attributes,omitempty"`
ParentId uint64 `json:"parent_id"`
Attributes AttributeKeyVals `json:"attributes,omitempty"`
}

func (x Tuple) Key() string {
Expand Down Expand Up @@ -88,15 +87,12 @@ type SpanSetErrorArgs struct {
}

type OtelStartSpanArgs struct {
Name string `json:"name"`
ParentId uint64 `json:"parent_id"`
SpanKind uint64 `json:"span_kind"`
Service string `json:"service"`
Resource string `json:"resource"`
Type string `json:"type"`
Timestamp int64 `json:"timestamp"`
SpanLinks []SpanLink `json:"links"`
Attributes AttributeKeyVals `json:"attributes"`
Name string `json:"name"`
ParentId *uint64 `json:"parent_id"`
SpanKind *uint64 `json:"span_kind"`
Timestamp *int64 `json:"timestamp"`
SpanLinks []SpanLink `json:"links"`
Attributes AttributeKeyVals `json:"attributes"`
}

type OtelStartSpanReturn struct {
Expand Down
12 changes: 6 additions & 6 deletions utils/build/docker/golang/parametric/otel.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,18 @@ func (s *apmClientServer) OtelStartSpan(args OtelStartSpanArgs) (OtelStartSpanRe
}
var pCtx = context.Background()
var ddOpts []tracer.StartSpanOption
if pid := args.ParentId; pid != 0 {
parent, ok := s.otelSpans[pid]
if pid := args.ParentId; pid != nil {
parent, ok := s.otelSpans[*pid]
if ok {
pCtx = parent.ctx
}
}
var otelOpts []otel_trace.SpanStartOption
if args.SpanKind != 0 {
otelOpts = append(otelOpts, otel_trace.WithSpanKind(otel_trace.ValidateSpanKind(otel_trace.SpanKind(args.SpanKind))))
if args.SpanKind != nil {
otelOpts = append(otelOpts, otel_trace.WithSpanKind(otel_trace.ValidateSpanKind(otel_trace.SpanKind(*args.SpanKind))))
}
if t := args.Timestamp; t != 0 {
tm := time.UnixMicro(t)
if t := args.Timestamp; t != nil {
tm := time.UnixMicro(*t)
otelOpts = append(otelOpts, otel_trace.WithTimestamp(tm))
}
if a := args.Attributes; len(a) > 0 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,19 +164,21 @@ public StartSpanResult startSpan(@RequestBody StartSpanArgs args) {
// Build span from request
SpanBuilder builder = this.tracer.spanBuilder(args.name());
// Check parent span to create parent context from
if (args.parentId() != 0L) {
if (args.parentId() != null) {
Span parentSpan = getSpan(args.parentId());
if (parentSpan != null) {
Context contextWithParentSpan = parentSpan.storeInContext(Context.root());
builder.setParent(contextWithParentSpan);
}
}
// Add other span information
builder.setSpanKind(parseSpanKindNumber(args.spanKind()));
if (args.timestamp() > 0) {
if (args.spanKind() != null) {
builder.setSpanKind(parseSpanKindNumber(args.spanKind()));
}
if (args.timestamp() != null) {
builder.setStartTimestamp(args.timestamp(), MICROSECONDS);
}
if (args.links() != null && !args.links().isEmpty()) {
if (!args.links().isEmpty()) {
for (SpanLink spanLink : args.links()) {
LOGGER.debug("Span link: {}", spanLink);
Span span = getSpan(spanLink.parentId());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
import java.util.Map;

public record StartSpanArgs(
@JsonProperty("parent_id") long parentId,
@JsonProperty("parent_id") Long parentId,
String name,
@JsonProperty("span_kind") int spanKind,
long timestamp,
@JsonProperty("span_kind") Integer spanKind,
Long timestamp,
List<SpanLink> links,
Map<String, Object> attributes) {
}
6 changes: 5 additions & 1 deletion utils/build/docker/nodejs/parametric/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,13 @@ app.post('/trace/otel/start_span', (req, res) => {
return {context: spanContext, attributes: link.attributes}
});

let kind = null
if (request.kind != null) {
kind = request.kind - 1
}
const span = otelTracer.startSpan(request.name, {
type: request.type,
kind: request.kind,
kind: kind,
attributes: request.attributes,
links,
startTime: microLongToHrTime(request.timestamp)
Expand Down
13 changes: 5 additions & 8 deletions utils/build/docker/python/parametric/apm_test_client/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -394,13 +394,10 @@ def trace_span_current() -> TraceSpanCurrentReturn:

class OtelStartSpanArgs(BaseModel):
name: str
parent_id: int
span_kind: int
service: str = ""
resource: str = ""
type: str = ""
links: List[Dict] = []
timestamp: int
parent_id: Optional[int] = None
span_kind: Optional[int] = None
timestamp: Optional[int] = None
links: List[Dict]
attributes: dict


Expand All @@ -422,7 +419,7 @@ def otel_start_span(args: OtelStartSpanArgs):

# parametric tests expect span kind to be 0 for internal, 1 for server, 2 for client, ....
# while parametric tests set 0 for unset, 1 internal, 2 for server, 3 for client, ....
span_kind_int = max(0, args.span_kind - 1)
span_kind_int = (args.span_kind or 1) - 1
with otel_tracer.start_as_current_span(
args.name,
context=set_span_in_context(parent_span),
Expand Down
2 changes: 1 addition & 1 deletion utils/build/docker/ruby/parametric/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -718,7 +718,7 @@ def handle_trace_otel_start_span(req, res)
js = JSON.parse(req.body.read)
args = OtelStartSpanArgs.new(js)

if args.parent_id != 0
if args.parent_id
parent_span = OTEL_SPANS[args.parent_id]
parent_context = OpenTelemetry::Trace.context_with_span(parent_span)
end
Expand Down
4 changes: 0 additions & 4 deletions utils/dd_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,6 @@ class SpanKind(IntEnum):
"""Specifies additional details on how this span relates to its parent span.
"""

# TODO: give unspecified to have a value of 5, and update the other values
# this better aligns with how this enum is defined in the OpenTelemetry Python API.
UNSPECIFIED = 0

#: Default value. Indicates that the span is used internally in the
# application.
INTERNAL = 1
Expand Down
24 changes: 12 additions & 12 deletions utils/parametric/_library_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,20 +222,20 @@ def trace_flush(self) -> bool:
def otel_trace_start_span(
self,
name: str,
timestamp: int,
span_kind: SpanKind,
parent_id: int,
links: List[Link],
attributes: dict = None,
timestamp: Optional[int],
span_kind: Optional[SpanKind],
parent_id: Optional[int],
links: Optional[List[Link]],
attributes: Optional[dict],
) -> StartSpanResponse:
resp = self._session.post(
self._url("/trace/otel/start_span"),
json={
"name": name,
"timestamp": timestamp,
"span_kind": span_kind.value,
"parent_id": parent_id,
"links": links,
"span_kind": span_kind.value if span_kind is not None else None,
"links": links or [],
"attributes": attributes or {},
},
).json()
Expand Down Expand Up @@ -447,19 +447,19 @@ def extract_headers_and_make_child_span(self, name, http_headers):
def otel_start_span(
self,
name: str,
timestamp: int = 0,
span_kind: SpanKind = SpanKind.UNSPECIFIED,
parent_id: int = 0,
timestamp: Optional[int] = None,
span_kind: Optional[SpanKind] = None,
parent_id: Optional[int] = None,
links: Optional[List[Link]] = None,
attributes: dict = None,
attributes: Optional[dict] = None,
end_on_exit: bool = True,
) -> Generator[_TestOtelSpan, None, None]:
resp = self._client.otel_trace_start_span(
name=name,
timestamp=timestamp,
span_kind=span_kind,
parent_id=parent_id,
links=links if links is not None else [],
links=links,
attributes=attributes,
)
span = _TestOtelSpan(self._client, resp["span_id"], resp["trace_id"])
Expand Down
Loading