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

Backend granularity (service.target.*) clarifications #674

Merged
merged 12 commits into from
Oct 3, 2022
29 changes: 16 additions & 13 deletions specs/agents/tracing-spans-service-target.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ Because there are a lots of moving pieces, implementation will be split into mul

(2) Value is always sent by APM agents for compatibility, but they SHOULD NOT rely on it internally.

(3) HTTP spans (and a few other spans) can't have their `resource` value inferred on APM server without relying on a
(3) HTTP spans (and a few other spans) can't have their `resource` value inferred on APM server without relying on a
brittle mapping on span `type` and `subtype` and breaking the breakdown metrics where `type` and `subtype` are not available.

## Implementation details
Expand All @@ -104,29 +104,32 @@ This specification assumes that values for `span.type` and `span.subtype` fit th
- `span.context.service.target.type` should have the same value as `span.subtype` and fallback to `span.type`.
- `span.context.service.target.name` depends on the span context attributes

On agents, the following algorithm should be used to infer the values for `span.context.service.target.*` fields.
On agents, the following algorithm should be used to infer the values for `span.context.service.target.*` fields.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

REVIEW NOTE: This section slightly tweaks the pseudo-code to infer context.service.target.* from other span fields to avoid a couple gotchas that I hit:

  1. The if (!service_target.type) check in JavaScript would accidentally override service_target.type if it had explicitly been set to the empty string.
  2. The if (span.context.db.instance) branch was changed to if (span.context.db) to use the DB logic for DB spans even if the span didn't happen to have a "db.instance" set -- which is less surprising and matches the old pseudo-code for inferring destination.service.resource.

```javascript
// span created on agent
span = {};

if (span.isExit) {
service_target = span.context.service.target;

if (!service_target.type) { // infer type from span type & subtype

// use sub-type if provided, fallback on type othewise

if ('type' in service_target) { // If not manually specified, infer type from span type & subtype.
trentm marked this conversation as resolved.
Show resolved Hide resolved
service_target.type = span.subtype || span.type;
}

if (!service_target.name) { // infer name from span attributes

if (span.context.db.instance) { // database spans
service_target.name = span.context.db.instance;

if ('name' in service_target) { // If not manually specified, infer name from span attributes.

if (span.context.db) { // database spans
if (span.context.db.instance) {
service_target.name = span.context.db.instance;
}
trentm marked this conversation as resolved.
Show resolved Hide resolved

} else if (span.context.message) { // messaging spans
service_target.name = span.context.message.queue.name
if (span.context.message.queue?.name) {
service_target.name = span.context.message.queue?.name
}

} else if (context.http.url) { // http spans
} else if (context.http?.url) { // http spans
service_target.name = getHostFromUrl(context.http.url);
port = getPortFromUrl(context.http.url);
if (port > 0) {
Expand Down