Skip to content

Commit b197231

Browse files
Copilotlpcox
andauthored
refactor: deduplicate tracer fallback and simplify logger helpers
Agent-Logs-Url: https://github.com/github/gh-aw-mcpg/sessions/73f6ab54-aba0-4958-aa14-8eec3780a37e Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
1 parent 36500a3 commit b197231

10 files changed

Lines changed: 51 additions & 40 deletions

File tree

internal/logger/common.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,21 +194,33 @@ import (
194194
// The three sets and their internal helpers are:
195195
//
196196
// file_logger.go LogInfo / LogWarn / LogError / LogDebug → logWithLevel
197-
// markdown_logger.go LogInfoMd / LogWarnMd / LogErrorMd / LogDebugMd → logWithMarkdownLevel
197+
// markdown_logger.go LogInfoMd / LogWarnMd / LogErrorMd / LogDebugMd → logWithMarkdown
198198
// server_file_logger.go LogInfoWithServer / ... / LogDebugWithServer → logWithLevelAndServer
199199
//
200200
// This pattern is intentionally kept across the three files because:
201201
// - Each set is a distinct public API with a different signature and set of callers.
202202
// - The one-liner wrappers are trivial and unlikely to diverge.
203203
// - Go lacks the metaprogramming to eliminate them without sacrificing readability.
204204
//
205-
// The shared logFuncs map (file_logger.go) centralises the LogLevel → log-function
206-
// mapping so that the internal helpers (logWithMarkdownLevel, logWithLevelAndServer)
205+
// The shared logFuncs map below centralises the LogLevel → log-function
206+
// mapping so that the internal helpers (logWithMarkdown, logWithLevelAndServer)
207207
// do not need their own switch-on-level blocks.
208208
//
209209
// When adding a new LogLevel constant (e.g., LogLevelTrace):
210-
// 1. Add a new entry to the logFuncs map in file_logger.go.
210+
// 1. Add a new entry to the logFuncs map below.
211211
// 2. Add a new LogTrace wrapper to each of the three files above.
212+
//
213+
// logFuncs maps each LogLevel to its corresponding global log function.
214+
// This eliminates repeated switch-on-level blocks in logWithMarkdown
215+
// (markdown_logger.go) and logWithLevelAndServer (server_file_logger.go).
216+
// When adding a new LogLevel constant, add a corresponding entry here so
217+
// that all dispatch sites automatically support the new level.
218+
var logFuncs = map[LogLevel]func(string, string, ...interface{}){
219+
LogLevelInfo: LogInfo,
220+
LogLevelWarn: LogWarn,
221+
LogLevelError: LogError,
222+
LogLevelDebug: LogDebug,
223+
}
212224

213225
// Global Logger RWMutex Access Pattern
214226
//

internal/logger/file_logger.go

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -133,18 +133,6 @@ func LogDebug(category, format string, args ...interface{}) {
133133
logWithLevel(LogLevelDebug, category, format, args...)
134134
}
135135

136-
// logFuncs maps each LogLevel to its corresponding global log function.
137-
// This eliminates repeated switch-on-level blocks in logWithMarkdownLevel
138-
// (markdown_logger.go) and logWithLevelAndServer (server_file_logger.go).
139-
// When adding a new LogLevel constant, add a corresponding entry here so
140-
// that all dispatch sites automatically support the new level.
141-
var logFuncs = map[LogLevel]func(string, string, ...interface{}){
142-
LogLevelInfo: LogInfo,
143-
LogLevelWarn: LogWarn,
144-
LogLevelError: LogError,
145-
LogLevelDebug: LogDebug,
146-
}
147-
148136
// CloseGlobalLogger closes the global file logger
149137
func CloseGlobalLogger() error {
150138
return closeGlobalLogger(&globalLoggerMu, &globalFileLogger)

internal/logger/helper_functions_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,9 @@ func TestLogWithLevelAndServer(t *testing.T) {
9999
assert.Contains(t, unifiedLog, "Debug message via server helper")
100100
}
101101

102-
// TestLogWithMarkdownLevel verifies the logWithMarkdownLevel helper function
102+
// TestLogWithMarkdown verifies the logWithMarkdown helper function
103103
// correctly handles both regular and markdown logging
104-
func TestLogWithMarkdownLevel(t *testing.T) {
104+
func TestLogWithMarkdown(t *testing.T) {
105105
tmpDir := t.TempDir()
106106
logDir := filepath.Join(tmpDir, "logs")
107107

internal/logger/markdown_logger.go

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -170,41 +170,34 @@ func (ml *MarkdownLogger) Log(level LogLevel, category, format string, args ...i
170170
// logWithMarkdown is a helper that logs to both regular and markdown loggers.
171171
// It uses the withGlobalLogger helper from global_helpers.go to handle mutex locking
172172
// and nil-checking for the markdown logger access.
173-
func logWithMarkdown(level LogLevel, regularLogFunc func(string, string, ...interface{}), category, format string, args ...interface{}) {
173+
func logWithMarkdown(level LogLevel, category, format string, args ...interface{}) {
174174
// Log to regular logger
175-
regularLogFunc(category, format, args...)
175+
logFuncs[level](category, format, args...)
176176

177177
// Log to markdown logger using withGlobalLogger helper
178178
withGlobalLogger(&globalMarkdownMu, &globalMarkdownLogger, func(logger *MarkdownLogger) {
179179
logger.Log(level, category, format, args...)
180180
})
181181
}
182182

183-
// logWithMarkdownLevel is a helper that reduces code duplication for markdown logging at different levels.
184-
// It uses the logFuncs map (file_logger.go) to look up the regular log function for the given level,
185-
// eliminating repeated switch-on-level patterns across LogInfoMd, LogWarnMd, LogErrorMd, and LogDebugMd.
186-
func logWithMarkdownLevel(level LogLevel, category, format string, args ...interface{}) {
187-
logWithMarkdown(level, logFuncs[level], category, format, args...)
188-
}
189-
190183
// LogInfoMd logs to both regular and markdown loggers
191184
func LogInfoMd(category, format string, args ...interface{}) {
192-
logWithMarkdownLevel(LogLevelInfo, category, format, args...)
185+
logWithMarkdown(LogLevelInfo, category, format, args...)
193186
}
194187

195188
// LogWarnMd logs to both regular and markdown loggers
196189
func LogWarnMd(category, format string, args ...interface{}) {
197-
logWithMarkdownLevel(LogLevelWarn, category, format, args...)
190+
logWithMarkdown(LogLevelWarn, category, format, args...)
198191
}
199192

200193
// LogErrorMd logs to both regular and markdown loggers
201194
func LogErrorMd(category, format string, args ...interface{}) {
202-
logWithMarkdownLevel(LogLevelError, category, format, args...)
195+
logWithMarkdown(LogLevelError, category, format, args...)
203196
}
204197

205198
// LogDebugMd logs to both regular and markdown loggers
206199
func LogDebugMd(category, format string, args ...interface{}) {
207-
logWithMarkdownLevel(LogLevelDebug, category, format, args...)
200+
logWithMarkdown(LogLevelDebug, category, format, args...)
208201
}
209202

210203
// CloseMarkdownLogger closes the global markdown logger

internal/logger/server_file_logger.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ func (sfl *ServerFileLogger) Close() error {
141141
// logWithLevelAndServer is a helper that reduces code duplication for per-server logging at different levels.
142142
// It uses the withGlobalLogger helper from global_helpers.go to handle mutex locking and nil-checking,
143143
// eliminating repeated patterns across LogInfoWithServer, LogWarnWithServer, LogErrorWithServer, and LogDebugWithServer.
144-
// It uses the logFuncs map (file_logger.go) for the unified log dispatch, avoiding a repeated switch-on-level block.
144+
// It uses the logFuncs map (common.go) for the unified log dispatch, avoiding a repeated switch-on-level block.
145145
func logWithLevelAndServer(serverID string, level LogLevel, category, format string, args ...interface{}) {
146146
withGlobalLogger(&globalServerLoggerMu, &globalServerFileLogger, func(logger *ServerFileLogger) {
147147
logger.Log(serverID, level, category, format, args...)

internal/proxy/handler.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,7 @@ type proxyHandler struct {
4040

4141
// getTracer returns the cached tracer if set, otherwise falls back to the global tracer.
4242
func (h *proxyHandler) getTracer() oteltrace.Tracer {
43-
if h.tracer != nil {
44-
return h.tracer
45-
}
46-
return tracing.Tracer()
43+
return tracing.GetCachedOrGlobal(h.tracer)
4744
}
4845

4946
func (h *proxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {

internal/server/tool_registry.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,8 @@ func (us *UnifiedServer) callSysServer(toolName string) (interface{}, error) {
350350
}
351351

352352
func marshalAndSanitizeForLog(value interface{}) string {
353+
// Best-effort logging helper: if marshaling fails, we intentionally keep logging
354+
// a sanitized empty string rather than surfacing an additional logging-only error.
353355
resultJSON, _ := json.Marshal(value)
354356
return sanitize.SanitizeString(string(resultJSON))
355357
}

internal/server/unified.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,7 @@ type UnifiedServer struct {
124124

125125
// getTracer returns the cached tracer if set, otherwise falls back to the global tracer.
126126
func (us *UnifiedServer) getTracer() oteltrace.Tracer {
127-
if us.tracer != nil {
128-
return us.tracer
129-
}
130-
return tracing.Tracer()
127+
return tracing.GetCachedOrGlobal(us.tracer)
131128
}
132129

133130
// NewUnified creates a new unified MCP server

internal/tracing/provider.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,14 @@ func Tracer() trace.Tracer {
306306
return otel.Tracer(instrumentationName)
307307
}
308308

309+
// GetCachedOrGlobal returns cached if non-nil, otherwise falls back to the global tracer.
310+
func GetCachedOrGlobal(cached trace.Tracer) trace.Tracer {
311+
if cached != nil {
312+
return cached
313+
}
314+
return Tracer()
315+
}
316+
309317
// ParentContext returns a context carrying the W3C remote parent span context
310318
// from the configured traceId and spanId (spec §4.1.3.6).
311319
// Exported for use at startup to build the root span's parent context.

internal/tracing/provider_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,20 @@ func TestTracer_ReturnsNonNil(t *testing.T) {
9292
assert.NotNil(t, tr)
9393
}
9494

95+
func TestGetCachedOrGlobal_WithCachedTracer_ReturnsCached(t *testing.T) {
96+
cached := noop.NewTracerProvider().Tracer("cached")
97+
assert.Equal(t, cached, tracing.GetCachedOrGlobal(cached))
98+
}
99+
100+
func TestGetCachedOrGlobal_WithNilTracer_ReturnsGlobal(t *testing.T) {
101+
ctx := context.Background()
102+
provider, err := tracing.InitProvider(ctx, nil)
103+
require.NoError(t, err)
104+
defer provider.Shutdown(ctx)
105+
106+
assert.NotNil(t, tracing.GetCachedOrGlobal(nil))
107+
}
108+
95109
func TestInitProvider_SampleRateZero_UsesNeverSampler(t *testing.T) {
96110
ctx := context.Background()
97111

0 commit comments

Comments
 (0)