From 977bf1cad992e803ea9374a1b7e9a8962c76a556 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 9 Jun 2021 21:51:59 -0700 Subject: [PATCH] fix(lotus-sim): write pprof profiles to a directory We need to know the sizes up-front for tar, and that's not happening. --- cmd/lotus-sim/profile.go | 43 +++++++++++++++++++++++----------------- cmd/lotus-sim/run.go | 2 +- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/cmd/lotus-sim/profile.go b/cmd/lotus-sim/profile.go index f2058949f..63e0ef3bd 100644 --- a/cmd/lotus-sim/profile.go +++ b/cmd/lotus-sim/profile.go @@ -1,12 +1,11 @@ package main import ( - "archive/tar" "context" "fmt" - "io" "os" "os/signal" + "path/filepath" "runtime/pprof" "time" @@ -14,32 +13,35 @@ import ( ) func takeProfiles(ctx context.Context) (fname string, _err error) { - file, err := os.CreateTemp(".", ".profiles*.tar") + dir, err := os.MkdirTemp(".", ".profiles-temp*") if err != nil { return "", err } - defer file.Close() - if err := writeProfiles(ctx, file); err != nil { - _ = os.Remove(file.Name()) + if err := writeProfiles(ctx, dir); err != nil { + _ = os.RemoveAll(dir) return "", err } - fname = fmt.Sprintf("pprof-simulation-%s.tar", time.Now()) - if err := os.Rename(file.Name(), fname); err != nil { - _ = os.Remove(file.Name()) + fname = fmt.Sprintf("pprof-simulation-%s", time.Now().Format(time.RFC3339)) + if err := os.Rename(dir, fname); err != nil { + _ = os.RemoveAll(dir) return "", err } return fname, nil } -func writeProfiles(ctx context.Context, w io.Writer) error { - tw := tar.NewWriter(w) +func writeProfiles(ctx context.Context, dir string) error { for _, profile := range pprof.Profiles() { - if err := tw.WriteHeader(&tar.Header{Name: profile.Name()}); err != nil { + file, err := os.Create(filepath.Join(dir, profile.Name()+".pprof.gz")) + if err != nil { return err } - if err := profile.WriteTo(tw, 0); err != nil { + if err := profile.WriteTo(file, 0); err != nil { + _ = file.Close() + return err + } + if err := file.Close(); err != nil { return err } if err := ctx.Err(); err != nil { @@ -47,20 +49,25 @@ func writeProfiles(ctx context.Context, w io.Writer) error { } } - if err := tw.WriteHeader(&tar.Header{Name: "cpu"}); err != nil { + file, err := os.Create(filepath.Join(dir, "cpu.pprof.gz")) + if err != nil { return err } - if err := pprof.StartCPUProfile(tw); err != nil { + + if err := pprof.StartCPUProfile(file); err != nil { + _ = file.Close() return err } select { case <-time.After(30 * time.Second): case <-ctx.Done(): - pprof.StopCPUProfile() - return ctx.Err() } pprof.StopCPUProfile() - return tw.Close() + err = file.Close() + if err := ctx.Err(); err != nil { + return err + } + return err } func profileOnSignal(cctx *cli.Context, signals ...os.Signal) { diff --git a/cmd/lotus-sim/run.go b/cmd/lotus-sim/run.go index 58eeb1a5e..ba6534b4b 100644 --- a/cmd/lotus-sim/run.go +++ b/cmd/lotus-sim/run.go @@ -15,7 +15,7 @@ var runSimCommand = &cli.Command{ Signals: - SIGUSR1: Print information about the current simulation (equivalent to 'lotus-sim info'). -- SIGUSR2: Write a pprof profile to pprof-simulation-$DATE.tar`, +- SIGUSR2: Write pprof profiles to ./pprof-simulation-$DATE/`, Flags: []cli.Flag{ &cli.IntFlag{ Name: "epochs",