Skip to content

Commit 8eecc78

Browse files
committed
Enhance logging and build process
- Added a new log adapter for integrating zerolog with Fx event logging. - Modified main application entry point to utilize the new logger. - Refactored UI handler to inject the logger for error handling. - Updated Makefile to build the application binary into a specified output directory. - Updated .gitignore to include build artifacts.
1 parent 5428244 commit 8eecc78

File tree

8 files changed

+172
-19
lines changed

8 files changed

+172
-19
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,6 @@ agent-browser
2828

2929
# MacOS
3030
.DS_Store
31+
32+
# Binaries and build artifacts
33+
out/

Makefile

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,30 @@
55

66
BINARY_NAME=agent-browser
77
CMD_PATH=./cmd/agent-browser
8+
OUTPUT_DIR=out
9+
BINARY_PATH=$(OUTPUT_DIR)/$(BINARY_NAME)
810

911
help:
1012
@echo "Usage: make [target]"
1113
@echo ""
1214
@echo "Targets:"
1315
@echo " help Show this help message (default)."
14-
@echo " build Build the Go application binary."
15-
@echo " run Build and run the Go application."
16+
@echo " build Build the Go application binary into $(OUTPUT_DIR)/."
17+
@echo " run Build and run the Go application from $(OUTPUT_DIR)/."
1618
@echo " generate Generate code (e.g., templ files)."
1719
@echo " test Run Go tests."
1820
@echo " fmt Format Go and templ code."
1921
@echo " lint Run golangci-lint (requires installation)."
2022
@echo " tidy Tidy Go module files."
2123

2224
build: generate
23-
@echo "Building $(BINARY_NAME)..."
24-
@go build -o $(BINARY_NAME) $(CMD_PATH)/main.go
25+
@echo "Building $(BINARY_NAME) into $(OUTPUT_DIR)/..."
26+
@mkdir -p $(OUTPUT_DIR) # Ensure output directory exists
27+
@go build -o $(BINARY_PATH) $(CMD_PATH)
2528

2629
run: build
27-
@echo "Running $(BINARY_NAME)..."
28-
@./$(BINARY_NAME)
30+
@echo "Running $(BINARY_NAME) from $(OUTPUT_DIR)/..."
31+
@$(BINARY_PATH)
2932

3033
generate:
3134
@echo "Generating templ files..."

cmd/agent-browser/main.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ package main
22

33
import (
44
"github.com/co-browser/agent-browser/internal/app"
5+
"github.com/co-browser/agent-browser/internal/log"
56
"go.uber.org/fx"
7+
"go.uber.org/fx/fxevent"
68
// No longer need context, errors, net/http, or log imports directly here
79
)
810

