Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use Dig Callbacks to Emit Run Events (#1077)
Folks have been asking for additional observability into what constructors/decorators they give to Fx actually get invoked. With uber-go/dig#377 being merged, we can use Dig callbacks to provide this observability point. This PR does this by registering callbacks with Dig that generate a new [fxevent](https://pkg.go.dev/go.uber.org/fx/fxevent#Event) called `fxevent.Run`, containing information about the provided/decorated function that was invoked by Dig: ```go // Run is emitted after a constructor, decorator, or supply/replace stub is run by Fx. type Run struct { // Name is the name of the function that was run. Name string // Kind indicates which Fx option was used to pass along the function. // It is either "provide", "decorate", "supply", or "replace". Kind string // ModuleName is the name of the module in which the function belongs. ModuleName string // Err is non-nil if the function returned an error. // If fx.RecoverFromPanics is used, this will include panics. Err error } ``` The default [fxevent.Logger](https://pkg.go.dev/go.uber.org/fx/fxevent#Logger)s have been updated to print to the console/log with Zap accordingly. Folks can use custom `fxevent.Logger`s to respond to these events as they would any other event: ```go type myLogger struct{ /* ... */ } func (l *myLogger) LogEvent(event fxevent.Event) { switch e := event.(type) { // ... case *fxevent.Run: // can access e.Name, e.Kind, e.ModuleName, and e.Err // ... } } func main() { app := fx.New( fx.WithLogger(func() fxevent.Logger { return &myLogger{} } ), // ... ) } ``` I wrote a small demo showing a custom logger like this can be used to identify "dead functions" within Fx: https:/JacobOaks/fx_dead_code_demo. This PR also adds stack trace information into the `Provided`, `Decorated`, `Supplied`, and `Decorated` fxevents to aid folks with larger codebases that consume many modules, who might otherwise have a hard time finding where exactly a "dead function" is being given to Fx with just the `name` and `ModuleName` fields of the `Run` event. Fx was already keeping track of this information, so I don't think this addition incurs too much additional overhead for Fx, but if folks disagree we can remove this addition or perhaps make it opt-in by gating it behind a new option `fx.ReportStackTraces()` or something.
- Loading branch information