feat: add portable directory safeguards
This commit is contained in:
@@ -3,6 +3,8 @@ package logging
|
||||
import (
|
||||
"io"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// New creates the process logger. Callers provide the sink so tests and the
|
||||
@@ -13,3 +15,17 @@ func New(w io.Writer) *slog.Logger {
|
||||
}
|
||||
return slog.New(slog.NewJSONHandler(w, &slog.HandlerOptions{Level: slog.LevelInfo}))
|
||||
}
|
||||
|
||||
// OpenFile creates an append-only local diagnostic log in the configured
|
||||
// directory. It never falls back to cwd, so a bad configured directory stays
|
||||
// visible to the caller instead of scattering logs beside a shortcut.
|
||||
func OpenFile(directory string) (*slog.Logger, io.Closer, error) {
|
||||
if err := os.MkdirAll(directory, 0o700); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
file, err := os.OpenFile(filepath.Join(directory, "chub.log"), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0o600)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return New(file), file, nil
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ package logging
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
@@ -20,3 +22,19 @@ func TestNewWritesStructuredLog(t *testing.T) {
|
||||
func TestNewNilWriterDoesNotPanic(t *testing.T) {
|
||||
New(nil).Info("discarded")
|
||||
}
|
||||
|
||||
func TestOpenFileWritesInsideConfiguredDirectory(t *testing.T) {
|
||||
directory := filepath.Join(t.TempDir(), "logs")
|
||||
logger, closer, err := OpenFile(directory)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
logger.Info("file event")
|
||||
if err := closer.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
contents, err := os.ReadFile(filepath.Join(directory, "chub.log"))
|
||||
if err != nil || !strings.Contains(string(contents), `"msg":"file event"`) {
|
||||
t.Fatalf("log contents = %q, error = %v", contents, err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user