~bigbes/sr-ht-dolt

ref: 5b00a51648a18e461bce9400d9fade6c9eeba28b sr-ht-dolt/cmd/doltsrht/logging.go -rw-r--r-- 2.7 KiB
5b00a516 — Eugene Blikh browse: say which cells are actually NULL 5 days ago
                                                                                
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
package main

import (
	"os"

	"github.com/vaughan0/go-ini"

	"go.bigb.es/auxilia/scribe"

	"sourcecraft.dev/bigbes/sr-ht-ecore/logging"
)

// setupLogging installs the process-wide slog handler.
//
// It sets the *default* logger rather than building one to thread through
// constructors, and that is the point rather than a shortcut. sr-ht-ecore's
// middleware reports a recovered panic through slog's default; so does every
// library package in this service that has no constructor to be handed a logger
// through (authn's cookie and JWT resolvers, the web renderer). A daemon that
// skipped this call would still log all of it — into Go's plain stderr handler,
// without a level, without source positions, and above all without the masking
// below.
//
// The policy is sr-ht-ecore's and the handler is ours, which is the split that
// package documents: the level, the colour decision and — the part that is not
// presentation — the set of attribute keys that must never reach a log file are
// facts about this instance and are maintained once, while the handler that
// spends them stays here, because a service wanting a JSON handler for a log
// shipper should not have to link a tinting one to share a mask list.
//
// The verbosity is [dolt.sr.ht]log-level ("debug", "info", "warn", "error") as
// before, and now also $LOG_LEVEL and the -d every SourceHut daemon takes. -d is
// resolved here rather than left to server.New because server.New runs after
// config loading and validation: a daemon that becomes verbose only once it has
// started is silent for exactly the window an operator passes -d to watch. An
// unreadable value is info, because a daemon that refused to boot over a typo in
// a log level would be trading an operator's whole service for their logging
// preference.
func setupLogging(conf ini.File) {
	opts := logging.Defaults(conf, serviceName)

	logging.Install(scribe.NewTintHandler(
		scribe.WithWriter(os.Stderr),
		scribe.WithLevel(opts.Level),
		scribe.WithSource(opts.AddSource),
		scribe.WithTimeFormat(opts.TimeFormat),
		// Colour is for a terminal; under systemd or a container's log
		// collector the escapes are noise in the journal.
		scribe.WithNoColor(!opts.Color),
		// The masks are keyed on the attribute *path*, not on the message, so
		// they cost nothing in prose and cannot be defeated by a sentence that
		// happens to contain the word "token". Taking the instance's list rather
		// than this service's three adds the keys the siblings had learned to
		// redact and this one had not — the network and webhook private keys out
		// of config.ini, and the migration DSN, which carries a password.
		scribe.WithMaskKeys(opts.MaskKeys...),
		scribe.WithMask(opts.MaskPattern, opts.MaskReplacement),
	))
}