summaryrefslogtreecommitdiff
path: root/internal/cmd/logger.go
blob: 3231abb2f9c0a19781b92220d4116011a46ce56b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package cmd

import (
	"io"
	"log/slog"
	"os"
	"runtime"

	"github.com/hairyhenderson/gomplate/v4/env"
	"github.com/lmittmann/tint"
	"golang.org/x/term"
)

func logFormat(out io.Writer) string {
	defaultFormat := "json"
	if f, ok := out.(*os.File); ok && term.IsTerminal(int(f.Fd())) {
		defaultFormat = "console"
	}
	return env.Getenv("GOMPLATE_LOG_FORMAT", defaultFormat)
}

func createLogHandler(format string, out io.Writer, level slog.Level) slog.Handler {
	opts := &slog.HandlerOptions{Level: level}

	var handler slog.Handler
	switch format {
	case "console":
		// logFormat() already checks if this is a terminal, but we need to
		// check again because the format may be overridden with `GOMPLATE_LOG_FORMAT`
		useColour := false
		if f, ok := out.(*os.File); ok && term.IsTerminal(int(f.Fd())) && runtime.GOOS != "windows" {
			useColour = true
		}
		handler = tint.NewHandler(out, &tint.Options{
			Level:      level,
			TimeFormat: "15:04:05",
			NoColor:    !useColour,
		})
	case "simple":
		handler = tint.NewHandler(out, &tint.Options{
			Level:   level,
			NoColor: true,
			ReplaceAttr: func(_ []string, attr slog.Attr) slog.Attr {
				if attr.Key == "level" {
					attr.Value = slog.StringValue("")
				}
				if attr.Key == "time" {
					attr.Value = slog.StringValue("")
				}
				return attr
			},
		})
	case "logfmt":
		handler = slog.NewTextHandler(out, opts)
	default:
		// json is still default
		handler = slog.NewJSONHandler(out, opts)
	}

	return handler
}

func initLogger(out io.Writer, level slog.Level) {
	// default to warn level
	if level == 0 {
		level = slog.LevelWarn
	}

	handler := createLogHandler(logFormat(out), out, level)
	slog.SetDefault(slog.New(handler))
}