wip: logging improvements

This commit is contained in:
adamdottv
2025-05-09 13:37:13 -05:00
parent f41b7bbd0a
commit f100777199
41 changed files with 848 additions and 438 deletions

View File

@@ -7,6 +7,8 @@ import (
"sync"
"time"
"log/slog"
tea "github.com/charmbracelet/bubbletea"
zone "github.com/lrstanley/bubblezone"
"github.com/opencode-ai/opencode/internal/app"
@@ -38,6 +40,13 @@ to assist developers in writing, debugging, and understanding code directly from
return nil
}
// Setup logging
lvl := new(slog.LevelVar)
logger := slog.New(slog.NewTextHandler(logging.NewWriter(), &slog.HandlerOptions{
Level: lvl,
}))
slog.SetDefault(logger)
// Load the config
debug, _ := cmd.Flags().GetBool("debug")
cwd, _ := cmd.Flags().GetString("cwd")
@@ -54,14 +63,14 @@ to assist developers in writing, debugging, and understanding code directly from
}
cwd = c
}
_, err := config.Load(cwd, debug)
_, err := config.Load(cwd, debug, lvl)
if err != nil {
return err
}
// Run LSP auto-discovery
if err := discovery.IntegrateLSPServers(cwd); err != nil {
logging.Warn("Failed to auto-discover LSP servers", "error", err)
slog.Warn("Failed to auto-discover LSP servers", "error", err)
// Continue anyway, this is not a fatal error
}
@@ -77,7 +86,7 @@ to assist developers in writing, debugging, and understanding code directly from
app, err := app.New(ctx, conn)
if err != nil {
logging.Error("Failed to create app: %v", err)
slog.Error("Failed to create app: %v", err)
return err
}
@@ -109,11 +118,11 @@ to assist developers in writing, debugging, and understanding code directly from
for {
select {
case <-tuiCtx.Done():
logging.Info("TUI message handler shutting down")
slog.Info("TUI message handler shutting down")
return
case msg, ok := <-ch:
if !ok {
logging.Info("TUI message channel closed")
slog.Info("TUI message channel closed")
return
}
program.Send(msg)
@@ -135,7 +144,7 @@ to assist developers in writing, debugging, and understanding code directly from
// Wait for TUI message handler to finish
tuiWg.Wait()
logging.Info("All goroutines cleaned up")
slog.Info("All goroutines cleaned up")
}
// Run the TUI
@@ -143,18 +152,18 @@ to assist developers in writing, debugging, and understanding code directly from
cleanup()
if err != nil {
logging.Error("TUI error: %v", err)
slog.Error("TUI error: %v", err)
return fmt.Errorf("TUI error: %v", err)
}
logging.Info("TUI exited with result: %v", result)
slog.Info("TUI exited with result: %v", result)
return nil
},
}
// attemptTUIRecovery tries to recover the TUI after a panic
func attemptTUIRecovery(program *tea.Program) {
logging.Info("Attempting to recover TUI after panic")
slog.Info("Attempting to recover TUI after panic")
// We could try to restart the TUI or gracefully exit
// For now, we'll just quit the program to avoid further issues
@@ -171,7 +180,7 @@ func initMCPTools(ctx context.Context, app *app.App) {
// Set this up once with proper error handling
agent.GetMcpTools(ctxWithTimeout, app.Permissions)
logging.Info("MCP message handling goroutine exiting")
slog.Info("MCP message handling goroutine exiting")
}()
}
@@ -189,7 +198,7 @@ func setupSubscriber[T any](
subCh := subscriber(ctx)
if subCh == nil {
logging.Warn("subscription channel is nil", "name", name)
slog.Warn("subscription channel is nil", "name", name)
return
}
@@ -197,7 +206,7 @@ func setupSubscriber[T any](
select {
case event, ok := <-subCh:
if !ok {
logging.Info("subscription channel closed", "name", name)
slog.Info("subscription channel closed", "name", name)
return
}
@@ -206,13 +215,13 @@ func setupSubscriber[T any](
select {
case outputCh <- msg:
case <-time.After(2 * time.Second):
logging.Warn("message dropped due to slow consumer", "name", name)
slog.Warn("message dropped due to slow consumer", "name", name)
case <-ctx.Done():
logging.Info("subscription cancelled", "name", name)
slog.Info("subscription cancelled", "name", name)
return
}
case <-ctx.Done():
logging.Info("subscription cancelled", "name", name)
slog.Info("subscription cancelled", "name", name)
return
}
}
@@ -225,14 +234,14 @@ func setupSubscriptions(app *app.App, parentCtx context.Context) (chan tea.Msg,
wg := sync.WaitGroup{}
ctx, cancel := context.WithCancel(parentCtx) // Inherit from parent context
setupSubscriber(ctx, &wg, "logging", logging.Subscribe, ch)
setupSubscriber(ctx, &wg, "logging", app.Logs.Subscribe, ch)
setupSubscriber(ctx, &wg, "sessions", app.Sessions.Subscribe, ch)
setupSubscriber(ctx, &wg, "messages", app.Messages.Subscribe, ch)
setupSubscriber(ctx, &wg, "permissions", app.Permissions.Subscribe, ch)
setupSubscriber(ctx, &wg, "status", app.Status.Subscribe, ch)
cleanupFunc := func() {
logging.Info("Cancelling all subscriptions")
slog.Info("Cancelling all subscriptions")
cancel() // Signal all goroutines to stop
waitCh := make(chan struct{})
@@ -244,10 +253,10 @@ func setupSubscriptions(app *app.App, parentCtx context.Context) (chan tea.Msg,
select {
case <-waitCh:
logging.Info("All subscription goroutines completed successfully")
slog.Info("All subscription goroutines completed successfully")
close(ch) // Only close after all writers are confirmed done
case <-time.After(5 * time.Second):
logging.Warn("Timed out waiting for some subscription goroutines to complete")
slog.Warn("Timed out waiting for some subscription goroutines to complete")
close(ch)
}
}