Skip to content

Commit

Permalink
feat: add runtime to fxevent.Run events (#1240)
Browse files Browse the repository at this point in the history
This PR adds runtime info of constructors and decorators to Run events,
and the runtime of every constructor and decorator (including ones
created
by fx.Supply and fx.Replace) will be logged when logging Run events.
This
will help us identify which part of the dependency graph takes long to
construct.

Closes #1213
  • Loading branch information
tchung1118 authored Oct 9, 2024
1 parent 99eee83 commit 57f8ff4
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 20 deletions.
2 changes: 1 addition & 1 deletion fxevent/console.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func (l *ConsoleLogger) LogEvent(event Event) {
if e.ModuleName != "" {
moduleStr = fmt.Sprintf(" from module %q", e.ModuleName)
}
l.logf("RUN\t%v: %v%v", e.Kind, e.Name, moduleStr)
l.logf("RUN\t%v: %v in %s%v", e.Kind, e.Name, e.Runtime, moduleStr)
if e.Err != nil {
l.logf("Error returned: %+v", e.Err)
}
Expand Down
16 changes: 9 additions & 7 deletions fxevent/console_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,27 +267,29 @@ func TestConsoleLogger(t *testing.T) {
},
{
name: "Run",
give: &Run{Name: "bytes.NewBuffer()", Kind: "constructor"},
want: "[Fx] RUN\tconstructor: bytes.NewBuffer()\n",
give: &Run{Name: "bytes.NewBuffer()", Kind: "constructor", Runtime: 10 * time.Nanosecond},
want: "[Fx] RUN\tconstructor: bytes.NewBuffer() in 10ns\n",
},
{
name: "Run with module",
give: &Run{
Name: "bytes.NewBuffer()",
Kind: "constructor",
Runtime: 50 * time.Millisecond,
ModuleName: "myModule",
},
want: "[Fx] RUN\tconstructor: bytes.NewBuffer() from module \"myModule\"\n",
want: "[Fx] RUN\tconstructor: bytes.NewBuffer() in 50ms from module \"myModule\"\n",
},
{
name: "RunError",
give: &Run{
Name: "bytes.NewBuffer()",
Kind: "constructor",
Err: errors.New("terrible constructor error"),
Name: "bytes.NewBuffer()",
Kind: "constructor",
Runtime: 5 * time.Second,
Err: errors.New("terrible constructor error"),
},
want: joinLines(
"[Fx] RUN\tconstructor: bytes.NewBuffer()",
"[Fx] RUN\tconstructor: bytes.NewBuffer() in 5s",
"[Fx] Error returned: terrible constructor error",
),
},
Expand Down
3 changes: 3 additions & 0 deletions fxevent/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,9 @@ type Run struct {
// ModuleName is the name of the module in which the function belongs.
ModuleName string

// Runtime specifies how long it took to run this function.
Runtime time.Duration

// Err is non-nil if the function returned an error.
// If fx.RecoverFromPanics is used, this will include panics.
Err error
Expand Down
1 change: 1 addition & 0 deletions fxevent/slog.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ func (l *SlogLogger) LogEvent(event Event) {
l.logEvent("run",
slog.String("name", e.Name),
slog.String("kind", e.Kind),
slog.String("runtime", e.Runtime.String()),
slogMaybeModuleField(e.ModuleName),
)
}
Expand Down
15 changes: 9 additions & 6 deletions fxevent/slog_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -342,11 +342,12 @@ func TestSlogLogger(t *testing.T) {
},
{
name: "Run",
give: &Run{Name: "bytes.NewBuffer()", Kind: "constructor"},
give: &Run{Name: "bytes.NewBuffer()", Kind: "constructor", Runtime: 3 * time.Millisecond},
wantMessage: "run",
wantFields: map[string]interface{}{
"name": "bytes.NewBuffer()",
"kind": "constructor",
"name": "bytes.NewBuffer()",
"kind": "constructor",
"runtime": "3ms",
},
},
{
Expand All @@ -355,12 +356,14 @@ func TestSlogLogger(t *testing.T) {
Name: "bytes.NewBuffer()",
Kind: "constructor",
ModuleName: "myModule",
Runtime: 3 * time.Millisecond,
},
wantMessage: "run",
wantFields: map[string]interface{}{
"name": "bytes.NewBuffer()",
"kind": "constructor",
"module": "myModule",
"name": "bytes.NewBuffer()",
"kind": "constructor",
"module": "myModule",
"runtime": "3ms",
},
},
{
Expand Down
1 change: 1 addition & 0 deletions fxevent/zap.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ func (l *ZapLogger) LogEvent(event Event) {
l.logEvent("run",
zap.String("name", e.Name),
zap.String("kind", e.Kind),
zap.String("runtime", e.Runtime.String()),
moduleField(e.ModuleName),
)
}
Expand Down
15 changes: 9 additions & 6 deletions fxevent/zap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,11 +274,12 @@ func TestZapLogger(t *testing.T) {
},
{
name: "Run",
give: &Run{Name: "bytes.NewBuffer()", Kind: "constructor"},
give: &Run{Name: "bytes.NewBuffer()", Kind: "constructor", Runtime: time.Second},
wantMessage: "run",
wantFields: map[string]interface{}{
"name": "bytes.NewBuffer()",
"kind": "constructor",
"name": "bytes.NewBuffer()",
"kind": "constructor",
"runtime": "1s",
},
},
{
Expand All @@ -287,12 +288,14 @@ func TestZapLogger(t *testing.T) {
Name: "bytes.NewBuffer()",
Kind: "constructor",
ModuleName: "myModule",
Runtime: time.Millisecond,
},
wantMessage: "run",
wantFields: map[string]interface{}{
"name": "bytes.NewBuffer()",
"kind": "constructor",
"module": "myModule",
"name": "bytes.NewBuffer()",
"kind": "constructor",
"module": "myModule",
"runtime": "1ms",
},
},
{
Expand Down
4 changes: 4 additions & 0 deletions module.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ func (m *module) provide(p provide) {
Name: funcName,
Kind: "provide",
ModuleName: m.name,
Runtime: ci.Runtime,
Err: ci.Error,
})
}),
Expand Down Expand Up @@ -232,6 +233,7 @@ func (m *module) supply(p provide) {
m.log.LogEvent(&fxevent.Run{
Name: fmt.Sprintf("stub(%v)", typeName),
Kind: "supply",
Runtime: ci.Runtime,
ModuleName: m.name,
})
}),
Expand Down Expand Up @@ -356,6 +358,7 @@ func (m *module) decorate(d decorator) (err error) {
Name: funcName,
Kind: "decorate",
ModuleName: m.name,
Runtime: ci.Runtime,
Err: ci.Error,
})
}),
Expand Down Expand Up @@ -387,6 +390,7 @@ func (m *module) replace(d decorator) error {
Name: fmt.Sprintf("stub(%v)", typeName),
Kind: "replace",
ModuleName: m.name,
Runtime: ci.Runtime,
Err: ci.Error,
})
}),
Expand Down

0 comments on commit 57f8ff4

Please sign in to comment.