Terminal logging is now coloured only on an interactive terminal
The terminal logger always coloured its text, so output piped or redirected to a file, and the systemd journal, got escape codes. It now colours only an interactive terminal. The service's logs can therefore go to the journal: logging.file is now optional for it, and the unit's comments and the README say so.
This commit is contained in:
1 parent
2aeb2993b0
commit
71eca2f194
4 files changed
+45
-9
No files matched your search
@@ -44,8 +44,10 @@ The `sqlite_fts5` tag is needed for the database's title search (see
|
|||||||
(the server and every enabled source's fetcher) as a `job-search` system
|
(the server and every enabled source's fetcher) as a `job-search` system
|
||||||
user, from `/usr/local/bin/job-search` with `/etc/job-search/config.yaml`.
|
user, from `/usr/local/bin/job-search` with `/etc/job-search/config.yaml`.
|
||||||
Its comments give the install steps. It keeps its data in
|
Its comments give the install steps. It keeps its data in
|
||||||
`/var/lib/job-search` and its log in `/var/log/job-search`, the only places
|
`/var/lib/job-search` and any log file in `/var/log/job-search`, the only
|
||||||
it can write, so set `database.file` and `logging.file` there.
|
places it can write, so set `database.file` there. Logs go to the journal
|
||||||
|
(`journalctl -u job-search`) unless `logging.file` is set to a file in
|
||||||
|
`/var/log/job-search`, which then needs rotating (below).
|
||||||
|
|
||||||
- The database isn't migrated on start: run `job-search migrate up`
|
- The database isn't migrated on start: run `job-search migrate up`
|
||||||
(`--create` the first time) as the `job-search` user before the first
|
(`--create` the first time) as the `job-search` user before the first
|
||||||
|
|||||||
@@ -12,13 +12,13 @@
|
|||||||
# sudo systemctl daemon-reload
|
# sudo systemctl daemon-reload
|
||||||
# sudo systemctl enable --now job-search
|
# sudo systemctl enable --now job-search
|
||||||
#
|
#
|
||||||
# /etc/job-search/config.yaml should set at least:
|
# /etc/job-search/config.yaml should set the database:
|
||||||
# database:
|
# database:
|
||||||
# file: /var/lib/job-search/jobsearch.db
|
# file: /var/lib/job-search/jobsearch.db
|
||||||
|
# Logs go to the journal (journalctl -u job-search), unless logging.file is
|
||||||
|
# set to log to a file instead, rotated with job-search.logrotate:
|
||||||
# logging:
|
# logging:
|
||||||
# file: /var/log/job-search/job-search.log
|
# file: /var/log/job-search/job-search.log
|
||||||
# Without logging.file, logs go to the journal (as coloured text). Rotate the
|
|
||||||
# log file with job-search.logrotate:
|
|
||||||
# sudo install -m 644 job-search.logrotate /etc/logrotate.d/job-search
|
# sudo install -m 644 job-search.logrotate /etc/logrotate.d/job-search
|
||||||
#
|
#
|
||||||
# After each upgrade, migrate the database before restarting:
|
# After each upgrade, migrate the database before restarting:
|
||||||
|
|||||||
@@ -79,16 +79,20 @@ func Shutdown() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// LogToTerminal sends all logging to stdout as coloured text, replacing the
|
// LogToTerminal sends all logging to stdout as text, replacing the default
|
||||||
// default slog logger. When stdout is an interactive terminal, loggers
|
// slog logger. The text is coloured only on an interactive terminal, so a
|
||||||
// derived from it report so to WritesToTerminal.
|
// pipe, a file or the systemd journal gets no escape codes. On an
|
||||||
|
// interactive terminal, loggers derived from it report so to
|
||||||
|
// WritesToTerminal.
|
||||||
func LogToTerminal() {
|
func LogToTerminal() {
|
||||||
|
interactive := isTerminal(terminal)
|
||||||
opts := &tint.Options{
|
opts := &tint.Options{
|
||||||
Level: &logLevel,
|
Level: &logLevel,
|
||||||
TimeFormat: "*",
|
TimeFormat: "*",
|
||||||
|
NoColor: !interactive,
|
||||||
}
|
}
|
||||||
handler := tint.NewTextHandler(terminal, opts)
|
handler := tint.NewTextHandler(terminal, opts)
|
||||||
if isTerminal(terminal) {
|
if interactive {
|
||||||
handler = terminalHandler{
|
handler = terminalHandler{
|
||||||
Handler: handler,
|
Handler: handler,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -171,6 +171,36 @@ func TestLogToTerminal(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The text is coloured on an interactive terminal only.
|
||||||
|
func TestLogToTerminalColour(t *testing.T) {
|
||||||
|
for _, interactive := range []bool{true, false} {
|
||||||
|
saveGlobals(t)
|
||||||
|
out, err := os.CreateTemp(t.TempDir(), "stdout")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Cleanup(func() {
|
||||||
|
out.Close()
|
||||||
|
})
|
||||||
|
terminal = out
|
||||||
|
isTerminal = func(*os.File) bool {
|
||||||
|
return interactive
|
||||||
|
}
|
||||||
|
|
||||||
|
LogToTerminal()
|
||||||
|
slog.Warn("hello", "key", "value")
|
||||||
|
|
||||||
|
written, err := os.ReadFile(out.Name())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
coloured := strings.Contains(string(written), "\x1b[")
|
||||||
|
if coloured != interactive || !strings.Contains(string(written), "hello") {
|
||||||
|
t.Errorf("interactive %v: wrote %q", interactive, written)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// On an interactive terminal the handler, and loggers derived from it, report
|
// On an interactive terminal the handler, and loggers derived from it, report
|
||||||
// that they write to the terminal; when stdout is a file or pipe they don't.
|
// that they write to the terminal; when stdout is a file or pipe they don't.
|
||||||
func TestWritesToTerminal(t *testing.T) {
|
func TestWritesToTerminal(t *testing.T) {
|
||||||
|
|||||||
Reference in new issue
Block a user