Skip to content

Commit 4a6c433

Browse files
logging: unify stdlib log usage to pkg/observability (zap) (#134)
* logging: unify stdlib log usage to pkg/observability (zap) Signed-off-by: Jintao Zhang <[email protected]> * apply for review comments Signed-off-by: Jintao Zhang <[email protected]> --------- Signed-off-by: Jintao Zhang <[email protected]>
1 parent 88aa203 commit 4a6c433

File tree

15 files changed

+171
-176
lines changed

15 files changed

+171
-176
lines changed

src/semantic-router/cmd/main.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package main
33
import (
44
"flag"
55
"fmt"
6-
"log"
76
"net/http"
87
"os"
98

@@ -26,43 +25,44 @@ func main() {
2625

2726
// Initialize logging (zap) from environment.
2827
if _, err := observability.InitLoggerFromEnv(); err != nil {
29-
log.Printf("failed to initialize logger, falling back to stdlib: %v", err)
28+
// Fallback to stderr since logger initialization failed
29+
fmt.Fprintf(os.Stderr, "failed to initialize logger: %v\n", err)
3030
}
3131

3232
// Check if config file exists
3333
if _, err := os.Stat(*configPath); os.IsNotExist(err) {
34-
log.Fatalf("Config file not found: %s", *configPath)
34+
observability.Fatalf("Config file not found: %s", *configPath)
3535
}
3636

3737
// Start metrics server
3838
go func() {
3939
http.Handle("/metrics", promhttp.Handler())
4040
metricsAddr := fmt.Sprintf(":%d", *metricsPort)
41-
log.Printf("Starting metrics server on %s", metricsAddr)
41+
observability.Infof("Starting metrics server on %s", metricsAddr)
4242
if err := http.ListenAndServe(metricsAddr, nil); err != nil {
43-
log.Printf("Metrics server error: %v", err)
43+
observability.Errorf("Metrics server error: %v", err)
4444
}
4545
}()
4646

4747
// Create and start the ExtProc server
4848
server, err := extproc.NewServer(*configPath, *port)
4949
if err != nil {
50-
log.Fatalf("Failed to create ExtProc server: %v", err)
50+
observability.Fatalf("Failed to create ExtProc server: %v", err)
5151
}
5252

53-
log.Printf("Starting vLLM Semantic Router ExtProc with config: %s", *configPath)
53+
observability.Infof("Starting vLLM Semantic Router ExtProc with config: %s", *configPath)
5454

5555
// Start API server if enabled
5656
if *enableAPI {
5757
go func() {
58-
log.Printf("Starting Classification API server on port %d", *apiPort)
58+
observability.Infof("Starting Classification API server on port %d", *apiPort)
5959
if err := api.StartClassificationAPI(*configPath, *apiPort); err != nil {
60-
log.Printf("Classification API server error: %v", err)
60+
observability.Errorf("Classification API server error: %v", err)
6161
}
6262
}()
6363
}
6464

6565
if err := server.Start(); err != nil {
66-
log.Fatalf("ExtProc server error: %v", err)
66+
observability.Fatalf("ExtProc server error: %v", err)
6767
}
6868
}

src/semantic-router/pkg/api/server.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ import (
55
"encoding/json"
66
"fmt"
77
"io"
8-
"log"
98
"net/http"
109
"runtime"
1110
"time"
1211

1312
"github.com/vllm-project/semantic-router/src/semantic-router/pkg/config"
1413
"github.com/vllm-project/semantic-router/src/semantic-router/pkg/metrics"
14+
"github.com/vllm-project/semantic-router/src/semantic-router/pkg/observability"
1515
"github.com/vllm-project/semantic-router/src/semantic-router/pkg/services"
1616
)
1717

@@ -97,13 +97,13 @@ func StartClassificationAPI(configPath string, port int) error {
9797
classificationSvc := getClassificationServiceWithRetry(5, 500*time.Millisecond)
9898
if classificationSvc == nil {
9999
// If no global service exists, try auto-discovery unified classifier
100-
log.Printf("No global classification service found, attempting auto-discovery...")
100+
observability.Infof("No global classification service found, attempting auto-discovery...")
101101
autoSvc, err := services.NewClassificationServiceWithAutoDiscovery(cfg)
102102
if err != nil {
103-
log.Printf("Auto-discovery failed: %v, using placeholder service", err)
103+
observability.Warnf("Auto-discovery failed: %v, using placeholder service", err)
104104
classificationSvc = services.NewPlaceholderClassificationService()
105105
} else {
106-
log.Printf("Auto-discovery successful, using unified classifier service")
106+
observability.Infof("Auto-discovery successful, using unified classifier service")
107107
classificationSvc = autoSvc
108108
}
109109
}
@@ -138,25 +138,25 @@ func StartClassificationAPI(configPath string, port int) error {
138138
IdleTimeout: 60 * time.Second,
139139
}
140140

141-
log.Printf("Classification API server listening on port %d", port)
141+
observability.Infof("Classification API server listening on port %d", port)
142142
return server.ListenAndServe()
143143
}
144144

145145
// getClassificationServiceWithRetry attempts to get the global classification service with retry logic
146146
func getClassificationServiceWithRetry(maxRetries int, retryInterval time.Duration) *services.ClassificationService {
147147
for i := 0; i < maxRetries; i++ {
148148
if svc := services.GetGlobalClassificationService(); svc != nil {
149-
log.Printf("Found global classification service on attempt %d/%d", i+1, maxRetries)
149+
observability.Infof("Found global classification service on attempt %d/%d", i+1, maxRetries)
150150
return svc
151151
}
152152

153153
if i < maxRetries-1 { // Don't sleep on the last attempt
154-
log.Printf("Global classification service not ready, retrying in %v (attempt %d/%d)", retryInterval, i+1, maxRetries)
154+
observability.Infof("Global classification service not ready, retrying in %v (attempt %d/%d)", retryInterval, i+1, maxRetries)
155155
time.Sleep(retryInterval)
156156
}
157157
}
158158

159-
log.Printf("Failed to find global classification service after %d attempts", maxRetries)
159+
observability.Warnf("Failed to find global classification service after %d attempts", maxRetries)
160160
return nil
161161
}
162162

@@ -387,7 +387,7 @@ func (s *ClassificationAPIServer) writeJSONResponse(w http.ResponseWriter, statu
387387
w.WriteHeader(statusCode)
388388

389389
if err := json.NewEncoder(w).Encode(data); err != nil {
390-
log.Printf("Failed to encode JSON response: %v", err)
390+
observability.Errorf("Failed to encode JSON response: %v", err)
391391
}
392392
}
393393

src/semantic-router/pkg/extproc/model_selector.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package extproc
22

33
import (
4-
"log"
4+
"github.com/vllm-project/semantic-router/src/semantic-router/pkg/observability"
55
)
66

77
// classifyAndSelectBestModel chooses best models based on category classification and model quality and expected TTFT
@@ -17,7 +17,7 @@ func (r *OpenAIRouter) findCategoryForClassification(query string) string {
1717

1818
categoryName, _, err := r.Classifier.ClassifyCategory(query)
1919
if err != nil {
20-
log.Printf("Category classification error: %v", err)
20+
observability.Errorf("Category classification error: %v", err)
2121
return ""
2222
}
2323

src/semantic-router/pkg/extproc/processor.go

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@ import (
44
"context"
55
"errors"
66
"io"
7-
"log"
87

98
ext_proc "github.com/envoyproxy/go-control-plane/envoy/service/ext_proc/v3"
109
"github.com/vllm-project/semantic-router/src/semantic-router/pkg/metrics"
10+
"github.com/vllm-project/semantic-router/src/semantic-router/pkg/observability"
1111
"google.golang.org/grpc/codes"
1212
"google.golang.org/grpc/status"
1313
)
1414

1515
// Process implements the ext_proc calls
1616
func (r *OpenAIRouter) Process(stream ext_proc.ExternalProcessor_ProcessServer) error {
17-
log.Println("Started processing a new request")
17+
observability.Infof("Started processing a new request")
1818

1919
// Initialize request context
2020
ctx := &RequestContext{
@@ -26,62 +26,60 @@ func (r *OpenAIRouter) Process(stream ext_proc.ExternalProcessor_ProcessServer)
2626
if err != nil {
2727
// Handle EOF - this indicates the client has closed the stream gracefully
2828
if err == io.EOF {
29-
log.Println("Stream ended gracefully")
29+
observability.Infof("Stream ended gracefully")
3030
return nil
3131
}
3232

3333
// Handle gRPC status-based cancellations/timeouts
3434
if s, ok := status.FromError(err); ok {
3535
switch s.Code() {
3636
case codes.Canceled:
37-
log.Println("Stream canceled gracefully")
37+
observability.Infof("Stream canceled gracefully")
3838
metrics.RecordRequestError(ctx.RequestModel, "cancellation")
3939
return nil
4040
case codes.DeadlineExceeded:
41-
log.Println("Stream deadline exceeded")
41+
observability.Infof("Stream deadline exceeded")
4242
metrics.RecordRequestError(ctx.RequestModel, "timeout")
4343
return nil
4444
}
4545
}
4646

4747
// Handle context cancellation from the server-side context
4848
if errors.Is(err, context.Canceled) {
49-
log.Println("Stream canceled gracefully")
49+
observability.Infof("Stream canceled gracefully")
5050
metrics.RecordRequestError(ctx.RequestModel, "cancellation")
5151
return nil
5252
}
5353
if errors.Is(err, context.DeadlineExceeded) {
54-
log.Println("Stream deadline exceeded")
54+
observability.Infof("Stream deadline exceeded")
5555
metrics.RecordRequestError(ctx.RequestModel, "timeout")
5656
return nil
5757
}
5858

59-
log.Printf("Error receiving request: %v", err)
59+
observability.Errorf("Error receiving request: %v", err)
6060
return err
6161
}
6262

6363
switch v := req.Request.(type) {
6464
case *ext_proc.ProcessingRequest_RequestHeaders:
6565
response, err := r.handleRequestHeaders(v, ctx)
6666
if err != nil {
67-
log.Printf("ERROR: handleRequestHeaders failed: %v", err)
67+
observability.Errorf("handleRequestHeaders failed: %v", err)
6868
return err
6969
}
7070
if err := sendResponse(stream, response, "request header"); err != nil {
71-
log.Printf("ERROR: sendResponse for headers failed: %v", err)
71+
observability.Errorf("sendResponse for headers failed: %v", err)
7272
return err
7373
}
7474

7575
case *ext_proc.ProcessingRequest_RequestBody:
76-
log.Printf("DEBUG: Processing Request Body - THIS IS WHERE ROUTING HAPPENS")
77-
7876
response, err := r.handleRequestBody(v, ctx)
7977
if err != nil {
80-
log.Printf("ERROR: handleRequestBody failed: %v", err)
78+
observability.Errorf("handleRequestBody failed: %v", err)
8179
return err
8280
}
8381
if err := sendResponse(stream, response, "request body"); err != nil {
84-
log.Printf("ERROR: sendResponse for body failed: %v", err)
82+
observability.Errorf("sendResponse for body failed: %v", err)
8583
return err
8684
}
8785

@@ -104,7 +102,7 @@ func (r *OpenAIRouter) Process(stream ext_proc.ExternalProcessor_ProcessServer)
104102
}
105103

106104
default:
107-
log.Printf("Unknown request type: %v", v)
105+
observability.Warnf("Unknown request type: %v", v)
108106

109107
// For unknown message types, create a body response with CONTINUE status
110108
response := &ext_proc.ProcessingResponse{

src/semantic-router/pkg/extproc/reason_mode_selector.go

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ package extproc
33
import (
44
"encoding/json"
55
"fmt"
6-
"log"
76
"strings"
87

98
"github.com/vllm-project/semantic-router/src/semantic-router/pkg/config"
109
"github.com/vllm-project/semantic-router/src/semantic-router/pkg/metrics"
10+
"github.com/vllm-project/semantic-router/src/semantic-router/pkg/observability"
1111
"github.com/vllm-project/semantic-router/src/semantic-router/pkg/utils/entropy"
1212
)
1313

@@ -24,7 +24,7 @@ func (r *OpenAIRouter) getReasoningModeAndCategory(query string) (bool, string)
2424

2525
// If no category was determined (empty string), default to no reasoning
2626
if categoryName == "" {
27-
log.Printf("No category determined for query, defaulting to no reasoning mode")
27+
observability.Infof("No category determined for query, defaulting to no reasoning mode")
2828
return false, ""
2929
}
3030

@@ -38,14 +38,14 @@ func (r *OpenAIRouter) getReasoningModeAndCategory(query string) (bool, string)
3838
if category.UseReasoning {
3939
reasoningStatus = "ENABLED"
4040
}
41-
log.Printf("Reasoning mode decision: Category '%s' → %s",
41+
observability.Infof("Reasoning mode decision: Category '%s' → %s",
4242
categoryName, reasoningStatus)
4343
return category.UseReasoning, categoryName
4444
}
4545
}
4646

4747
// If category not found in config, default to no reasoning
48-
log.Printf("Category '%s' not found in configuration, defaulting to no reasoning mode", categoryName)
48+
observability.Infof("Category '%s' not found in configuration, defaulting to no reasoning mode", categoryName)
4949
return false, categoryName
5050
}
5151

@@ -55,7 +55,7 @@ func (r *OpenAIRouter) getEntropyBasedReasoningModeAndCategory(query string) (bo
5555
categoryName, confidence, reasoningDecision, err := r.Classifier.ClassifyCategoryWithEntropy(query)
5656

5757
if err != nil {
58-
log.Printf("Entropy-based classification error: %v, falling back to traditional method", err)
58+
observability.Warnf("Entropy-based classification error: %v, falling back to traditional method", err)
5959

6060
// Record fallback metrics
6161
metrics.RecordEntropyFallback("classification_error", "traditional_method")
@@ -74,12 +74,12 @@ func (r *OpenAIRouter) getEntropyBasedReasoningModeAndCategory(query string) (bo
7474
}
7575

7676
// Log the entropy-based decision
77-
log.Printf("Entropy-based reasoning decision: category='%s', confidence=%.3f, use_reasoning=%t, reason=%s, strategy=%s",
77+
observability.Infof("Entropy-based reasoning decision: category='%s', confidence=%.3f, use_reasoning=%t, reason=%s, strategy=%s",
7878
categoryName, confidence, reasoningDecision.UseReasoning, reasoningDecision.DecisionReason, reasoningDecision.FallbackStrategy)
7979

8080
// If we have top categories from entropy analysis, log them
8181
if len(reasoningDecision.TopCategories) > 0 {
82-
log.Printf("Top predicted categories: %v", reasoningDecision.TopCategories)
82+
observability.Infof("Top predicted categories: %v", reasoningDecision.TopCategories)
8383
}
8484

8585
return reasoningDecision.UseReasoning, categoryName, reasoningDecision
@@ -181,11 +181,11 @@ func (r *OpenAIRouter) setReasoningModeToRequestBody(requestBody []byte, enabled
181181

182182
// Log based on what actually happened
183183
if enabled && !reasoningApplied {
184-
log.Printf("No reasoning support for model: %s (no reasoning family configured)", model)
184+
observability.Infof("No reasoning support for model: %s (no reasoning family configured)", model)
185185
} else if reasoningApplied {
186-
log.Printf("Applied reasoning mode (enabled: %v) with effort (%s) to model: %s", enabled, appliedEffort, model)
186+
observability.Infof("Applied reasoning mode (enabled: %v) with effort (%s) to model: %s", enabled, appliedEffort, model)
187187
} else {
188-
log.Printf("Reasoning mode disabled for model: %s", model)
188+
observability.Infof("Reasoning mode disabled for model: %s", model)
189189
}
190190

191191
// Record metrics for template usage and effort when enabled
@@ -228,7 +228,7 @@ func (r *OpenAIRouter) setReasoningModeToRequestBody(requestBody []byte, enabled
228228
// logReasoningConfiguration logs the reasoning mode configuration for all categories during startup
229229
func (r *OpenAIRouter) logReasoningConfiguration() {
230230
if len(r.Config.Categories) == 0 {
231-
log.Printf("No categories configured for reasoning mode")
231+
observability.Infof("No categories configured for reasoning mode")
232232
return
233233
}
234234

@@ -243,14 +243,14 @@ func (r *OpenAIRouter) logReasoningConfiguration() {
243243
}
244244
}
245245

246-
log.Printf("Reasoning configuration - Total categories: %d", len(r.Config.Categories))
246+
observability.Infof("Reasoning configuration - Total categories: %d", len(r.Config.Categories))
247247

248248
if len(reasoningEnabled) > 0 {
249-
log.Printf("Reasoning ENABLED for categories (%d): %v", len(reasoningEnabled), reasoningEnabled)
249+
observability.Infof("Reasoning ENABLED for categories (%d): %v", len(reasoningEnabled), reasoningEnabled)
250250
}
251251

252252
if len(reasoningDisabled) > 0 {
253-
log.Printf("Reasoning DISABLED for categories (%d): %v", len(reasoningDisabled), reasoningDisabled)
253+
observability.Infof("Reasoning DISABLED for categories (%d): %v", len(reasoningDisabled), reasoningDisabled)
254254
}
255255
}
256256

@@ -266,7 +266,7 @@ func (r *OpenAIRouter) ClassifyAndDetermineReasoningMode(query string) (string,
266266
if useReasoning {
267267
reasoningStatus = "enabled"
268268
}
269-
log.Printf("Model selection complete: model=%s, reasoning=%s", bestModel, reasoningStatus)
269+
observability.Infof("Model selection complete: model=%s, reasoning=%s", bestModel, reasoningStatus)
270270

271271
return bestModel, useReasoning
272272
}
@@ -284,7 +284,7 @@ func (r *OpenAIRouter) LogReasoningConfigurationSummary() {
284284
}
285285
}
286286

287-
log.Printf("Reasoning mode summary: %d/%d categories have reasoning enabled", enabledCount, len(r.Config.Categories))
287+
observability.Infof("Reasoning mode summary: %d/%d categories have reasoning enabled", enabledCount, len(r.Config.Categories))
288288
}
289289

290290
// getReasoningEffort returns the reasoning effort level for a given category

0 commit comments

Comments
 (0)