Skip to content

Commit c24b748

Browse files
authored
ref: create debuglog package (#1105)
1 parent 4edee8a commit c24b748

File tree

18 files changed

+245
-69
lines changed

18 files changed

+245
-69
lines changed

client.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"crypto/x509"
66
"fmt"
77
"io"
8-
"log"
98
"math/rand"
109
"net/http"
1110
"os"
@@ -15,6 +14,7 @@ import (
1514
"time"
1615

1716
"github.com/getsentry/sentry-go/internal/debug"
17+
"github.com/getsentry/sentry-go/internal/debuglog"
1818
)
1919

2020
// The identifier of the SDK.
@@ -78,8 +78,8 @@ type usageError struct {
7878
}
7979

8080
// DebugLogger is an instance of log.Logger that is used to provide debug information about running Sentry Client
81-
// can be enabled by either using DebugLogger.SetOutput directly or with Debug client option.
82-
var DebugLogger = log.New(io.Discard, "[Sentry] ", log.LstdFlags)
81+
// can be enabled by either using debuglog.SetOutput directly or with Debug client option.
82+
var DebugLogger = debuglog.GetLogger()
8383

8484
// EventProcessor is a function that processes an event.
8585
// Event processors are used to change an event before it is sent to Sentry.
@@ -296,7 +296,7 @@ func NewClient(options ClientOptions) (*Client, error) {
296296
if debugWriter == nil {
297297
debugWriter = os.Stderr
298298
}
299-
DebugLogger.SetOutput(debugWriter)
299+
debuglog.SetOutput(debugWriter)
300300
}
301301

302302
if options.Dsn == "" {
@@ -401,12 +401,12 @@ func (client *Client) setupIntegrations() {
401401

402402
for _, integration := range integrations {
403403
if client.integrationAlreadyInstalled(integration.Name()) {
404-
DebugLogger.Printf("Integration %s is already installed\n", integration.Name())
404+
debuglog.Printf("Integration %s is already installed\n", integration.Name())
405405
continue
406406
}
407407
client.integrations = append(client.integrations, integration)
408408
integration.SetupOnce(client)
409-
DebugLogger.Printf("Integration installed: %s\n", integration.Name())
409+
debuglog.Printf("Integration installed: %s\n", integration.Name())
410410
}
411411

412412
sort.Slice(client.integrations, func(i, j int) bool {
@@ -647,7 +647,7 @@ func (client *Client) processEvent(event *Event, hint *EventHint, scope EventMod
647647
// options.TracesSampler when they are started. Other events
648648
// (errors, messages) are sampled here. Does not apply to check-ins.
649649
if event.Type != transactionType && event.Type != checkInType && !sample(client.options.SampleRate) {
650-
DebugLogger.Println("Event dropped due to SampleRate hit.")
650+
debuglog.Println("Event dropped due to SampleRate hit.")
651651
return nil
652652
}
653653

@@ -663,15 +663,15 @@ func (client *Client) processEvent(event *Event, hint *EventHint, scope EventMod
663663
case transactionType:
664664
if client.options.BeforeSendTransaction != nil {
665665
if event = client.options.BeforeSendTransaction(event, hint); event == nil {
666-
DebugLogger.Println("Transaction dropped due to BeforeSendTransaction callback.")
666+
debuglog.Println("Transaction dropped due to BeforeSendTransaction callback.")
667667
return nil
668668
}
669669
}
670670
case checkInType: // not a default case, since we shouldn't apply BeforeSend on check-in events
671671
default:
672672
if client.options.BeforeSend != nil {
673673
if event = client.options.BeforeSend(event, hint); event == nil {
674-
DebugLogger.Println("Event dropped due to BeforeSend callback.")
674+
debuglog.Println("Event dropped due to BeforeSend callback.")
675675
return nil
676676
}
677677
}
@@ -738,7 +738,7 @@ func (client *Client) prepareEvent(event *Event, hint *EventHint, scope EventMod
738738
id := event.EventID
739739
event = processor(event, hint)
740740
if event == nil {
741-
DebugLogger.Printf("Event dropped by one of the Client EventProcessors: %s\n", id)
741+
debuglog.Printf("Event dropped by one of the Client EventProcessors: %s\n", id)
742742
return nil
743743
}
744744
}
@@ -747,7 +747,7 @@ func (client *Client) prepareEvent(event *Event, hint *EventHint, scope EventMod
747747
id := event.EventID
748748
event = processor(event, hint)
749749
if event == nil {
750-
DebugLogger.Printf("Event dropped by one of the Global EventProcessors: %s\n", id)
750+
debuglog.Printf("Event dropped by one of the Global EventProcessors: %s\n", id)
751751
return nil
752752
}
753753
}

fasthttp/sentryfasthttp.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"time"
1111

1212
"github.com/getsentry/sentry-go"
13+
"github.com/getsentry/sentry-go/internal/debuglog"
1314
"github.com/valyala/fasthttp"
1415
)
1516

@@ -143,7 +144,7 @@ func GetSpanFromContext(ctx *fasthttp.RequestCtx) *sentry.Span {
143144
func convert(ctx *fasthttp.RequestCtx) *http.Request {
144145
defer func() {
145146
if err := recover(); err != nil {
146-
sentry.DebugLogger.Printf("%v", err)
147+
debuglog.Printf("%v", err)
147148
}
148149
}()
149150

fiber/sentryfiber.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/gofiber/fiber/v2/utils"
1414

1515
"github.com/getsentry/sentry-go"
16+
"github.com/getsentry/sentry-go/internal/debuglog"
1617
)
1718

1819
const (
@@ -143,7 +144,7 @@ func GetSpanFromContext(ctx *fiber.Ctx) *sentry.Span {
143144
func convert(ctx *fiber.Ctx) *http.Request {
144145
defer func() {
145146
if err := recover(); err != nil {
146-
sentry.DebugLogger.Printf("%v", err)
147+
debuglog.Printf("%v", err)
147148
}
148149
}()
149150

hub.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"fmt"
66
"sync"
77
"time"
8+
9+
"github.com/getsentry/sentry-go/internal/debuglog"
810
)
911

1012
type contextKey int
@@ -308,7 +310,7 @@ func (hub *Hub) AddBreadcrumb(breadcrumb *Breadcrumb, hint *BreadcrumbHint) {
308310
hint = &BreadcrumbHint{}
309311
}
310312
if breadcrumb = client.options.BeforeBreadcrumb(breadcrumb, hint); breadcrumb == nil {
311-
DebugLogger.Println("breadcrumb dropped due to BeforeBreadcrumb callback.")
313+
debuglog.Println("breadcrumb dropped due to BeforeBreadcrumb callback.")
312314
return
313315
}
314316
}

integrations.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import (
88
"runtime/debug"
99
"strings"
1010
"sync"
11+
12+
"github.com/getsentry/sentry-go/internal/debuglog"
1113
)
1214

1315
// ================================
@@ -32,7 +34,7 @@ func (mi *modulesIntegration) processor(event *Event, _ *EventHint) *Event {
3234
mi.once.Do(func() {
3335
info, ok := debug.ReadBuildInfo()
3436
if !ok {
35-
DebugLogger.Print("The Modules integration is not available in binaries built without module support.")
37+
debuglog.Print("The Modules integration is not available in binaries built without module support.")
3638
return
3739
}
3840
mi.modules = extractModules(info)
@@ -141,7 +143,7 @@ func (iei *ignoreErrorsIntegration) processor(event *Event, _ *EventHint) *Event
141143
for _, suspect := range suspects {
142144
for _, pattern := range iei.ignoreErrors {
143145
if pattern.Match([]byte(suspect)) || strings.Contains(suspect, pattern.String()) {
144-
DebugLogger.Printf("Event dropped due to being matched by `IgnoreErrors` option."+
146+
debuglog.Printf("Event dropped due to being matched by `IgnoreErrors` option."+
145147
"| Value matched: %s | Filter used: %s", suspect, pattern)
146148
return nil
147149
}
@@ -203,7 +205,7 @@ func (iei *ignoreTransactionsIntegration) processor(event *Event, _ *EventHint)
203205

204206
for _, pattern := range iei.ignoreTransactions {
205207
if pattern.Match([]byte(suspect)) || strings.Contains(suspect, pattern.String()) {
206-
DebugLogger.Printf("Transaction dropped due to being matched by `IgnoreTransactions` option."+
208+
debuglog.Printf("Transaction dropped due to being matched by `IgnoreTransactions` option."+
207209
"| Value matched: %s | Filter used: %s", suspect, pattern)
208210
return nil
209211
}

internal/debuglog/log.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package debuglog
2+
3+
import (
4+
"io"
5+
"log"
6+
)
7+
8+
// logger is the global debug logger instance.
9+
var logger = log.New(io.Discard, "[Sentry] ", log.LstdFlags)
10+
11+
// SetOutput changes the output destination of the logger.
12+
func SetOutput(w io.Writer) {
13+
logger.SetOutput(w)
14+
}
15+
16+
// GetLogger returns the current logger instance.
17+
// This function is thread-safe and can be called concurrently.
18+
func GetLogger() *log.Logger {
19+
return logger
20+
}
21+
22+
// Printf calls Printf on the underlying logger.
23+
func Printf(format string, args ...interface{}) {
24+
logger.Printf(format, args...)
25+
}
26+
27+
// Println calls Println on the underlying logger.
28+
func Println(args ...interface{}) {
29+
logger.Println(args...)
30+
}
31+
32+
// Print calls Print on the underlying logger.
33+
func Print(args ...interface{}) {
34+
logger.Print(args...)
35+
}

internal/debuglog/log_test.go

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
package debuglog
2+
3+
import (
4+
"bytes"
5+
"io"
6+
"strings"
7+
"sync"
8+
"testing"
9+
)
10+
11+
func TestGetLogger(t *testing.T) {
12+
logger := GetLogger()
13+
if logger == nil {
14+
t.Error("GetLogger returned nil")
15+
}
16+
}
17+
18+
func TestSetOutput(t *testing.T) {
19+
var buf bytes.Buffer
20+
SetOutput(&buf)
21+
defer SetOutput(io.Discard)
22+
23+
Printf("test %s %d", "message", 42)
24+
25+
output := buf.String()
26+
if !strings.Contains(output, "test message 42") {
27+
t.Errorf("Printf output incorrect: got %q", output)
28+
}
29+
}
30+
31+
func TestPrintf(t *testing.T) {
32+
var buf bytes.Buffer
33+
SetOutput(&buf)
34+
defer SetOutput(io.Discard)
35+
36+
Printf("test %s %d", "message", 42)
37+
38+
output := buf.String()
39+
if !strings.Contains(output, "test message 42") {
40+
t.Errorf("Printf output incorrect: got %q", output)
41+
}
42+
}
43+
44+
func TestPrintln(t *testing.T) {
45+
var buf bytes.Buffer
46+
SetOutput(&buf)
47+
defer SetOutput(io.Discard)
48+
49+
Println("test", "message")
50+
51+
output := buf.String()
52+
if !strings.Contains(output, "test message") {
53+
t.Errorf("Println output incorrect: got %q", output)
54+
}
55+
}
56+
57+
func TestPrint(t *testing.T) {
58+
var buf bytes.Buffer
59+
SetOutput(&buf)
60+
defer SetOutput(io.Discard)
61+
62+
Print("test", "message")
63+
64+
output := buf.String()
65+
if !strings.Contains(output, "testmessage") {
66+
t.Errorf("Print output incorrect: got %q", output)
67+
}
68+
}
69+
70+
func TestConcurrentAccess(_ *testing.T) {
71+
var wg sync.WaitGroup
72+
iterations := 1000
73+
74+
for i := 0; i < iterations; i++ {
75+
wg.Add(1)
76+
go func(n int) {
77+
defer wg.Done()
78+
Printf("concurrent message %d", n)
79+
}(i)
80+
}
81+
82+
for i := 0; i < iterations; i++ {
83+
wg.Add(1)
84+
go func() {
85+
defer wg.Done()
86+
_ = GetLogger()
87+
}()
88+
}
89+
90+
for i := 0; i < 10; i++ {
91+
wg.Add(1)
92+
go func() {
93+
defer wg.Done()
94+
SetOutput(io.Discard)
95+
}()
96+
}
97+
98+
wg.Wait()
99+
}
100+
101+
func TestInitialization(t *testing.T) {
102+
// The logger should be initialized on package load
103+
logger := GetLogger()
104+
if logger == nil {
105+
t.Error("Logger was not initialized")
106+
}
107+
108+
var buf bytes.Buffer
109+
SetOutput(&buf)
110+
defer SetOutput(io.Discard)
111+
112+
Printf("test")
113+
Println("test")
114+
Print("test")
115+
116+
output := buf.String()
117+
if !strings.Contains(output, "test") {
118+
t.Errorf("Expected output to contain 'test', got %q", output)
119+
}
120+
}

log.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"time"
1111

1212
"github.com/getsentry/sentry-go/attribute"
13+
debuglog "github.com/getsentry/sentry-go/internal/debuglog"
1314
)
1415

1516
type LogLevel string
@@ -74,7 +75,7 @@ func NewLogger(ctx context.Context) Logger {
7475
}
7576
}
7677

77-
DebugLogger.Println("fallback to noopLogger: enableLogs disabled")
78+
debuglog.Println("fallback to noopLogger: enableLogs disabled")
7879
return &noopLogger{} // fallback: does nothing
7980
}
8081

@@ -187,7 +188,7 @@ func (l *sentryLogger) log(ctx context.Context, level LogLevel, severity int, me
187188
}
188189

189190
if l.client.options.Debug {
190-
DebugLogger.Printf(message, args...)
191+
debuglog.Printf(message, args...)
191192
}
192193
}
193194

@@ -198,7 +199,7 @@ func (l *sentryLogger) SetAttributes(attrs ...attribute.Builder) {
198199
for _, v := range attrs {
199200
t, ok := mapTypesToStr[v.Value.Type()]
200201
if !ok || t == "" {
201-
DebugLogger.Printf("invalid attribute type set: %v", t)
202+
debuglog.Printf("invalid attribute type set: %v", t)
202203
continue
203204
}
204205

0 commit comments

Comments
 (0)