@@ -11,7 +13,13 @@ func main() {
1113
// Lifecycle management is handled within the invoked functions in the modules.
1214
fxApp := fx.New(
1315
app.CoreModules,
14-
// Add fx.NopLogger() here for quiet startup, or fx.WithLogger(...) for custom fx logging
16+
17+
// Configure Fx to use our custom zerolog logger
18+
fx.WithLogger(func(logger log.Logger) fxevent.Logger {
19+
// Use the adapter we created
20+
return log.NewFxZerologAdapter(logger)
21+
}),
22+
// Remove old comment: // Add fx.NopLogger() here for quiet startup, or fx.WithLogger(...) for custom fx logging
1523
)
1624

1725
// Run the application.

internal/app/app.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package app
22

33
import (
4+
"github.com/co-browser/agent-browser/internal/log"
45
"github.com/co-browser/agent-browser/internal/web"
56
"github.com/co-browser/agent-browser/internal/web/handlers"
6-
"github.com/co-browser/agent-browser/pkg/log"
77
"go.uber.org/fx"
88
)
99

internal/log/fx_adapter.go

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package log
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/rs/zerolog"
7+
"go.uber.org/fx/fxevent"
8+
)
9+
10+
// FxZerologAdapter implements fxevent.Logger, sending Fx logs to a zerolog.Logger.
11+
type FxZerologAdapter struct {
12+
Logger Logger // Use your abstract Logger interface (defined in log.go in the same package)
13+
}
14+
15+
// Ensure FxZerologAdapter implements fxevent.Logger
16+
var _ fxevent.Logger = (*FxZerologAdapter)(nil)
17+
18+
// NewFxZerologAdapter creates a new adapter.
19+
func NewFxZerologAdapter(logger Logger) *FxZerologAdapter {
20+
return &FxZerologAdapter{Logger: logger}
21+
}
22+
23+
// LogEvent logs the given event to the underlying zerolog logger.
24+
// It maps Fx event types to appropriate log levels and messages.
25+
func (l *FxZerologAdapter) LogEvent(event fxevent.Event) {
26+
switch e := event.(type) {
27+
case *fxevent.OnStartExecuting:
28+
l.Logger.Debug().Str("callee", e.FunctionName).Str("caller", e.CallerName).Msg("OnStart hook executing")
29+
case *fxevent.OnStartExecuted:
30+
if e.Err != nil {
31+
l.Logger.Error().Err(e.Err).Str("callee", e.FunctionName).Str("caller", e.CallerName).Msg("OnStart hook failed")
32+
} else {
33+
l.Logger.Debug().Str("callee", e.FunctionName).Str("caller", e.CallerName).Dur("runtime", e.Runtime).Msg("OnStart hook executed")
34+
}
35+
case *fxevent.OnStopExecuting:
36+
l.Logger.Debug().Str("callee", e.FunctionName).Str("caller", e.CallerName).Msg("OnStop hook executing")
37+
case *fxevent.OnStopExecuted:
38+
if e.Err != nil {
39+
l.Logger.Error().Err(e.Err).Str("callee", e.FunctionName).Str("caller", e.CallerName).Msg("OnStop hook failed")
40+
} else {
41+
l.Logger.Debug().Str("callee", e.FunctionName).Str("caller", e.CallerName).Dur("runtime", e.Runtime).Msg("OnStop hook executed")
42+
}
43+
case *fxevent.Supplied:
44+
// Suppress these noisy logs unless debugging Fx directly
45+
if z, ok := l.Logger.(*zerologLogger); ok && z.logger.GetLevel() <= zerolog.DebugLevel {
46+
if e.Err != nil {
47+
l.Logger.Debug().Err(e.Err).Str("type", e.TypeName).Str("module", e.ModuleName).Msg("supplied")
48+
} else {
49+
l.Logger.Debug().Str("type", e.TypeName).Str("module", e.ModuleName).Msg("supplied")
50+
}
51+
}
52+
case *fxevent.Provided:
53+
// Slightly less noisy than Supplied, keep at Debug.
54+
if e.Err != nil {
55+
l.Logger.Debug().Err(e.Err).Strs("output_types", e.OutputTypeNames).Str("module", e.ModuleName).Msg("provided")
56+
} else {
57+
l.Logger.Debug().Strs("output_types", e.OutputTypeNames).Str("module", e.ModuleName).Msg("provided")
58+
59+
// Specifically log the logger type when provided, similar to the guide example
60+
for _, typeName := range e.OutputTypeNames {
61+
if typeName == "*zap.Logger" || typeName == "log.Logger" || typeName == "*log.zerologLogger" { // Adjust if your type name is different
62+
l.Logger.Info().Str("type", typeName).Str("constructor", e.ConstructorName).Msg("Logger provided")
63+
}
64+
}
65+
}
66+
case *fxevent.Replaced:
67+
// Also noisy, keep at Debug.
68+
if e.Err != nil {
69+
l.Logger.Debug().Err(e.Err).Strs("output_types", e.OutputTypeNames).Str("module", e.ModuleName).Msg("replaced")
70+
} else {
71+
l.Logger.Debug().Strs("output_types", e.OutputTypeNames).Str("module", e.ModuleName).Msg("replaced")
72+
}
73+
case *fxevent.Decorated:
74+
// Also noisy, keep at Debug.
75+
if e.Err != nil {
76+
l.Logger.Debug().Err(e.Err).Strs("output_types", e.OutputTypeNames).Str("module", e.ModuleName).Msg("decorated")
77+
} else {
78+
l.Logger.Debug().Strs("output_types", e.OutputTypeNames).Str("decorator", e.DecoratorName).Str("module", e.ModuleName).Msg("decorated")
79+
}
80+
case *fxevent.Invoking:
81+
// Keep Invoking logs at Debug level.
82+
l.Logger.Debug().Str("function", e.FunctionName).Str("module", e.ModuleName).Msg("invoking")
83+
case *fxevent.Invoked:
84+
if e.Err != nil {
85+
l.Logger.Error().Err(e.Err).Str("function", e.FunctionName).Str("module", e.ModuleName).Str("trace", e.Trace).Msg("invoke failed")
86+
} else {
87+
// Keep successful invokes at Debug level.
88+
l.Logger.Debug().Str("function", e.FunctionName).Str("module", e.ModuleName).Msg("invoked")
89+
}
90+
case *fxevent.Stopping:
91+
l.Logger.Info().Str("signal", e.Signal.String()).Msg("received signal")
92+
case *fxevent.Stopped:
93+
if e.Err != nil {
94+
l.Logger.Error().Err(e.Err).Msg("stop failed")
95+
} else {
96+
l.Logger.Info().Msg("stopped")
97+
}
98+
case *fxevent.RollingBack:
99+
l.Logger.Error().Err(e.StartErr).Msg("start failed, rolling back")
100+
case *fxevent.RolledBack:
101+
if e.Err != nil {
102+
l.Logger.Error().Err(e.Err).Msg("rollback failed")
103+
} else {
104+
l.Logger.Info().Msg("rolled back")
105+
}
106+
case *fxevent.Started:
107+
if e.Err != nil {
108+
l.Logger.Error().Err(e.Err).Msg("start failed")
109+
} else {
110+
l.Logger.Info().Msg("started")
111+
}
112+
case *fxevent.LoggerInitialized:
113+
if e.Err != nil {
114+
l.Logger.Error().Err(e.Err).Msg("custom logger initialization failed")
115+
} else {
116+
// Use the provided constructor name if available.
117+
if e.ConstructorName != "" {
118+
l.Logger.Info().Str("function", e.ConstructorName).Msg("initialized custom fxevent.Logger")
119+
} else {
120+
l.Logger.Info().Msg("initialized custom fxevent.Logger")
121+
}
122+
}
123+
default:
124+
// Log unexpected event types
125+
l.Logger.Warn().Str("type", fmt.Sprintf("%T", event)).Msg("received unknown Fx event")
126+
}
127+
}
File renamed without changes.

