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

Allow specifying parent and/or follows_from of spans made by #[instrument] #879

Closed
anp opened this issue Aug 3, 2020 · 2 comments · Fixed by #2091 or #2093
Closed

Allow specifying parent and/or follows_from of spans made by #[instrument] #879

anp opened this issue Aug 3, 2020 · 2 comments · Fixed by #2091 or #2093
Labels
crate/attributes Related to the `tracing-attributes` crate crate/tracing Related to the `tracing` crate good first issue Good for newcomers kind/feature New feature or request

Comments

@anp
Copy link
Contributor

anp commented Aug 3, 2020

Feature Request

Crates

tracing & tracing-core, I think.

Motivation

It would be very useful to have support for #[instrument] on methods of a type which holds a span corresponding to its lifecycle.

Proposal

It's not (yet?) possible to inject fields into a struct from a derive, so we'll assume that a user has added a span field to the type whose lifecycle we're tracking:

struct ServiceConnection {
    // ...
    span: tracing::Span,
}

What I think we want is a way for that span to be used as the immediate span for method calls that are annotated with instrument:

impl ServiceConnection {
    #[instrument(parent = "self.span")]
    fn send_response(&self) { ... }
}

In this example, send_response's span would have the value's span as its parent. I think we'd also want a way to say that the method's span follows from the span which was active when the call was made, so that the method's span is connected both to the object and to the active tree of spans. Maybe that should be implicit or have a convenient shorthand?

Alternatives

We could express these semantics in terms of a trait, like

trait Spanned {
    fn span(&self) -> tracing::Span;
}

Then #[instrument] could have a shorthand for using self's span:

impl ServiceConnection {
    #[instrument(spanned)]
    fn send_response(&self) { ... }
}

Related

This relies on #651 to omit self by default from instrumentation. The core idea is to provide a less verbose way to instrument self.

@hawkw
Copy link
Member

hawkw commented Aug 3, 2020

Now that we accept arbitrary expressions in #[instrument], I think it would be quite possible to add a parent argument, so you could write

struct MyGreatStruct {
    /* ... my great fields */
    span: tracing::Span,
}

impl MyGreatStruct {
    #[instrument(parent = &self.span), skip(self)]
    pub fn do_something_interesting(&self, /* ... cool method parameters ... */) {
         /* do something interesting and cool */
    }
}

I think adding this should be pretty simple. We would add a new custom keyword for parent, in this module:

mod kw {
syn::custom_keyword!(fields);
syn::custom_keyword!(skip);
syn::custom_keyword!(level);
syn::custom_keyword!(target);
syn::custom_keyword!(name);
syn::custom_keyword!(err);
}

and then add logic for parsing the parent keyword in InstrumentArgs::parse:
} else if lookahead.peek(kw::target) {
if args.target.is_some() {
return Err(input.error("expected only a single `target` argument"));
}
let target = input.parse::<StrArg<kw::target>>()?.value;
args.target = Some(target);

We would parse any expression after the parent keyword, and interpolate that into the generated span.

We could probably do something similar for a follows_from argument, except that this could take a list of multiple expressions (or be provided multiple times). We would then generate a Span::follows_from call for each argument after the span is created and before it's entered.

This relies on #651 to omit self by default from instrumentation. The core idea is to provide a less verbose way to instrument self.

I don't think this strictly relies on skipping self by default — it can also be used today with skip(self), although that introduces some boilerplate. I'd prefer to add this feature now, rather than waiting for 0.2 (which skipping self fields by default will require) — if there was a PR up for this change, we could merge and release it today.

@hawkw hawkw added crate/attributes Related to the `tracing-attributes` crate crate/tracing Related to the `tracing` crate good first issue Good for newcomers kind/feature New feature or request labels Aug 3, 2020
@bnjjj
Copy link
Contributor

bnjjj commented Oct 1, 2020

I will implement this :) thanks for the explanation

