From 09ee2de72936ea0b0edc5d3360ce1c72803a817b Mon Sep 17 00:00:00 2001 From: Alan Pearce Date: Sun, 19 May 2024 15:42:36 +0200 Subject: log in logfmt via zap, with nicer console output in dev --- internal/builder/builder.go | 26 ++++++++++++------------ internal/builder/posts.go | 6 +++--- internal/builder/template.go | 6 +++--- internal/config/config.go | 4 ++-- internal/log/log.go | 48 ++++++++++++++++++++++++++++++++++++++++++++ internal/server/filemap.go | 8 ++++---- internal/server/server.go | 19 +++++++++--------- 7 files changed, 82 insertions(+), 35 deletions(-) create mode 100644 internal/log/log.go (limited to 'internal') diff --git a/internal/builder/builder.go b/internal/builder/builder.go index cb3b670..a8205a3 100644 --- a/internal/builder/builder.go +++ b/internal/builder/builder.go @@ -3,13 +3,13 @@ package builder import ( "fmt" "io" - "log/slog" "net/url" "os" "path" "slices" "website/internal/config" + "website/internal/log" cp "github.com/otiai10/copy" "github.com/pkg/errors" @@ -27,7 +27,7 @@ func mkdirp(dirs ...string) error { } func outputToFile(output io.Reader, filename ...string) error { - slog.Debug(fmt.Sprintf("outputting file %s", path.Join(filename...))) + log.Debug("outputting file", "filename", path.Join(filename...)) file, err := os.OpenFile(path.Join(filename...), os.O_WRONLY|os.O_CREATE, 0644) if err != nil { return errors.WithMessage(err, "could not open output file") @@ -41,7 +41,7 @@ func outputToFile(output io.Reader, filename ...string) error { } func build(outDir string, config config.Config) error { - slog.Debug(fmt.Sprintf("output directory %s", outDir)) + log.Debug("output", "dir", outDir) privateDir := path.Join(outDir, "private") if err := mkdirp(privateDir); err != nil { return errors.WithMessage(err, "could not create private directory") @@ -62,7 +62,7 @@ func build(outDir string, config config.Config) error { if err := mkdirp(publicDir, "post"); err != nil { return errors.WithMessage(err, "could not create post output directory") } - slog.Debug("reading posts") + log.Debug("reading posts") posts, tags, err := readPosts("content", "post", publicDir) if err != nil { return err @@ -72,7 +72,7 @@ func build(outDir string, config config.Config) error { if err := mkdirp(publicDir, "post", post.Basename); err != nil { return errors.WithMessage(err, "could not create directory for post") } - slog.Debug("rendering post", "post", post.Basename) + log.Debug("rendering post", "post", post.Basename) output, err := renderPost(post, config) if err != nil { return errors.WithMessagef(err, "could not render post %s", post.Input) @@ -85,7 +85,7 @@ func build(outDir string, config config.Config) error { if err := mkdirp(publicDir, "tags"); err != nil { return errors.WithMessage(err, "could not create directory for tags") } - slog.Debug("rendering tags list") + log.Debug("rendering tags list") output, err := renderTags(tags, config, "/tags") if err != nil { return errors.WithMessage(err, "could not render tags") @@ -104,7 +104,7 @@ func build(outDir string, config config.Config) error { if err := mkdirp(publicDir, "tags", tag); err != nil { return errors.WithMessage(err, "could not create directory") } - slog.Debug("rendering tags page", "tag", tag) + log.Debug("rendering tags page", "tag", tag) output, err := renderListPage(tag, config, matchingPosts, "/tags/"+tag) if err != nil { return errors.WithMessage(err, "could not render tag page") @@ -113,7 +113,7 @@ func build(outDir string, config config.Config) error { return err } - slog.Debug("rendering tags feed", "tag", tag) + log.Debug("rendering tags feed", "tag", tag) output, err = renderFeed( fmt.Sprintf("%s - %s", config.Title, tag), config, @@ -128,7 +128,7 @@ func build(outDir string, config config.Config) error { } } - slog.Debug("rendering list page") + log.Debug("rendering list page") listPage, err := renderListPage("", config, posts, "/post") if err != nil { return errors.WithMessage(err, "could not render list page") @@ -137,7 +137,7 @@ func build(outDir string, config config.Config) error { return err } - slog.Debug("rendering feed") + log.Debug("rendering feed") feed, err := renderFeed(config.Title, config, posts, "feed") if err != nil { return errors.WithMessage(err, "could not render feed") @@ -146,7 +146,7 @@ func build(outDir string, config config.Config) error { return err } - slog.Debug("rendering feed styles") + log.Debug("rendering feed styles") feedStyles, err := renderFeedStyles() if err != nil { return errors.WithMessage(err, "could not render feed styles") @@ -155,7 +155,7 @@ func build(outDir string, config config.Config) error { return err } - slog.Debug("rendering homepage") + log.Debug("rendering homepage") homePage, err := renderHomepage(config, posts, "/") if err != nil { return errors.WithMessage(err, "could not render homepage") @@ -164,7 +164,7 @@ func build(outDir string, config config.Config) error { return err } - slog.Debug("rendering 404 page") + log.Debug("rendering 404 page") notFound, err := render404(config, "/404.html") if err != nil { return errors.WithMessage(err, "could not render 404 page") diff --git a/internal/builder/posts.go b/internal/builder/posts.go index a4526e4..954e259 100644 --- a/internal/builder/posts.go +++ b/internal/builder/posts.go @@ -2,13 +2,13 @@ package builder import ( "bytes" - "log/slog" "os" "path" "path/filepath" "slices" "strings" "time" + "website/internal/log" "github.com/adrg/frontmatter" mapset "github.com/deckarep/golang-set/v2" @@ -91,7 +91,7 @@ func readPosts(root string, inputDir string, outputDir string) ([]Post, Tags, er if !f.IsDir() && path.Ext(pathFromRoot) == ".md" { output := outputReplacer.Replace(pathFromRoot) url := urlReplacer.Replace(pathFromRoot) - slog.Debug("reading post", "post", pathFromRoot) + log.Debug("reading post", "post", pathFromRoot) matter, content, err := getPost(pathFromRoot) if err != nil { return nil, nil, err @@ -101,7 +101,7 @@ func readPosts(root string, inputDir string, outputDir string) ([]Post, Tags, er tags.Add(strings.ToLower(tag)) } - slog.Debug("rendering markdown in post", "post", pathFromRoot) + log.Debug("rendering markdown in post", "post", pathFromRoot) html, err := renderMarkdown(content) if err != nil { return nil, nil, err diff --git a/internal/builder/template.go b/internal/builder/template.go index 5bd990e..c63e1c2 100644 --- a/internal/builder/template.go +++ b/internal/builder/template.go @@ -4,7 +4,6 @@ import ( "encoding/xml" "fmt" "io" - "log/slog" "net/url" "os" "strings" @@ -12,6 +11,7 @@ import ( "time" "website/internal/atom" "website/internal/config" + "website/internal/log" "github.com/PuerkitoBio/goquery" "github.com/a-h/htmlformat" @@ -391,12 +391,12 @@ func renderHTML(doc *goquery.Document) io.Reader { go func() { _, err := w.Write([]byte("\n")) if err != nil { - slog.Error("error writing doctype") + log.Error("error writing doctype", "error", err) w.CloseWithError(err) } err = htmlformat.Nodes(w, []*html.Node{doc.Children().Get(0)}) if err != nil { - slog.Error("error rendering html", "error", err) + log.Error("error rendering html", "error", err) w.CloseWithError(err) return } diff --git a/internal/config/config.go b/internal/config/config.go index 47422e7..063f549 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -2,8 +2,8 @@ package config import ( "io/fs" - "log/slog" "net/url" + "website/internal/log" "github.com/BurntSushi/toml" "github.com/pkg/errors" @@ -47,7 +47,7 @@ type Config struct { func GetConfig() (*Config, error) { config := Config{} - slog.Debug("reading config.toml") + log.Debug("reading config.toml") _, err := toml.DecodeFile("config.toml", &config) if err != nil { var pathError *fs.PathError diff --git a/internal/log/log.go b/internal/log/log.go new file mode 100644 index 0000000..e16d7bb --- /dev/null +++ b/internal/log/log.go @@ -0,0 +1,48 @@ +package log + +import ( + "os" + + zaplogfmt "github.com/sykesm/zap-logfmt" + prettyconsole "github.com/thessem/zap-prettyconsole" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +var logger *zap.SugaredLogger + +func DPanic(msg string, rest ...any) { + logger.DPanicw(msg, rest...) +} +func Debug(msg string, rest ...any) { + logger.Debugw(msg, rest...) +} +func Info(msg string, rest ...any) { + logger.Infow(msg, rest...) +} +func Warn(msg string, rest ...any) { + logger.Warnw(msg, rest...) +} +func Error(msg string, rest ...any) { + logger.Errorw(msg, rest...) +} +func Panic(msg string, rest ...any) { + logger.Panicw(msg, rest...) +} +func Fatal(msg string, rest ...any) { + logger.Fatalw(msg, rest...) +} + +func Configure(isProduction bool) { + var l *zap.Logger + if isProduction { + cfg := zap.NewProductionEncoderConfig() + cfg.TimeKey = "" + l = zap.New(zapcore.NewCore(zaplogfmt.NewEncoder(cfg), os.Stderr, zapcore.InfoLevel)) + } else { + cfg := prettyconsole.NewConfig() + cfg.EncoderConfig.TimeKey = "" + l = zap.Must(cfg.Build()) + } + logger = l.WithOptions(zap.AddCallerSkip(1)).Sugar() +} diff --git a/internal/server/filemap.go b/internal/server/filemap.go index 466db49..6130e65 100644 --- a/internal/server/filemap.go +++ b/internal/server/filemap.go @@ -5,12 +5,12 @@ import ( "hash/fnv" "io" "io/fs" - "log" - "log/slog" "os" "path/filepath" "strings" + "website/internal/log" + "github.com/pkg/errors" ) @@ -36,7 +36,7 @@ func hashFile(filename string) (string, error) { func registerFile(urlpath string, filepath string) error { if files[urlpath] != (File{}) { - log.Printf("registerFile called with duplicate file, urlPath: %s", urlpath) + log.Info("registerFile called with duplicate file", "url_path", urlpath) return nil } hash, err := hashFile(filepath) @@ -61,7 +61,7 @@ func registerContentFiles(root string) error { } urlPath, _ := strings.CutSuffix(relPath, "index.html") if !f.IsDir() { - slog.Debug("registering file", "urlpath", "/"+urlPath) + log.Debug("registering file", "urlpath", "/"+urlPath) return registerFile("/"+urlPath, filePath) } return nil diff --git a/internal/server/server.go b/internal/server/server.go index cbee989..62e32d5 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -4,8 +4,6 @@ import ( "context" "fmt" "io" - "log" - "log/slog" "mime" "net" "net/http" @@ -16,6 +14,7 @@ import ( "time" cfg "website/internal/config" + "website/internal/log" "github.com/getsentry/sentry-go" sentryhttp "github.com/getsentry/sentry-go/http" @@ -89,7 +88,7 @@ func (fn webHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { defer func() { if fail := recover(); fail != nil { w.WriteHeader(http.StatusInternalServerError) - slog.Error("runtime panic!", "error", fail) + log.Error("runtime panic!", "error", fail) } }() w.Header().Set("Server", fmt.Sprintf("website (%s)", ShortSHA)) @@ -111,7 +110,7 @@ var newMIMEs = map[string]string{ func fixupMIMETypes() { for ext, newType := range newMIMEs { if err := mime.AddExtensionType(ext, newType); err != nil { - slog.Error("could not update mime type", "ext", ext, "mime", newType) + log.Error("could not update mime type", "ext", ext, "mime", newType) } } } @@ -134,7 +133,7 @@ func New(runtimeConfig *Config) (*Server, error) { } prefix := path.Join(runtimeConfig.Root, "public") - slog.Debug("registering content files", "prefix", prefix) + log.Debug("registering content files", "prefix", prefix) err = registerContentFiles(prefix) if err != nil { return nil, errors.WithMessagef(err, "registering content files") @@ -161,7 +160,7 @@ func New(runtimeConfig *Config) (*Server, error) { top := http.NewServeMux() mux := http.NewServeMux() - slog.Debug("binding main handler to", "host", runtimeConfig.BaseURL.Hostname()+"/") + log.Debug("binding main handler to", "host", runtimeConfig.BaseURL.Hostname()+"/") mux.Handle(runtimeConfig.BaseURL.Hostname()+"/", webHandler(serveFile)) mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { @@ -205,19 +204,19 @@ func (s *Server) Start() error { } func (s *Server) Stop() chan struct{} { - slog.Debug("stop called") + log.Debug("stop called") idleConnsClosed := make(chan struct{}) go func() { - slog.Debug("shutting down server") + log.Debug("shutting down server") ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() err := s.Server.Shutdown(ctx) - slog.Debug("server shut down") + log.Debug("server shut down") if err != nil { // Error from closing listeners, or context timeout: - log.Printf("HTTP server Shutdown: %v", err) + log.Warn("HTTP server Shutdown", "error", err) } close(idleConnsClosed) }() -- cgit 1.4.1