-
Notifications
You must be signed in to change notification settings - Fork 12
Add a TracingMacros module providing the @Traced macro #42
Conversation
**Motivation:** Adding tracing to functions can be a slightly invasive modification because using `withSpan` requires re-indenting the whole function. It also requires some duplicated modifications when modifying the effects signatures of functions. We want a macro to perform this transformation. **Modifications:** Introduce a TracingMacros module to provide macros for the Tracing package. Add a `@Traced` macro that performs the transformation. This is defined as a separate product so that users who don't want to pay the compile-time cost of macros don't have to use it, you opt-in to that cost by depending on the TracingMacros module. The `@Traced` macro is only available in Swift 6.0 compilers since function body macros were introduced in Swift 6.0.
**Motivation:** We need to support `@Traced` on async and throws functions to make it compatible with everywhere people want to use them. **Modifications:** Based on the effects signature of the attached function we apply try/await as appropriate. But, if the function is async/throws but those effects aren't actually used in the function body, this causes a new warning because the closure isn't inferred to be async and/or throws. To avoid those warnings, we also apply matching effects specifiers to the withSpan closure. **Result:** The `@Traced` macro is now usable on all functions.
**Motivation:** The `@Traced` macro isn't sufficient for all cases of `withSpan` because it doesn't allow the same customization of the span. We need to expose those parameters to the macro. **Modifications:** First, allow overriding the regular parameters of the withSpan call: setting the operationName, the context, and the kind. If it's not specified, it's not passed to the function, which means the function remains the source of truth for default arguments. Also allow overriding the span name, which controls the variable binding in the closure body. This is primarily useful for avoiding shadowing an outer "span" variable. **Result:** Users of the macro can use the operationName, context, and kind parameters to customize the span like `withSpan`, and can use the span parameter to customize the variable introduced by the macro's expansion.
**Motivation:** We want to allow richer customization of the operation name in the `@Traced` macro, in particular the difference between the different ways you can view a function name. **Modifications:** - Add a TracedOperationName type that represents the kinds of operation names we want to support. - Change the `@Traced` macro interface and expansion to use the new operation name type. **Result:** Now you can write `@Traced(.baseName)`, `@Traced(.fullName)` as well as `@Traced("custom name here")`, giving more flexibility between types of operation names.
This didn't need to be `@_exported import`, this change cleans up the docs
Ok, awesome! Let's include this in the extras repo then rather the main then. As folks indicated bumping the required OS would have been technically breaking. Thanks @Lukasa for chiming in |
We want to give folks a moment to debate the swift-syntax issue before cutting a release. But imho there's nothing we as a package can do to improve the situation; the package manager and how swift deals with macros needs to improve really to avoid these issues, unless we'd say we don't do any macros anywhere until then -- but that's not ok either tbh, we literarily developed a language feature for this specific macro, so let's have it available as opt in to folks. |
assertMacroExpansion( | ||
""" | ||
@Traced | ||
func syncThrowingExample(param: Int) throws { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will you get a warning in the expanded macro if the traced function is marked as throws
but doesn't actually try
anywhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same with async/await
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope—this is what motivated doing the extra work to copy over the effect specifier on the closure instead of leaving it inferred. See the commit message on 3951ba2 for a discussion of that.
marking this as semver/none because we reverted the change. |
This provides a
@Traced
macro which adds a tracing span around the body of the function. This macro allows customizing theoperationName
, thecontext
, and thekind
of the span, same as thewithSpan
function. It also exposes the span itself into the scope of the function, with a customizable name.This doesn't attempt to support automatically adding parameters as attributes, because the scoping rules of attached macros aren't very amenable to controlling that. That could be added in the future if it's judged necessary.
Examples:
expands to:
Notes:
This places the macros into a separate product so that users who don't want to pay the compile-time cost of macros don't have to use it, you opt-in to that cost by depending on the
TracingMacros
module.This is an alternative to apple/swift-distributed-tracing#157 to avoid a semver major bump, since the minimum platform versions are already set here.
Resolves apple/swift-distributed-tracing#125