pandaman64 added a commit to pandaman64/tracing that referenced this issue Feb 16, 2021
hawkw pushed a commit that referenced this issue Apr 25, 2022
#2091)

This PR extends the `#[instrument]` attribute to accept an optionally
`parent = …` argument that provides an explicit parent to the generated
`Span`.

## Motivation

This PR resolves #2021 and partially resolves #879. (It only partly
resolves #879 in that it only provides a mechanism for specifying an
explicit parent, but *not* for invoking `follows_from`.)

## Solution

This PR follows the implementation strategy articulated by @hawkw:
#879 (comment).
The user-provided value to the `parent` argument may be any expression,
and this expression is provided directly to the invocation of
[`span!`](https://tracing.rs/tracing/macro.span.html).
jswrenn added a commit to jswrenn/tracing that referenced this issue Apr 25, 2022
The optional `follows_from` argument allows users to specify any
number of `Span::follows_from` relationships. The value to this
argument is an expression of type:
  `impl IntoIterator<Item = impl Into<Option<Id>>>`

Fixes: tokio-rs#879
hawkw pushed a commit that referenced this issue Apr 26, 2022
This PR extends the `#[instrument]` attribute to accept an optional
`follows_from = …` argument that supplies any number of
`Span::follows_from` relationships to the generated `Span`.

## Motivation

This PR resolves #879.

## Solution

This PR largely follows the implementation strategy articulated by
@hawkw:
#879 (comment)

In that comment, @hawkw suggests taking one of two approaches:
1. each `follows_from` relationship is supplied with a distinct
   `follows_from` argument
2. the `follows_from` argument is provided once, and its value is a
   **list** of indirect causes

I take the second approach, since it is slightly more flexible: it
allows for the number of indirect causes to vary at runtime.

This addition is complemented by changes to `tracing-mock` to permit
making `follows_from` assertions for testing purposes.
hawkw pushed a commit that referenced this issue Apr 26, 2022
#2091)

This PR extends the `#[instrument]` attribute to accept an optionally
`parent = …` argument that provides an explicit parent to the generated
`Span`.

## Motivation

This PR resolves #2021 and partially resolves #879. (It only partly
resolves #879 in that it only provides a mechanism for specifying an
explicit parent, but *not* for invoking `follows_from`.)

## Solution

This PR follows the implementation strategy articulated by @hawkw:
#879 (comment).
The user-provided value to the `parent` argument may be any expression,
and this expression is provided directly to the invocation of
[`span!`](https://tracing.rs/tracing/macro.span.html).
hawkw pushed a commit that referenced this issue Apr 26, 2022
This PR extends the `#[instrument]` attribute to accept an optional
`follows_from = …` argument that supplies any number of
`Span::follows_from` relationships to the generated `Span`.

## Motivation

This PR resolves #879.

## Solution

This PR largely follows the implementation strategy articulated by
@hawkw:
#879 (comment)

In that comment, @hawkw suggests taking one of two approaches:
1. each `follows_from` relationship is supplied with a distinct
   `follows_from` argument
2. the `follows_from` argument is provided once, and its value is a
   **list** of indirect causes

I take the second approach, since it is slightly more flexible: it
allows for the number of indirect causes to vary at runtime.

This addition is complemented by changes to `tracing-mock` to permit
making `follows_from` assertions for testing purposes.
hawkw pushed a commit that referenced this issue Apr 26, 2022
#2091)

This PR extends the `#[instrument]` attribute to accept an optionally
`parent = …` argument that provides an explicit parent to the generated
`Span`.

## Motivation

This PR resolves #2021 and partially resolves #879. (It only partly
resolves #879 in that it only provides a mechanism for specifying an
explicit parent, but *not* for invoking `follows_from`.)

## Solution

