logfile colors

This commit is contained in:
ed
2026-03-19 00:57:09 +00:00
parent dcb0ffa72c
commit 8c6d8a3c22
2 changed files with 99 additions and 1 deletions

View File

@@ -65,6 +65,7 @@ built in Norway 🇳🇴 with contributions from [not-norway](https://github.com
* [searching](#searching) - search by size, date, path/name, mp3-tags, ...
* [server config](#server-config) - using arguments or config files, or a mix of both
* [version-checker](#version-checker) - sleep better at night
* [logging](#logging) - serverlog is sent to stdout by default
* [zeroconf](#zeroconf) - announce enabled services on the LAN ([pic](https://user-images.githubusercontent.com/241032/215344737-0eae8d98-9496-4256-9aa8-cd2f6971810d.png))
* [mdns](#mdns) - LAN domain-name and feature announcer
* [ssdp](#ssdp) - windows-explorer announcer
@@ -1339,6 +1340,33 @@ config file example:
```
## logging
serverlog is sent to stdout by default (but logging to a file is also possible)
"stdout" usually means either the terminal, or journalctl, or whatever is collecting logs from your docker containers, so that depends on your setup
* [-q](https://copyparty.eu/cli/#g-q) disables logging to stdout, and may improve performance a little bit
* combine it with `-lo logfolder/cpp-%Y-%m-%d.txt` to log to a file instead
* the `%Y-%m-%d` makes it create a new logfile every day, with the date as filename
* `-lo whatever.txt` can be used without `-q` to log to both at the same time
* by default, the logfile will have colors if the terminal does (usually the case)
* use the [textfile-viewer](https://github.com/user-attachments/assets/8a828947-2fae-4df9-bd2a-3de46f42d478) or `less -R` in a terminal to see colors correctly
* if you want [no colors](https://youtu.be/biW5UVGkPMA?t=148):
* `--flo 2` disables colors for just the logfile
* `--no-ansi` disables colors for both the terminal and logfile
config file example:
```yaml
[global]
log-date: %Y-%m-%d # show dates on stdout too
lo: /var/log/cpp/%Y-%m-%d.txt # logfile path
flo: 2 # just text (no colors) in logfile
q # disable stdout; use logfile only
```
## zeroconf
announce enabled services on the LAN ([pic](https://user-images.githubusercontent.com/241032/215344737-0eae8d98-9496-4256-9aa8-cd2f6971810d.png)) -- `-z` enables both [mdns](#mdns) and [ssdp](#ssdp)

View File

@@ -196,7 +196,14 @@ class SvcHub(object):
self.log_div = 10 ** (6 - args.log_tdec)
self.log_efmt = "%02d:%02d:%02d.%0{}d".format(args.log_tdec)
self.log_dfmt = "%04d-%04d-%06d.%0{}d".format(args.log_tdec)
self.log = self._log_disabled if args.q else self._log_enabled
if args.q:
self.log = self._log_disabled
elif args.lo and args.flo == 2 and not self.no_ansi:
self.log = self._log_en_f2
else:
self.log = self._log_enabled
if args.lo:
self._setup_logfile(printed)
@@ -1714,6 +1721,69 @@ class SvcHub(object):
if not self.args.no_logflush:
self.logf.flush()
def _log_en_f2(self, src: str, msg: str, c: Union[int, str] = 0) -> None:
with self.log_mutex:
dt = datetime.now(self.tz)
if dt.day != self.cday or dt.month != self.cmon:
if self.args.log_date:
zs = dt.strftime(self.args.log_date)
self.log_efmt = "%s %s" % (zs, self.log_efmt.split(" ")[-1])
zs = "{}\n" if self.no_ansi else "\033[36m{}\033[0m\n"
zs = zs.format(dt.strftime("%Y-%m-%d"))
print(zs, end="")
self._set_next_day(dt)
if self.logf:
self.logf.write(zs)
ts = self.log_efmt % (
dt.hour,
dt.minute,
dt.second,
dt.microsecond // self.log_div,
)
# logfile:
if not c:
fmt = "%s %-21s LOG: %s\n"
elif c == 1:
fmt = "%s %-21s CRIT: %s\n"
elif c == 3:
fmt = "%s %-21s WARN: %s\n"
elif c == 6:
fmt = "%s %-21s BTW: %s\n"
else:
fmt = "%s %-21s LOG: %s\n"
fsrc = RE_ANSI.sub("", src) if "\033" in src else src
fmsg = RE_ANSI.sub("", msg) if "\033" in msg else msg
fmsg = fmt % (ts, fsrc, fmsg)
# stdout ansi:
fmt = "\033[36m%s \033[33m%-21s \033[0m%s\n"
if not c:
pass
elif isinstance(c, int):
msg = "\033[3%sm%s\033[0m" % (c, msg)
elif "\033" not in c:
msg = "\033[%sm%s\033[0m" % (c, msg)
else:
msg = "%s%s\033[0m" % (c, msg)
msg = fmt % (ts, src, msg)
try:
print(msg, end="")
except UnicodeEncodeError:
try:
print(msg.encode("utf-8", "replace").decode(), end="")
except:
print(msg.encode("ascii", "replace").decode(), end="")
except OSError as ex:
if ex.errno != errno.EPIPE:
raise
self.logf.write(fmsg)
if not self.args.no_logflush:
self.logf.flush()
def pr(self, *a: Any, **ka: Any) -> None:
try:
with self.log_mutex: