ZFS Log Compression
Again and again I was annoyed when I found logs bz compressed on FreeBSD systems with ZFS root. Would it not be more effective and efficient to let ZFS do the compression transparently with zstd?
Today I got fed up and searched what others thought of this and I found this Article Log Compressin on FreeBSD.
They share my sentiment. Their remedy is to make sure zfs compression is enabled and switch off newsyslog bz compression:
Since we want ZFS to do the compression, remove the
Jfrom this column for each such log file listed there. Once finished with the changes, save and exit newsyslog.conf.
Doing the actual work
First we need to find every relevant file and then edit them all. Doing this by hand would be annoying on a single machine. What about hosts with many jails?
The relevant files
The relevant files are /etc/newsyslog.conf, all files
/etc/newsyslog.conf.d/*.conf and /usr/local/etc/newsyslog.conf.d/*.conf.
So use sed
My first approach was to
sed s/J// /etc/newsyslog.conf /etc/newsyslog.conf.d/*.conf
But this broke newsyslog and it refused to start with a message about
/ not being a valid flag.
Find where the error occured:
newsyslog -vn
/etc/newsyslog.conf.d/opensm.conf is the culprit. It has the path
to a pid-file following the J.
So if something follows the flag J, it needs to be replaced by -, not
deleted. So find a J between two tabs and replace it by a -
between two tabs. \t stands for tab.
sed 's/\tJ\t/\t-\t/'
Sed allows multiple commands, seperated by ;.
This works:
sed 's/\tJ\t/\t-\t/;s/J//' /etc/newsyslog.conf /etc/newsyslog.conf.d/*.conf
The replacement of J by - has to come first. If we delete first there is no J left to replace.
Be thorough
Tabs or whitespaces
There are some lines in the config files that end on a J with different numbers in spaces in front. I do not want to leave behind a file that has whitespace at the end of lines.
sed 's/[\t ]*J//'
All together
- On /etc/newsyslog.conf and all *.conf files in the newsyslog.conf.d directories.
- Work only on none comment lines.
- Remove trailing Js with preceeding whitespace.
- Replace single Js with -.
- Remove the remaining Js.
One-Liners
Here two long, ugly one-liners for future me to cut and paste.
For a host
sed -i '' '/^[^#]/s/[\t ]*J$//;/^[^#]/s/\tJ\t/\t-\t/;/^[^#]/s/J//' etc/newsyslog.conf etc/newsyslog.conf.d/*.conf /etc/usr/local/etc/newsyslog.conf.d/*.conf
Loop over jails
for JAIL in $(jls name); do sudo sed -i '' '/^[^#]/s/[\t ]*J$//;/^[^#]/s/\tJ\t/\t-\t/;/^[^#]/s/J//' /jail/$JAIL/etc/newsyslog.conf /jail/$JAIL/etc/newsyslog.conf.d/*.conf /jail/$JAIL/usr/local/etc/newsyslog.conf.d/*.conf ; done for JAIL in $(jls name); do sudo service -j $JAIL newsyslog restart ; done