diff --git a/app_test.go b/app_test.go index e38a73570..5b0f4634b 100644 --- a/app_test.go +++ b/app_test.go @@ -423,7 +423,7 @@ func TestWithLoggerErrorUseDefault(t *testing.T) { // Failed: must provide constructor function, got (type *bytes.Buffer) out := string(stderr) - assert.Contains(t, out, "[Fx] SUPPLY\t*zap.Logger\n") + assert.Contains(t, out, "[Fx] SUPPLY\t*zap.Logger from Module \"\"\n") assert.Contains(t, out, "[Fx] ERROR\t\tFailed to initialize custom logger: fx.WithLogger") assert.Contains(t, out, "must provide constructor function, got (type *bytes.Buffer)\n") } diff --git a/fxevent/console.go b/fxevent/console.go index 2fa990197..89e2fc19d 100644 --- a/fxevent/console.go +++ b/fxevent/console.go @@ -63,24 +63,24 @@ func (l *ConsoleLogger) LogEvent(event Event) { if e.Err != nil { l.logf("ERROR\tFailed to supply %v: %v", e.TypeName, e.Err) } else { - l.logf("SUPPLY\t%v", e.TypeName) + l.logf("SUPPLY\t%v from Module \"%v\"", e.TypeName, e.ModuleName) } case *Provided: for _, rtype := range e.OutputTypeNames { - l.logf("PROVIDE\t%v <= %v", rtype, e.ConstructorName) + l.logf("PROVIDE\t%v <= %v from Module \"%v\"", rtype, e.ConstructorName, e.ModuleName) } if e.Err != nil { l.logf("Error after options were applied: %v", e.Err) } case *Decorated: for _, rtype := range e.OutputTypeNames { - l.logf("DECORATE\t%v <= %v", rtype, e.DecoratorName) + l.logf("DECORATE\t%v <= %v from Module \"%v\"", rtype, e.DecoratorName, e.ModuleName) } if e.Err != nil { l.logf("Error after options were applied: %v", e.Err) } case *Invoking: - l.logf("INVOKE\t\t%s", e.FunctionName) + l.logf("INVOKE\t\t%s from Module \"%v\"", e.FunctionName, e.ModuleName) case *Invoked: if e.Err != nil { l.logf("ERROR\t\tfx.Invoke(%v) called from:\n%+vFailed: %v", e.FunctionName, e.Trace, e.Err) diff --git a/fxevent/console_test.go b/fxevent/console_test.go index 0e7f465e6..4fcd4e22d 100644 --- a/fxevent/console_test.go +++ b/fxevent/console_test.go @@ -99,8 +99,8 @@ func TestConsoleLogger(t *testing.T) { }, { name: "Supplied", - give: &Supplied{TypeName: "*bytes.Buffer"}, - want: "[Fx] SUPPLY *bytes.Buffer\n", + give: &Supplied{TypeName: "*bytes.Buffer", ModuleName: "myModule"}, + want: "[Fx] SUPPLY *bytes.Buffer from Module \"myModule\"\n", }, { name: "SuppliedError", @@ -111,17 +111,19 @@ func TestConsoleLogger(t *testing.T) { name: "Provided", give: &Provided{ ConstructorName: "bytes.NewBuffer()", + ModuleName: "myModule", OutputTypeNames: []string{"*bytes.Buffer"}, }, - want: "[Fx] PROVIDE *bytes.Buffer <= bytes.NewBuffer()\n", + want: "[Fx] PROVIDE *bytes.Buffer <= bytes.NewBuffer() from Module \"myModule\"\n", }, { name: "Decorated", give: &Decorated{ DecoratorName: "bytes.NewBuffer()", + ModuleName: "myModule", OutputTypeNames: []string{"*bytes.Buffer"}, }, - want: "[Fx] DECORATE *bytes.Buffer <= bytes.NewBuffer()\n", + want: "[Fx] DECORATE *bytes.Buffer <= bytes.NewBuffer() from Module \"myModule\"\n", }, { name: "DecorateError", @@ -131,7 +133,7 @@ func TestConsoleLogger(t *testing.T) { { name: "Invoking", give: &Invoking{FunctionName: "bytes.NewBuffer()"}, - want: "[Fx] INVOKE bytes.NewBuffer()\n", + want: "[Fx] INVOKE bytes.NewBuffer() from Module \"\"\n", }, { name: "Invoked/Error", diff --git a/fxevent/event.go b/fxevent/event.go index 10c0f2f63..297c14394 100644 --- a/fxevent/event.go +++ b/fxevent/event.go @@ -105,9 +105,12 @@ type OnStopExecuted struct { // Supplied is emitted after a value is added with fx.Supply. type Supplied struct { - // Name of the type of value that was added. + // TypeName is the name of the type of value that was added. TypeName string + // ModuleName is the name of the module in which the value was added to. + ModuleName string + // Err is non-nil if we failed to supply the value. Err error } @@ -122,6 +125,10 @@ type Provided struct { // this constructor. OutputTypeNames []string + // ModuleName is the name of the module in which the constructor was + // provided to. + ModuleName string + // Err is non-nil if we failed to provide this constructor. Err error } @@ -132,6 +139,9 @@ type Decorated struct { // provided to Fx. DecoratorName string + // ModuleName is the name of the module in which the value was added to. + ModuleName string + // OutputTypeNames is a list of names of types that are decorated by // this decorator. OutputTypeNames []string @@ -144,6 +154,9 @@ type Decorated struct { type Invoking struct { // FunctionName is the name of the function that will be invoked. FunctionName string + + // ModuleName is the name of the module in which the value was added to. + ModuleName string } // Invoked is emitted after we invoke a function specified with fx.Invoke, @@ -152,6 +165,9 @@ type Invoked struct { // Functionname is the name of the function that was invoked. FunctionName string + // ModuleName is the name of the module in which the value was added to. + ModuleName string + // Err is non-nil if the function failed to execute. Err error diff --git a/fxevent/zap.go b/fxevent/zap.go index e6b75e5a2..b35cb6f83 100644 --- a/fxevent/zap.go +++ b/fxevent/zap.go @@ -75,39 +75,50 @@ func (l *ZapLogger) LogEvent(event Event) { ) } case *Supplied: - l.Logger.Info("supplied", zap.String("type", e.TypeName), zap.Error(e.Err)) + l.Logger.Info("supplied", + zap.String("type", e.TypeName), + zap.String("module", e.ModuleName), + zap.Error(e.Err)) case *Provided: for _, rtype := range e.OutputTypeNames { l.Logger.Info("provided", zap.String("constructor", e.ConstructorName), + zap.String("module", e.ModuleName), zap.String("type", rtype), ) } if e.Err != nil { l.Logger.Error("error encountered while applying options", + zap.String("module", e.ModuleName), zap.Error(e.Err)) } case *Decorated: for _, rtype := range e.OutputTypeNames { l.Logger.Info("decorated", zap.String("decorator", e.DecoratorName), + zap.String("module", e.ModuleName), zap.String("type", rtype), ) } if e.Err != nil { l.Logger.Error("error encountered while applying options", + zap.String("module", e.ModuleName), zap.Error(e.Err)) } case *Invoking: // Do not log stack as it will make logs hard to read. l.Logger.Info("invoking", - zap.String("function", e.FunctionName)) + zap.String("function", e.FunctionName), + zap.String("module", e.ModuleName), + ) case *Invoked: if e.Err != nil { l.Logger.Error("invoke failed", zap.Error(e.Err), zap.String("stack", e.Trace), - zap.String("function", e.FunctionName)) + zap.String("function", e.FunctionName), + zap.String("module", e.ModuleName), + ) } case *Stopping: l.Logger.Info("received signal", diff --git a/fxevent/zap_test.go b/fxevent/zap_test.go index a6fc4266b..72da2ca54 100644 --- a/fxevent/zap_test.go +++ b/fxevent/zap_test.go @@ -131,7 +131,8 @@ func TestZapLogger(t *testing.T) { give: &Supplied{TypeName: "*bytes.Buffer"}, wantMessage: "supplied", wantFields: map[string]interface{}{ - "type": "*bytes.Buffer", + "type": "*bytes.Buffer", + "module": "", }, }, { @@ -139,20 +140,23 @@ func TestZapLogger(t *testing.T) { give: &Supplied{TypeName: "*bytes.Buffer", Err: someError}, wantMessage: "supplied", wantFields: map[string]interface{}{ - "type": "*bytes.Buffer", - "error": "some error", + "type": "*bytes.Buffer", + "module": "", + "error": "some error", }, }, { name: "Provide", give: &Provided{ ConstructorName: "bytes.NewBuffer()", + ModuleName: "myModule", OutputTypeNames: []string{"*bytes.Buffer"}, }, wantMessage: "provided", wantFields: map[string]interface{}{ "constructor": "bytes.NewBuffer()", "type": "*bytes.Buffer", + "module": "myModule", }, }, { @@ -160,19 +164,22 @@ func TestZapLogger(t *testing.T) { give: &Provided{Err: someError}, wantMessage: "error encountered while applying options", wantFields: map[string]interface{}{ - "error": "some error", + "error": "some error", + "module": "", }, }, { name: "Decorate", give: &Decorated{ DecoratorName: "bytes.NewBuffer()", + ModuleName: "myModule", OutputTypeNames: []string{"*bytes.Buffer"}, }, wantMessage: "decorated", wantFields: map[string]interface{}{ "decorator": "bytes.NewBuffer()", "type": "*bytes.Buffer", + "module": "myModule", }, }, { @@ -180,15 +187,17 @@ func TestZapLogger(t *testing.T) { give: &Decorated{Err: someError}, wantMessage: "error encountered while applying options", wantFields: map[string]interface{}{ - "error": "some error", + "error": "some error", + "module": "", }, }, { name: "Invoking/Success", - give: &Invoking{FunctionName: "bytes.NewBuffer()"}, + give: &Invoking{ModuleName: "myModule", FunctionName: "bytes.NewBuffer()"}, wantMessage: "invoking", wantFields: map[string]interface{}{ "function": "bytes.NewBuffer()", + "module": "myModule", }, }, { @@ -199,6 +208,7 @@ func TestZapLogger(t *testing.T) { "error": "some error", "stack": "", "function": "bytes.NewBuffer()", + "module": "", }, }, { diff --git a/module.go b/module.go index 423155fde..1412ec14a 100644 --- a/module.go +++ b/module.go @@ -129,8 +129,9 @@ func (m *module) provide(p provide) { switch { case p.IsSupply: ev = &fxevent.Supplied{ - TypeName: p.SupplyType.String(), - Err: m.app.err, + TypeName: p.SupplyType.String(), + ModuleName: m.name, + Err: m.app.err, } default: @@ -141,6 +142,7 @@ func (m *module) provide(p provide) { ev = &fxevent.Provided{ ConstructorName: fxreflect.FuncName(p.Target), + ModuleName: m.name, OutputTypeNames: outputNames, Err: m.app.err, } @@ -167,10 +169,12 @@ func (m *module) executeInvoke(i invoke) (err error) { fnName := fxreflect.FuncName(i.Target) m.app.log.LogEvent(&fxevent.Invoking{ FunctionName: fnName, + ModuleName: m.name, }) err = runInvoke(m.scope, i) m.app.log.LogEvent(&fxevent.Invoked{ FunctionName: fnName, + ModuleName: m.name, Err: err, Trace: fmt.Sprintf("%+v", i.Stack), // format stack trace as multi-line }) @@ -188,6 +192,7 @@ func (m *module) decorate() (err error) { m.app.log.LogEvent(&fxevent.Decorated{ DecoratorName: fxreflect.FuncName(decorator.Target), + ModuleName: m.name, OutputTypeNames: outputNames, Err: err, })