Skip to content
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
851e42f
refactor: replace logrus for global slog logger
rogercoll Oct 24, 2025
7a0d52f
Merge branch 'main' into set_global_logger
rogercoll Oct 24, 2025
0c99916
set default info level and remove file source
rogercoll Oct 24, 2025
b98c85b
remove logrus license
rogercoll Oct 24, 2025
530d0ce
Merge branch 'main' into set_global_logger
rogercoll Oct 24, 2025
586fdee
fix: ebpf amd blog
rogercoll Oct 24, 2025
49353b6
fix: coredump logger usage
rogercoll Oct 24, 2025
2facbb6
fix non constant strings
rogercoll Oct 24, 2025
fc2c5f6
Update internal/global/logging.go
rogercoll Oct 24, 2025
4eadd9f
Update internal/global/logging.go
rogercoll Oct 28, 2025
b2c88d2
Update internal/global/logging.go
rogercoll Oct 28, 2025
7f23a13
add helper function to set Debug global logger
rogercoll Oct 28, 2025
82d98d5
map log.Printf statements to Info level
rogercoll Oct 28, 2025
1064fd2
Merge branch 'main' into set_global_logger
rogercoll Oct 28, 2025
49405a2
fix non-constant string
rogercoll Oct 28, 2025
6c29f67
refactor: move global package to log
rogercoll Oct 28, 2025
2ce403c
Merge branch 'main' into set_global_logger
rogercoll Oct 29, 2025
1a5537f
Merge branch 'main' into set_global_logger
rogercoll Oct 30, 2025
74824b3
Update collector/factory.go
rogercoll Oct 30, 2025
64f9b21
Update internal/global/log/logging.go
rogercoll Oct 30, 2025
1236b9c
remove global level path
rogercoll Oct 30, 2025
6861c47
Merge branch 'main' into set_global_logger
rogercoll Nov 3, 2025
853ae6e
Merge branch 'main' into set_global_logger
rogercoll Nov 4, 2025
2e0ed68
fix: integration tests debug log
rogercoll Nov 4, 2025
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
21 changes: 0 additions & 21 deletions LICENSES/github.com/sirupsen/logrus/LICENSE

This file was deleted.

5 changes: 5 additions & 0 deletions collector/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,19 @@ package collector // import "go.opentelemetry.io/ebpf-profiler/collector"
import (
"context"
"errors"
"log/slog"
"time"

"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/consumer/xconsumer"
"go.opentelemetry.io/collector/receiver"
"go.opentelemetry.io/collector/receiver/xreceiver"
"go.uber.org/zap/exp/zapslog"

"go.opentelemetry.io/ebpf-profiler/collector/config"
"go.opentelemetry.io/ebpf-profiler/collector/internal"
"go.opentelemetry.io/ebpf-profiler/internal/controller"
"go.opentelemetry.io/ebpf-profiler/internal/log"
)

