Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 38 additions & 2 deletions command/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ func (c *DebugCommand) Flags() *FlagSets {
Usage: "Target to capture, defaulting to all if none specified. " +
"This can be specified multiple times to capture multiple targets. " +
"Available targets are: config, host, metrics, pprof, " +
"replication-status, server-status.",
"replication-status, server-status, log.",
})

return set
Expand Down Expand Up @@ -477,7 +477,7 @@ func (c *DebugCommand) preflight(rawArgs []string) (string, error) {
}

func (c *DebugCommand) defaultTargets() []string {
return []string{"config", "host", "metrics", "pprof", "replication-status", "server-status"}
return []string{"config", "host", "metrics", "pprof", "replication-status", "server-status", "log"}
}

func (c *DebugCommand) captureStaticTargets() error {
Expand Down Expand Up @@ -513,6 +513,7 @@ func (c *DebugCommand) capturePollingTargets() error {
var g run.Group

ctx, cancelFunc := context.WithTimeout(context.Background(), c.flagDuration+debugDurationGrace)
defer cancelFunc()

// This run group watches for interrupt or duration
g.Add(func() error {
Expand Down Expand Up @@ -576,6 +577,15 @@ func (c *DebugCommand) capturePollingTargets() error {
})
}

if strutil.StrListContains(c.flagTargets, "log") {
g.Add(func() error {
_ = c.writeLogs(ctx)
return nil
}, func(error) {
cancelFunc()
})
}

// We shouldn't bump across errors since none is returned by the interrupts,
// but we error check for sanity here.
if err := g.Run(); err != nil {
Expand Down Expand Up @@ -981,3 +991,29 @@ func (c *DebugCommand) captureError(target string, err error) {
})
c.errLock.Unlock()
}

func (c *DebugCommand) writeLogs(ctx context.Context) error {
out, err := os.Create(filepath.Join(c.flagOutput, "vault.log"))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to close out?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

D'oh, ty!

if err != nil {
return err
}
logCh, err := c.cachedClient.Sys().Monitor(ctx, "trace")
if err != nil {
return err
}

for {
select {
case log, ok := <-logCh:
if !ok {
return nil
}
_, err = out.WriteString(log)
if err != nil {
return err
}
case <-ctx.Done():
return nil
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What causes this loop to terminate other than errors? I don't think the context will time out, will it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the context passed in has a timeout.

}
1 change: 1 addition & 0 deletions command/debug_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,7 @@ func TestDebugCommand_PartialPermissions(t *testing.T) {
case fh.Name == filepath.Join(basePath, "index.json"):
case fh.Name == filepath.Join(basePath, "replication_status.json"):
case fh.Name == filepath.Join(basePath, "server_status.json"):
case fh.Name == filepath.Join(basePath, "vault.log"):
default:
return fmt.Errorf("unexpected file: %s", fh.Name)
}
Expand Down