mirror of
https://github.com/moby/moby.git
synced 2026-01-11 10:41:43 +00:00
pkg/stack: move to daemon/internal
This package is used by the daemon to produce a stack-dump, It has no external consumers, so we can move it to daemon/internal. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
@@ -1,59 +0,0 @@
|
||||
package stack
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const stacksLogNameTemplate = "goroutine-stacks-%s.log"
|
||||
|
||||
// Dump outputs the runtime stack to os.StdErr.
|
||||
func Dump() {
|
||||
_ = dump(os.Stderr)
|
||||
}
|
||||
|
||||
// DumpToFile appends the runtime stack into a file named "goroutine-stacks-<timestamp>.log"
|
||||
// in dir and returns the full path to that file. If no directory name is
|
||||
// provided, it outputs to os.Stderr.
|
||||
func DumpToFile(dir string) (string, error) {
|
||||
var f *os.File
|
||||
if dir != "" {
|
||||
path := filepath.Join(dir, fmt.Sprintf(stacksLogNameTemplate, strings.ReplaceAll(time.Now().Format(time.RFC3339), ":", "")))
|
||||
var err error
|
||||
f, err = os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0o666)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "failed to open file to write the goroutine stacks")
|
||||
}
|
||||
defer func() {
|
||||
_ = f.Sync()
|
||||
_ = f.Close()
|
||||
}()
|
||||
} else {
|
||||
f = os.Stderr
|
||||
}
|
||||
return f.Name(), dump(f)
|
||||
}
|
||||
|
||||
func dump(f *os.File) error {
|
||||
var (
|
||||
buf []byte
|
||||
stackSize int
|
||||
)
|
||||
bufferLen := 16384
|
||||
for stackSize == len(buf) {
|
||||
buf = make([]byte, bufferLen)
|
||||
stackSize = runtime.Stack(buf, true)
|
||||
bufferLen *= 2
|
||||
}
|
||||
buf = buf[:stackSize]
|
||||
if _, err := f.Write(buf); err != nil {
|
||||
return errors.Wrap(err, "failed to write goroutine stacks")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package stack
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
)
|
||||
|
||||
func TestDump(t *testing.T) {
|
||||
Dump()
|
||||
}
|
||||
|
||||
func TestDumpToFile(t *testing.T) {
|
||||
tmpDir := t.TempDir()
|
||||
dumpPath, err := DumpToFile(tmpDir)
|
||||
assert.Check(t, err)
|
||||
readFile, _ := os.ReadFile(dumpPath)
|
||||
fileData := string(readFile)
|
||||
assert.Check(t, is.Contains(fileData, "goroutine"))
|
||||
}
|
||||
|
||||
func TestDumpToFileWithEmptyInput(t *testing.T) {
|
||||
path, err := DumpToFile("")
|
||||
assert.Check(t, err)
|
||||
assert.Check(t, is.Equal(os.Stderr.Name(), path))
|
||||
}
|
||||
Reference in New Issue
Block a user