This PR follows the implementation strategy articulated by @hawkw:
#879 (comment).
The user-provided value to the `parent` argument may be any expression,
and this expression is provided directly to the invocation of
[`span!`](https://tracing.rs/tracing/macro.span.html).
hawkw pushed a commit that referenced this issue Apr 26, 2022
This PR extends the `#[instrument]` attribute to accept an optional
`follows_from = …` argument that supplies any number of
`Span::follows_from` relationships to the generated `Span`.

## Motivation

This PR resolves #879.

## Solution

This PR largely follows the implementation strategy articulated by
@hawkw:
#879 (comment)

In that comment, @hawkw suggests taking one of two approaches:
1. each `follows_from` relationship is supplied with a distinct
   `follows_from` argument
2. the `follows_from` argument is provided once, and its value is a
   **list** of indirect causes

I take the second approach, since it is slightly more flexible: it
allows for the number of indirect causes to vary at runtime.

This addition is complemented by changes to `tracing-mock` to permit
making `follows_from` assertions for testing purposes.
hawkw pushed a commit that referenced this issue Apr 26, 2022
#2091)

This PR extends the `#[instrument]` attribute to accept an optionally
`parent = …` argument that provides an explicit parent to the generated
`Span`.

## Motivation

This PR resolves #2021 and partially resolves #879. (It only partly
resolves #879 in that it only provides a mechanism for specifying an
explicit parent, but *not* for invoking `follows_from`.)

## Solution

This PR follows the implementation strategy articulated by @hawkw:
#879 (comment).
The user-provided value to the `parent` argument may be any expression,
and this expression is provided directly to the invocation of
[`span!`](https://tracing.rs/tracing/macro.span.html).
hawkw pushed a commit that referenced this issue Apr 26, 2022
This PR extends the `#[instrument]` attribute to accept an optional
`follows_from = …` argument that supplies any number of
`Span::follows_from` relationships to the generated `Span`.

## Motivation

This PR resolves #879.

## Solution

This PR largely follows the implementation strategy articulated by
@hawkw:
#879 (comment)

In that comment, @hawkw suggests taking one of two approaches:
1. each `follows_from` relationship is supplied with a distinct
   `follows_from` argument
2. the `follows_from` argument is provided once, and its value is a
   **list** of indirect causes

I take the second approach, since it is slightly more flexible: it
allows for the number of indirect causes to vary at runtime.

This addition is complemented by changes to `tracing-mock` to permit
making `follows_from` assertions for testing purposes.
hawkw pushed a commit that referenced this issue Apr 26, 2022
This PR extends the `#[instrument]` attribute to accept an optional
`follows_from = …` argument that supplies any number of
`Span::follows_from` relationships to the generated `Span`.

## Motivation

This PR resolves #879.

## Solution

This PR largely follows the implementation strategy articulated by
@hawkw:
#879 (comment)

In that comment, @hawkw suggests taking one of two approaches:
1. each `follows_from` relationship is supplied with a distinct
   `follows_from` argument
2. the `follows_from` argument is provided once, and its value is a
   **list** of indirect causes

I take the second approach, since it is slightly more flexible: it
allows for the number of indirect causes to vary at runtime.

This addition is complemented by changes to `tracing-mock` to permit
making `follows_from` assertions for testing purposes.
hawkw pushed a commit that referenced this issue Apr 26, 2022
This PR extends the `#[instrument]` attribute to accept an optional
`follows_from = …` argument that supplies any number of
`Span::follows_from` relationships to the generated `Span`.

## Motivation

This PR resolves #879.

## Solution

This PR largely follows the implementation strategy articulated by
@hawkw:
#879 (comment)

In that comment, @hawkw suggests taking one of two approaches:
1. each `follows_from` relationship is supplied with a distinct
   `follows_from` argument
2. the `follows_from` argument is provided once, and its value is a
   **list** of indirect causes

I take the second approach, since it is slightly more flexible: it
allows for the number of indirect causes to vary at runtime.

This addition is complemented by changes to `tracing-mock` to permit
making `follows_from` assertions for testing purposes.
hawkw pushed a commit that referenced this issue Apr 26, 2022
#2091)

This PR extends the `#[instrument]` attribute to accept an optionally
`parent = …` argument that provides an explicit parent to the generated
`Span`.

## Motivation

This PR resolves #2021 and partially resolves #879. (It only partly
resolves #879 in that it only provides a mechanism for specifying an
explicit parent, but *not* for invoking `follows_from`.)