internal/web/handlers/ui.go

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,29 @@ package handlers
33
import (
44
"net/http"
55

6+
"github.com/co-browser/agent-browser/internal/log"
67
"github.com/co-browser/agent-browser/internal/web/templates"
78
)
89

10+
// UIHandler holds dependencies for UI handlers.
11+
type UIHandler struct {
12+
log log.Logger
13+
}
14+
915
// NewUIHandler creates a handler for serving the main UI page.
10-
func NewUIHandler() http.Handler {
11-
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
12-
err := templates.IndexPage().Render(r.Context(), w)
13-
if err != nil {
14-
// Handle the error appropriately, e.g., log it and return an error response
15-
http.Error(w, "failed to render page", http.StatusInternalServerError)
16-
// Consider logging the error as well: log.Printf("Error rendering template: %v", err)
17-
}
18-
})
16+
// It now requires a logger.
17+
func NewUIHandler(logger log.Logger) http.Handler {
18+
h := &UIHandler{log: logger}
19+
return http.HandlerFunc(h.serveIndex)
20+
}
21+
22+
// serveIndex handles requests for the main UI page.
23+
func (h *UIHandler) serveIndex(w http.ResponseWriter, r *http.Request) {
24+
err := templates.IndexPage().Render(r.Context(), w)
25+
if err != nil {
26+
// Use the injected logger
27+
h.log.Error().Err(err).Msg("failed to render index page template")
28+
http.Error(w, "failed to render page", http.StatusInternalServerError)
29+
// Removed old comment: // Consider logging the error as well: log.Printf(\"Error rendering template: %v\", err)
30+
}
1931
}

internal/web/server.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ import (
55
"errors"
66
"net/http"
77

8-
"github.com/co-browser/agent-browser/pkg/log"
8+
"github.com/co-browser/agent-browser/internal/log"
99
"go.uber.org/fx"
1010
)
1111

1212
// NewMux creates the main HTTP ServeMux.
1313
func NewMux(uiHandler http.Handler /* add apiHandler http.Handler later */) *http.ServeMux {
1414
mux := http.NewServeMux()
1515
// Define routes here
16-
mux.Handle("/", uiHandler)
16+
mux.Handle("/ui", uiHandler)
1717
// TODO: Add routes for API handlers
1818
// mux.Handle("/api/", apiHandler)
1919
return mux

0 commit comments

Comments
 (0)