Effect.fn should automatically apply withLogSpan
What is the problem this feature would solve?
Effect.fn has been a tremendous improvement for dx. It removes boilerplate required to add span names to traces. Howvever it does not add span names to logs. Span names in logs can be useful information for developers and LLMs.
Before Effect.fn:
const MyService = {
myFn: (arg: string) =>
Effect.succeed(arg).pipe(
Effect.withSpan("MyService.myFn"),
Effect.withLogSpan("MyService.myFn")
)
}
With Effect.fn today:
Effect.fn("MyService.myFn")(
function* (arg) { return arg; },
Effect.withLogSpan("MyService.myFn") // ← not added automatically
)
What is the feature you are proposing to solve the problem?
Effect.fn should automatically add .withLogSpan the same way it adds .withSpan.
Proposed:
Effect.fn("MyService.myFn")(
function* (arg) { return arg; },
) // annotates traces and logs with the name of the fn
What alternatives have you considered?
Wrapping Effect.fn to perform this automatically, using the wrapped version instead of Effect.fn in the codebase
Relying on tracing only (inevitably we still have logs, somewhat impractical for contexts like tests or scripts)
Won't this make logs very noisy when you have a deep stack? I like the idea but I'd want more control with log spans. Unlike stack traces where you want to follow the steps through a trace, log spans are more for timing and observability imho.
Would be nice to have more control.
@dpnova
Won't this make logs very noisy when you have a deep stack?
So I think it would be up to the logger implementation. This would technically just make the information available to the logging pipeline.
In most contexts with a custom logger I just print out the head span, maybe its parent on an annotation/property.
I’m not sure whether default effect loggers do this but I thought so…
@dpnova
Won't this make logs very noisy when you have a deep stack?
So I think it would be up to the logger implementation. This would technically just make the information available to the logging pipeline.
In most contexts with a custom logger I just print out the head span, maybe its parent on an annotation/property.
I’m not sure whether default effect loggers do this but I thought so…
This is what I do. I also pull in annotations from them and don't use logger spans at all.
Logger.make<unknown, Message>( ({ annotations, cause, context, date, fiberId, logLevel, message }) => {
const spanAnnotations = FiberRefs.get(context, FiberRef.currentContext).pipe(
Option.flatMap(Context.getOption(Tracer.ParentSpan))
);
...
});