var (
Expand All @@ -38,6 +41,8 @@ func BuildProfilesReceiver(options ...Option) xreceiver.CreateProfilesFunc {
baseCfg component.Config,
nextConsumer xconsumer.Profiles,
) (xreceiver.Profiles, error) {
log.SetLogger(*slog.New(zapslog.NewHandler(rs.Logger.Core())))

cfg, ok := baseCfg.(*config.Config)
if !ok {
return nil, errInvalidConfig
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ require (
github.com/mdlayher/kobject v0.0.0-20200520190114-19ca17470d7d
github.com/minio/sha256-simd v1.0.1
github.com/peterbourgon/ff/v3 v3.4.0
github.com/sirupsen/logrus v1.9.3
github.com/stretchr/testify v1.11.1
github.com/zeebo/xxh3 v1.0.2
go.opentelemetry.io/collector/component v1.44.0
Expand All @@ -35,6 +34,7 @@ require (
go.opentelemetry.io/collector/receiver/xreceiver v0.138.0
go.opentelemetry.io/otel v1.38.0
go.opentelemetry.io/otel/metric v1.38.0
go.uber.org/zap/exp v0.3.0
golang.org/x/arch v0.22.0
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546
golang.org/x/mod v0.29.0
Expand Down
7 changes: 2 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down Expand Up @@ -179,6 +176,8 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
go.uber.org/zap/exp v0.3.0 h1:6JYzdifzYkGmTdRR59oYH+Ng7k49H9qVpWwNSsGJj3U=
go.uber.org/zap/exp v0.3.0/go.mod h1:5I384qq7XGxYyByIhHm6jg5CHkGY0nsTfbDLgDDlgJQ=
golang.org/x/arch v0.22.0 h1:c/Zle32i5ttqRXjdLyyHZESLD/bB90DCU1g9l/0YBDI=
golang.org/x/arch v0.22.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
Expand Down Expand Up @@ -213,7 +212,6 @@ golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
Expand All @@ -240,6 +238,5 @@ google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
2 changes: 1 addition & 1 deletion internal/controller/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"runtime"
"time"

log "github.com/sirupsen/logrus"
"go.opentelemetry.io/ebpf-profiler/internal/log"

"go.opentelemetry.io/collector/consumer/xconsumer"
"go.opentelemetry.io/ebpf-profiler/collector/config"
Expand Down
12 changes: 6 additions & 6 deletions internal/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"strings"
"time"

log "github.com/sirupsen/logrus"
"go.opentelemetry.io/ebpf-profiler/internal/log"

"go.opentelemetry.io/ebpf-profiler/host"
"go.opentelemetry.io/ebpf-profiler/libpf"
Expand Down Expand Up @@ -95,7 +95,7 @@ func (c *Controller) Start(ctx context.Context) error {
return fmt.Errorf("failed to load eBPF tracer: %w", err)
}
c.tracer = trc
log.Printf("eBPF tracer loaded")
log.Info("eBPF tracer loaded")

now := time.Now()

Expand All @@ -114,19 +114,19 @@ func (c *Controller) Start(ctx context.Context) error {
if err := trc.StartOffCPUProfiling(); err != nil {
return fmt.Errorf("failed to start off-cpu profiling: %v", err)
}
log.Printf("Enabled off-cpu profiling with p=%f", c.config.OffCPUThreshold)
log.Infof("Enabled off-cpu profiling with p=%f", c.config.OffCPUThreshold)
}

if len(c.config.UProbeLinks) > 0 {
if err := trc.AttachUProbes(c.config.UProbeLinks); err != nil {
return fmt.Errorf("failed to attach uprobes: %v", err)
}
log.Printf("Attached uprobes")
log.Info("Attached uprobes")
}

if c.config.ProbabilisticThreshold < tracer.ProbabilisticThresholdMax {
trc.StartProbabilisticProfiling(ctx)
log.Printf("Enabled probabilistic profiling")
log.Info("Enabled probabilistic profiling")
} else {
if err := trc.EnableProfiling(); err != nil {
return fmt.Errorf("failed to enable perf events: %w", err)
Expand All @@ -139,7 +139,7 @@ func (c *Controller) Start(ctx context.Context) error {

// This log line is used in our system tests to verify if that the agent has started.
// So if you change this log line update also the system test.
log.Printf("Attached sched monitor")
log.Info("Attached sched monitor")

if err := startTraceHandling(ctx, trc); err != nil {
return fmt.Errorf("failed to start trace handling: %w", err)
Expand Down
119 changes: 119 additions & 0 deletions internal/log/logging.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package log // import "go.opentelemetry.io/ebpf-profiler/internal/log"

import (
"context"
"fmt"
"log/slog"
"os"
"sync/atomic"
)

// globalLogger holds a reference to the [slog.Logger] used within
// go.opentelemetry.io/ebpf-profiler.
//
// The default logger logs to stderr which is backed by the standard `log.Logger`
// interface. This logger will show messages at the Info Level.
var globalLogger = func() *atomic.Pointer[slog.Logger] {
l := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{
Level: slog.LevelInfo,
}))

p := new(atomic.Pointer[slog.Logger])
p.Store(l)
return p
}()

// SetLogger sets the global Logger to l.
func SetLogger(l slog.Logger) {
globalLogger.Store(&l)
}

// SetDebugLogger configures the global logger to write debug-level logs to stderr.
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of SetDebugLogger an API should be provided to set the log level.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The slog Handler does not provide any mechanism to change the log level in runtime, a new logger needs to be created instead. Any suggestion on the naming?

Also, keep in mind that this will be removed once we transition to just having the otel receiver (verbosity will be defined from the collector's configuration)

Copy link
Contributor

Choose a reason for hiding this comment

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

In the example provided with slog.SetLogLoggerLevel, changing the severity level after setting the logger just works.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That function only works in case we were using the default slog.Logger instance, in this case we created a new non default logger.

func SetDebugLogger() {
SetLogger(*slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{
Level: slog.LevelDebug,
})))
}

// getLogger returns the global logger.
func getLogger() *slog.Logger {
return globalLogger.Load()
}

// Infof logs informational messages about the general state of the profiler.
// This function is a wrapper around the structured slog-based logger,
// formatting the message as a string for backward compatibility with
// previous unstructured logging.
func Infof(msg string, keysAndValues ...any) {
if getLogger().Enabled(context.Background(), slog.LevelInfo) {
getLogger().Info(fmt.Sprintf(msg, keysAndValues...))
}
}

// Info logs informational messages about the general state of the profiler.
// This is a wrapper around Infof for convenience.
func Info(msg string) {
if getLogger().Enabled(context.Background(), slog.LevelInfo) {
getLogger().Info(msg)
}
}

// Errorf logs error messages about exceptional states of the profiler.
// This wrapper formats structured log data into a string message for
// backward compatibility with older unstructured logs.
func Errorf(msg string, keysAndValues ...any) {
if getLogger().Enabled(context.Background(), slog.LevelError) {
getLogger().Error(fmt.Sprintf(msg, keysAndValues...))
}
}

// Error logs error messages about exceptional states of the profiler.
// This is a wrapper around Errorf for convenience.
func Error(msg error) {
if getLogger().Enabled(context.Background(), slog.LevelError) {
getLogger().Error(msg.Error())
}
}

// Debugf logs detailed debugging information about internal profiler behavior.
// This wrapper converts structured log data into a string message for
// backward compatibility with older unstructured logs.
func Debugf(msg string, keysAndValues ...any) {
if getLogger().Enabled(context.Background(), slog.LevelDebug) {
getLogger().Debug(fmt.Sprintf(msg, keysAndValues...))
}
}

// Debug logs detailed debugging information about internal profiler behavior.
// This is a wrapper around Debugf for convenience.
func Debug(msg string) {
if getLogger().Enabled(context.Background(), slog.LevelDebug) {
getLogger().Debug(msg)
}
}

// Warnf logs warnings in the profiler — not errors, but likely more important
// than informational messages. This wrapper preserves backward compatibility
// by string-formatting structured log data.
func Warnf(msg string, keysAndValues ...any) {
if getLogger().Enabled(context.Background(), slog.LevelWarn) {
getLogger().Warn(fmt.Sprintf(msg, keysAndValues...))
}
}

// Warn logs warnings in the profiler — not errors, but likely more important
// than informational messages. This is a wrapper around Warnf for convenience.
func Warn(msg string) {
if getLogger().Enabled(context.Background(), slog.LevelWarn) {
getLogger().Warn(msg)
}
}

// Fatalf logs a fatal error message and exits the program.
// This wrapper maintains backward compatibility with unstructured logs by
// formatting messages as strings.
// TODO: remove Fatalf calls from the codebase (https://github.com/open-telemetry/opentelemetry-ebpf-profiler/issues/888).
func Fatalf(msg string, keysAndValues ...any) {
Errorf(msg, keysAndValues...)
os.Exit(1)
}
8 changes: 5 additions & 3 deletions interpreter/apmint/apmint.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"regexp"
"unsafe"

log "github.com/sirupsen/logrus"
"go.opentelemetry.io/ebpf-profiler/internal/log"

"go.opentelemetry.io/ebpf-profiler/host"
"go.opentelemetry.io/ebpf-profiler/interpreter"
Expand Down Expand Up @@ -108,7 +108,8 @@ type data struct {
var _ interpreter.Data = &data{}

func (d data) Attach(ebpf interpreter.EbpfHandler, pid libpf.PID,
bias libpf.Address, rm remotememory.RemoteMemory) (interpreter.Instance, error) {
bias libpf.Address, rm remotememory.RemoteMemory,
) (interpreter.Instance, error) {
procStorage, err := readProcStorage(rm, bias+d.procStorageElfVA)
if err != nil {
return nil, fmt.Errorf("failed to read APM correlation process storage: %s", err)
Expand Down Expand Up @@ -157,7 +158,8 @@ func (i *Instance) Detach(ebpf interpreter.EbpfHandler, pid libpf.PID) error {

// NotifyAPMAgent sends out collected traces to the connected APM agent.
func (i *Instance) NotifyAPMAgent(
pid libpf.PID, rawTrace *host.Trace, umTraceHash libpf.TraceHash, count uint16) {
pid libpf.PID, rawTrace *host.Trace, umTraceHash libpf.TraceHash, count uint16,
) {
if rawTrace.APMTransactionID == libpf.InvalidAPMSpanID || i.socket == nil {
return
}
Expand Down
5 changes: 3 additions & 2 deletions interpreter/dotnet/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"fmt"
"unsafe"

log "github.com/sirupsen/logrus"
"go.opentelemetry.io/ebpf-profiler/internal/log"

"github.com/elastic/go-freelru"

Expand Down Expand Up @@ -133,7 +133,8 @@ func (d *dotnetData) String() string {
}

func (d *dotnetData) Attach(ebpf interpreter.EbpfHandler, pid libpf.PID, bias libpf.Address,
rm remotememory.RemoteMemory) (interpreter.Instance, error) {
rm remotememory.RemoteMemory,
) (interpreter.Instance, error) {
log.Debugf("Attach PID %d, bias %x", pid, bias)

addrToMethod, err := freelru.New[libpf.Address, *dotnetMethod](interpreter.LruFunctionCacheSize,
Expand Down
2 changes: 1 addition & 1 deletion interpreter/dotnet/dotnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ import (
"regexp"
"strconv"

log "github.com/sirupsen/logrus"
"go.opentelemetry.io/ebpf-profiler/internal/log"

"go.opentelemetry.io/ebpf-profiler/interpreter"
)
Expand Down
Loading