## Solution

This PR follows the implementation strategy articulated by @hawkw:
#879 (comment).
The user-provided value to the `parent` argument may be any expression,
and this expression is provided directly to the invocation of
[`span!`](https://tracing.rs/tracing/macro.span.html).
hawkw pushed a commit that referenced this issue Apr 26, 2022
This PR extends the `#[instrument]` attribute to accept an optional
`follows_from = …` argument that supplies any number of
`Span::follows_from` relationships to the generated `Span`.

## Motivation

This PR resolves #879.

## Solution

This PR largely follows the implementation strategy articulated by
@hawkw:
#879 (comment)

In that comment, @hawkw suggests taking one of two approaches:
1. each `follows_from` relationship is supplied with a distinct
   `follows_from` argument
2. the `follows_from` argument is provided once, and its value is a
   **list** of indirect causes

I take the second approach, since it is slightly more flexible: it
allows for the number of indirect causes to vary at runtime.

This addition is complemented by changes to `tracing-mock` to permit
making `follows_from` assertions for testing purposes.
liuhaozhan added a commit to liuhaozhan/tracing that referenced this issue Nov 17, 2022
…` (#2091)

This PR extends the `#[instrument]` attribute to accept an optionally
`parent = …` argument that provides an explicit parent to the generated
`Span`.

## Motivation

This PR resolves #2021 and partially resolves #879. (It only partly
resolves #879 in that it only provides a mechanism for specifying an
explicit parent, but *not* for invoking `follows_from`.)

## Solution

This PR follows the implementation strategy articulated by @hawkw:
tokio-rs/tracing#879 (comment).
The user-provided value to the `parent` argument may be any expression,
and this expression is provided directly to the invocation of
[`span!`](https://tracing.rs/tracing/macro.span.html).
liuhaozhan added a commit to liuhaozhan/tracing that referenced this issue Nov 17, 2022
This PR extends the `#[instrument]` attribute to accept an optional
`follows_from = …` argument that supplies any number of
`Span::follows_from` relationships to the generated `Span`.

## Motivation

This PR resolves #879.

## Solution

This PR largely follows the implementation strategy articulated by
@hawkw:
tokio-rs/tracing#879 (comment)

In that comment, @hawkw suggests taking one of two approaches:
1. each `follows_from` relationship is supplied with a distinct
   `follows_from` argument
2. the `follows_from` argument is provided once, and its value is a
   **list** of indirect causes

I take the second approach, since it is slightly more flexible: it
allows for the number of indirect causes to vary at runtime.

This addition is complemented by changes to `tracing-mock` to permit
making `follows_from` assertions for testing purposes.
kaffarell pushed a commit to kaffarell/tracing that referenced this issue May 22, 2024
This PR extends the `#[instrument]` attribute to accept an optional
`follows_from = …` argument that supplies any number of
`Span::follows_from` relationships to the generated `Span`.

## Motivation

This PR resolves tokio-rs#879.

## Solution

This PR largely follows the implementation strategy articulated by
@hawkw:
tokio-rs#879 (comment)

In that comment, @hawkw suggests taking one of two approaches:
1. each `follows_from` relationship is supplied with a distinct
   `follows_from` argument
2. the `follows_from` argument is provided once, and its value is a
   **list** of indirect causes

I take the second approach, since it is slightly more flexible: it
allows for the number of indirect causes to vary at runtime.

This addition is complemented by changes to `tracing-mock` to permit
making `follows_from` assertions for testing purposes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
crate/attributes Related to the `tracing-attributes` crate crate/tracing Related to the `tracing` crate good first issue Good for newcomers kind/feature New feature or request
Projects
None yet
3 participants