| 1 |
|
package main |
| 2 |
|
|
| 3 |
|
import ( |
| 4 |
|
"os" |
| 5 |
|
|
| 6 |
|
"github.com/vaughan0/go-ini" |
| 7 |
|
|
| 8 |
|
"go.bigb.es/auxilia/scribe" |
| 9 |
|
|
| 10 |
|
"sourcecraft.dev/bigbes/sr-ht-ecore/logging" |
| 11 |
|
) |
| 12 |
|
|
| 13 |
|
// setupLogging installs the process-wide slog handler. |
| 14 |
|
// |
| 15 |
|
// It sets the *default* logger rather than building one to thread through |
| 16 |
|
// constructors, and that is the point rather than a shortcut. sr-ht-ecore's |
| 17 |
|
// middleware reports a recovered panic through slog's default; so does every |
| 18 |
|
// library package in this service that has no constructor to be handed a logger |
| 19 |
|
// through (authn's cookie and JWT resolvers, the web renderer). A daemon that |
| 20 |
|
// skipped this call would still log all of it — into Go's plain stderr handler, |
| 21 |
|
// without a level, without source positions, and above all without the masking |
| 22 |
|
// below. |
| 23 |
|
// |
| 24 |
|
// The policy is sr-ht-ecore's and the handler is ours, which is the split that |
| 25 |
|
// package documents: the level, the colour decision and — the part that is not |
| 26 |
|
// presentation — the set of attribute keys that must never reach a log file are |
| 27 |
|
// facts about this instance and are maintained once, while the handler that |
| 28 |
|
// spends them stays here, because a service wanting a JSON handler for a log |
| 29 |
|
// shipper should not have to link a tinting one to share a mask list. |
| 30 |
|
// |
| 31 |
|
// The verbosity is [dolt.sr.ht]log-level ("debug", "info", "warn", "error") as |
| 32 |
|
// before, and now also $LOG_LEVEL and the -d every SourceHut daemon takes. -d is |
| 33 |
|
// resolved here rather than left to server.New because server.New runs after |
| 34 |
|
// config loading and validation: a daemon that becomes verbose only once it has |
| 35 |
|
// started is silent for exactly the window an operator passes -d to watch. An |
| 36 |
|
// unreadable value is info, because a daemon that refused to boot over a typo in |
| 37 |
|
// a log level would be trading an operator's whole service for their logging |
| 38 |
|
// preference. |
| 39 |
0 |
func setupLogging(conf ini.File) { |
| 40 |
0 |
opts := logging.Defaults(conf, serviceName) |
| 41 |
0 |
|
| 42 |
0 |
logging.Install(scribe.NewTintHandler( |
| 43 |
0 |
scribe.WithWriter(os.Stderr), |
| 44 |
0 |
scribe.WithLevel(opts.Level), |
| 45 |
0 |
scribe.WithSource(opts.AddSource), |
| 46 |
0 |
scribe.WithTimeFormat(opts.TimeFormat), |
| 47 |
0 |
// Colour is for a terminal; under systemd or a container's log |
| 48 |
0 |
// collector the escapes are noise in the journal. |
| 49 |
0 |
scribe.WithNoColor(!opts.Color), |
| 50 |
0 |
// The masks are keyed on the attribute *path*, not on the message, so |
| 51 |
0 |
// they cost nothing in prose and cannot be defeated by a sentence that |
| 52 |
0 |
// happens to contain the word "token". Taking the instance's list rather |
| 53 |
0 |
// than this service's three adds the keys the siblings had learned to |
| 54 |
0 |
// redact and this one had not — the network and webhook private keys out |
| 55 |
0 |
// of config.ini, and the migration DSN, which carries a password. |
| 56 |
0 |
scribe.WithMaskKeys(opts.MaskKeys...), |
| 57 |
0 |
scribe.WithMask(opts.MaskPattern, opts.MaskReplacement), |
| 58 |
0 |
)) |
| 59 |
0 |
} |