|
1 | 1 | package log |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "io" |
4 | 5 | "log/slog" |
5 | 6 | "os" |
| 7 | + "path/filepath" |
6 | 8 | ) |
7 | 9 |
|
8 | 10 | // Re-export slog attribute constructors so callers don't need to import log/slog |
@@ -53,12 +55,39 @@ func Wrap(l *slog.Logger) Logger { |
53 | 55 | return &logger{l} |
54 | 56 | } |
55 | 57 |
|
56 | | -// New creates a new logger that writes to /tmp/tero.log |
| 58 | +// LogPath returns the log file path for the given environment. |
| 59 | +func LogPath(env string) (string, error) { |
| 60 | + homeDir, err := os.UserHomeDir() |
| 61 | + if err != nil { |
| 62 | + return "", err |
| 63 | + } |
| 64 | + return filepath.Join(homeDir, ".tero", "environments", env, "tero.log"), nil |
| 65 | +} |
| 66 | + |
| 67 | +const maxLogSize = 5 * 1024 * 1024 // 5MB |
| 68 | + |
| 69 | +// New creates a new logger that writes to ~/.tero/environments/{env}/tero.log. |
57 | 70 | // Appends to existing log file, with a clear session separator. |
58 | | -func New(level Level) Logger { |
59 | | - logFile, err := os.OpenFile("/tmp/tero.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) |
| 71 | +// Truncates the file at session start if it exceeds 5MB. |
| 72 | +// Falls back to a no-op logger if the log file cannot be opened. |
| 73 | +func New(env string, level Level) Logger { |
| 74 | + logPath, err := LogPath(env) |
| 75 | + if err != nil { |
| 76 | + return &logger{slog.New(slog.NewTextHandler(io.Discard, nil))} |
| 77 | + } |
| 78 | + |
| 79 | + if err := os.MkdirAll(filepath.Dir(logPath), 0o755); err != nil { |
| 80 | + return &logger{slog.New(slog.NewTextHandler(io.Discard, nil))} |
| 81 | + } |
| 82 | + |
| 83 | + // Truncate if over size limit before opening for append. |
| 84 | + if info, err := os.Stat(logPath); err == nil && info.Size() > maxLogSize { |
| 85 | + _ = os.Truncate(logPath, 0) |
| 86 | + } |
| 87 | + |
| 88 | + logFile, err := os.OpenFile(logPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o644) |
60 | 89 | if err != nil { |
61 | | - panic(err) |
| 90 | + return &logger{slog.New(slog.NewTextHandler(io.Discard, nil))} |
62 | 91 | } |
63 | 92 |
|
64 | 93 | // Write session separator (ignore errors - best effort logging) |
|
0 commit comments