diff --git a/ebpf/gmon.go b/ebpf/gmon.go index cfd5048..4dc860d 100644 --- a/ebpf/gmon.go +++ b/ebpf/gmon.go @@ -1,14 +1,10 @@ package ebpf import ( - "bufio" "context" "errors" "fmt" - "io/fs" "log/slog" - "os" - "strings" "github.com/cilium/ebpf" "github.com/cilium/ebpf/link" @@ -28,7 +24,6 @@ func Run(ctx context.Context, config Config) (func(), error) { if err != nil { return func() {}, err } - go logTracePipe(ctx.Done()) ex, err := link.OpenExecutable(config.binPath) if err != nil { return func() {}, err @@ -117,30 +112,3 @@ func linkUprobe( slog.Debug("attach uprobe with address", slog.String("symbol", symbol), slog.String("address", fmt.Sprintf("%#x", address))) return l, nil } - -func logTracePipe(done <-chan struct{}) { - tracePipe, err := os.Open("/sys/kernel/debug/tracing/trace_pipe") - if err != nil { - slog.Error("open trace_pipe", slog.Any("error", err)) - return - } - defer tracePipe.Close() - - go func() { - // Create a bufio.Scanner to read the trace data. - scanner := bufio.NewScanner(tracePipe) - // Read and print the trace data. - for scanner.Scan() { - msg := strings.TrimSpace(scanner.Text()) - if strings.Contains(msg, "gmon") { - slog.Warn(msg) - } - } - if err := scanner.Err(); err != nil { - if !errors.Is(err, fs.ErrClosed) { - slog.Error("read trace_pipe", slog.Any("error", err)) - } - } - }() - <-done -} diff --git a/main.go b/main.go index a295ce9..6d944d3 100644 --- a/main.go +++ b/main.go @@ -1,9 +1,12 @@ package main import ( + "bufio" "context" + "errors" "flag" "fmt" + "io/fs" "log" "log/slog" "net/http" @@ -12,6 +15,7 @@ import ( "os/signal" "runtime" "runtime/trace" + "strings" "github.com/cilium/ebpf/rlimit" "github.com/keisku/gmon/ebpf" @@ -96,6 +100,9 @@ func main() { if err != nil { errlog.Fatalln(err) } + if levelMap[*level] == slog.LevelDebug { + go logTracePipe(ctx.Done()) + } if 1023 < *pprofPort { go func() { _ = http.ListenAndServe(fmt.Sprintf("127.0.0.1:%d", pprofPort), nil) @@ -105,3 +112,28 @@ func main() { slog.Debug("gmon exits") eBPFClose() } + +func logTracePipe(done <-chan struct{}) { + tracePipe, err := os.Open("/sys/kernel/debug/tracing/trace_pipe") + if err != nil { + slog.Error("open trace_pipe", slog.Any("error", err)) + return + } + defer tracePipe.Close() + + go func() { + scanner := bufio.NewScanner(tracePipe) + for scanner.Scan() { + msg := strings.TrimSpace(scanner.Text()) + if strings.Contains(msg, "gmon") { + slog.Debug(msg) + } + } + if err := scanner.Err(); err != nil { + if !errors.Is(err, fs.ErrClosed) { + slog.Error("read trace_pipe", slog.Any("error", err)) + } + } + }() + <-done +}