Tiny Core Linux
Tiny Core Base => TCB Q&A Forum => Topic started by: Stefann on October 13, 2024, 07:27:31 AM
-
Hi,
I see /var/log/wtmp growing.
Is it at anytime getting rotated or flushed?
Until now I did reboot tcl from time to time and with that it got restarted.
Recently however I added /var/log to .filetool.lst for reason that I like to have my logs persistent over reboots.
My server works as a 24/7 homecontrol server. I have disabled logging from standard applications (like Apache) as I never look to them anyways. I have my own application now logged with rsyslog with which I successfully got the rotation working.
However… I now see /var/log/wtmp growing.
I can/could definitely create a rotation or flush for it myself with some cron job, but actually I feel this should be a default or standard setting.
In practice it will take few month before this becomes a problem. By default /var/log is not part of .filetool.lst so it’s very. Likely in default it gets flushed by a reboot every few month.
Still however… it seems to be a file that is growing without control.
Or… does it get flushed some day?
-
No, busybox doesn't look like it supports rotating wtmp and utmp. You can clear it manually, or use a package like logrotate.
-
Ah,
I will solve this one way or the other.
I think I will do by cron job because I already have that running while log rotate would be something I would need to add.
With that said however...
Isn't it a bit as a vulnerability that TC "out of the box without extra apps" has a growing log?
Would it be an idea to add something "basic" in next TC release?
Maybe a std cron configuration that has a line like:
1 1 1 * * echo ' ' > /var/log/wtmp
(where overwriting with something empty is better practice than removal of the file)
-
Well,
To keep things simple
I added below line to my cron file:
1 1 1 * * /bin/echo > /var/log/wtmp
This will flush wtmp monthly.
Tested it with all * (every minute) and works
-
Sorry to tell your echo will not empty out the file, you get one char line feed(new line).
You have to provide option -n to disable echo auto ending the line with line feed.
1 1 1 * * /bin/echo -n > /var/log/wtmp
-
Hi Stefann
For text files, here is how you can limit length (I'll address wtmp later):
#Limit log file to 100 lines.
echo "$(tail -n 100 xyzzy.log)" > xyzzy.log
Or conditionally:
#Limit log file to 100 lines if it's greater than 150 lines.
[ $(wc -l xyzzy.log | cut -d " " -f1) -gt 150 ] && echo "$(tail -n 100 xyzzy.log)" > xyzzy.log
Limiting wtmp needs to be handled differently since it's stored in a
binary format, not a text format. Examining the file in hex suggested
fixed length entries of 384 bytes, confirmed here:
https://askubuntu.com/questions/325491/how-to-properly-display-the-contents-of-the-utmp-wtmp-and-btmp-files
This means wtmp needs to be trimmed in multiples of 384 bytes.
Here is the current status of my wtmp file:
tc@E310:~$ last -f /var/log/wtmp | tail -n 1
wtmp begins Sun Jun 23 18:33:39 2024
tc@E310:~$ last -f /var/log/wtmp | head -n 1
tc pts/7 :0.0 Sun Oct 13 08:26 still logged in
tc@E310:~$ wc -c /var/log/wtmp
181248 /var/log/wtmp
tc@E310:~$ calc 181248/384
472
tc@E310:~$
Its first entry is dated June 23 and the last entry is dated Sun Oct 13 08:26.
The file contains 472 entries each 384 bytes long.
Lets say I want to shorten it to 275 entries:
tc@E310:~$ calc 275*384
105600
tc@E310:~$ tail -c 105600 /var/log/wtmp > NewWtmp
tc@E310:~$ sudo mv NewWtmp /var/log/wtmp
tc@E310:~$ last -f /var/log/wtmp | tail -n 1
wtmp begins Wed Aug 21 10:35:48 2024
tc@E310:~$ last -f /var/log/wtmp | head -n 1
tc pts/7 :0.0 Sun Oct 13 08:26 still logged in
tc@E310:~$ wc -c /var/log/wtmp
105600 /var/log/wtmp
tc@E310:~$
The size has been reduced to 105600 bytes (275*384).
Its first entry is now dated Aug 21 and the last entry is still dated Sun Oct 13 08:26.
The file now contains 275 entries each 384 bytes long.
You can launch something like this to periodically trim certain files in the background.
TrimLogs.sh:
#!/bin/sh
# List of text logs to trim formatted as /Path/Filename:MinSize:MaxSize
# MinSize and MaxSize refer to number of lines.
# Example:
TextLogs="/var/log/messages:300:350 /var/log/Xorg.0.log:526:700 AnotherPath/Filename:MinSize:MaxSize"
# Variables for trimming /var/log/wtmp.
# How many entries to keep.
Entries=275
#
EntrySize=384
FileSize=$(($Entries*$EntrySize))
# Run forever.
while true
do
# Process the list of text based logs.
for F in $TextLogs
do
LogFile="$(echo $F | cut -d ":" -f1)"
MinSize=$(echo $F | cut -d ":" -f2)
MaxSize=$(echo $F | cut -d ":" -f3)
[ $(wc -l $LogFile | cut -d " " -f1) -gt $MaxSize ] && echo "$(tail -n $MinSize $LogFile)" > $LogFile
done
# Process /var/log/wtmp.
tail -c $FileSize /var/log/wtmp > NewWtmp
sudo mv NewWtmp /var/log/wtmp
# Sleep for 8 hours, then trim again.
sleep 8h
done
Then launch it like this:
TrimLogs.sh &
-
Rich, thanks a lot!
3 questions/remarks.
1/
On your 1st in-line script you run tail on a file and write the result back in the original file without using a temp intermediate file. Isn’t that dangerous? Does that not have a risk of getting entangled and conflict?
It’s a very nice code-line. I can use that in my rsyslog.conf file instead of calling a rotate script (I like your approach because that reduces the amount of small interlinked cluttering files)
2/
Thanks for wtmp explaination, I’ll follow it, but that will be next weekend as a workweek is showing up now.
3/
Yes I understand the shell script and that will certainly work. In fact (apart from the 384byte handling of wtmp) I have things nicely setup now.
But….
Point was different…
Should we not include something like this in next TC release?
For reason that in fact one can consider this a memory leak: “vanilla tc is growing ram-usage if not restarted”.
As I said earlier, the risk is quite minor. You yourself had grown to 100k in 3.5month. My file had grown to 22k in about a month. Still it’s a bit ugly.
I’m afraid I’m not yet a skills level I could contribute on that.
And with that said, it’s only a community concern, I have my own stuff covered now.
-
Hi Stefann
... On your 1st in-line script you run tail on a file and write the result back in the original file without using a temp intermediate file. Isn’t that dangerous? ...
If you try to do it this way:
tail -n 100 xyzzy.log > xyzzy.log
It won't work
When you do it this way:
echo "$(tail -n 100 xyzzy.log)" > xyzzy.log
The tail command executes first. The results are then presented
to the echo command and then redirected into the original file.
(The actual mechanics may be more complex than that).
... Should we not include something like this in next TC release?
For reason that in fact one can consider this a memory leak: ...
This particular machine has 3 Gig of RAM. So a couple of hundred Kbytes
of RAM gets lost in the noise, especially compared to a pig like Firefox
which needs to be restarted every so often to force it to release some of
the RAM it's hogging.
-
Rich
Thanks for explanation on “no need of intermediate file”
I like the single line command
I will probably use that in my rsyslog.conf file for rotating logs.
I “just managed” to get that working this weekend by using an extra script file. The “1 line command” opens the door to do it in the rsyslog.conf without needing that extra script.
I like that.
It gets rid of an “undocumented script file” and brings all in the rsyslog.conf that is a clear documented need for rsyslog
I feel the wtmp rotation can be converted similarly in a 1 line command. I will be able to figure that out. Just following the logic of the other command.
patrikg
Also thanks for the “1 byte comment” and the -n suggestion.
You are very right, I indeed did see the file to be 1 byte big after flush.
This morning I checked and it’s now 2688 bytes, 7x384. So “somehow things corrected itself”.
At least this means there is no immediate need to change things.
Anyway
Weekend is over. Things will have to wait until next week.
I will definitely followup and report on how I got things finally solved.
-
The right place for this functionality would probably be busybox. We don't have default crontabs, cron isn't even running by default. If you know C, you could submit a patch to busybox.
-
The right place for this functionality would probably be busybox. We don't have default crontabs, cron isn't even running by default. If you know C, you could submit a patch to busybox.
I would be willing to send such a thing.
C is my favorite language.
But I currently do not work with GitHub (getting familiar with that is on the bucket list when job obligations get lower). So… I really not feel in the position to do.
As rich mentioned, “it’s not super urgent”.
Wtmp grows by about 1MB per year.
Frugal installs that do not have /var/log listed in .filetool.lst will likely get at least a reboot per year and than that 1MB will not really kill you also on low ram systems.
Still… it’s a memory leak on an out of the box system which is “not nice”.
One possibility is to erase wtmp with every system reboot. That way also systems that have /var/log in .filetool.lst will at least get a flush with a reboot.
Alternatively one could of course also take the position that “a user that deliberately puts /var/log in .filetool.lst should be smart enough to prevent overflow”. Which makes some sense.
At the end this is why I very much like tinycore.
As stated somewhere in the information “you get a fresh install at every reboot”. That is very very true!
Anything I “polute by accident” is cleaned with a reboot.
The only thing I have to worry about are the things I on purpose did put in .filetool.lst.
So yeah…. That’s how I got attracted to this situation in the first place.
-
Hi Stefann
... I feel the wtmp rotation can be converted similarly in a 1 line command. I will be able to figure that out. Just following the logic of the other command. ...
Maybe something like this:
Entries=100 ; tail -c $(($Entries*384)) /var/log/wtmp > NewWtmp && sudo mv NewWtmp /var/log/wtmp
Just change the value of Entries to how much history you wish to retain.
Just for the record, the number of entries that the "last" command reports
may not match FileSize/384. It seems when you close a terminal, that action
gets logged, but "last" does not report it.
Here I trim wtmp to 10 entries:
Entries=10 ; tail -c $(($Entries*384)) /var/log/wtmp > NewWtmp && sudo mv NewWtmp /var/log/wtmp
This is what last reports:
tc@E310:~$ last -F -f /var/log/wtmp
tc pts/8 :0.0 Mon Oct 14 10:45:55 2024 - Mon Oct 14 10:45:57 2024 (00:00)
tc pts/7 :0.0 Mon Oct 14 09:22:07 2024 still logged in
tc pts/7 :0.0 Mon Oct 14 08:37:22 2024 - Mon Oct 14 09:22:07 2024 (00:44)
tc pts/7 :0.0 Sun Oct 13 08:26:48 2024 - Sun Oct 13 12:26:17 2024 (03:59)
tc pts/5 :0.0 Sun Oct 13 08:17:32 2024 still logged in
tc pts/5 :0.0 Sat Oct 12 09:32:51 2024 - Sat Oct 12 09:46:46 2024 (00:13)
tc pts/5 :0.0 Wed Oct 9 21:51:27 2024 - Sat Oct 12 09:32:51 2024 (2+11:41)
wtmp begins Wed Oct 9 21:51:27 2024
tc@E310:~$
It shows 7 entries.
Using the perl script found at the link in reply #5 I get this:
tc@E310:~$ ./ReadWtmp.sh < /var/log/wtmp | sort -r -k 3
Mon Oct 14 10:45:57 2024 Term tc pts/8 :0.0
Mon Oct 14 10:45:55 2024 Normal tc pts/8 :0.0
Mon Oct 14 09:22:07 2024 Normal tc pts/7 :0.0
Mon Oct 14 08:37:22 2024 Normal tc pts/7 :0.0
Sun Oct 13 12:26:17 2024 Term tc pts/7 :0.0
Sun Oct 13 08:26:48 2024 Normal tc pts/7 :0.0
Sun Oct 13 08:17:32 2024 Normal tc pts/5 :0.0
Sat Oct 12 09:46:46 2024 Term tc pts/5 :0.0
Sat Oct 12 09:32:51 2024 Normal tc pts/5 :0.0
Wed Oct 9 21:51:27 2024 Normal tc pts/5 :0.0
tc@E310:~$
It shows 10 entries.
Note the two pts/8 entries. That was me opening then closing a terminal.
The last command only reports me opening the terminal at 10:45:55.
Just wanted to point that out in case anyone else notices that discrepancy.
-
Hi rich,
Thanks,
As said, it will need to wait until next weekend before I will try.
In the mean time I keep reading (on iPad with a whiskey on the couch :) ).
Based on this info: https://www.unix.com/aix/226435-wtmp-empty-everyday.html
They claim “better to overwrite than to remove” to avoid inode number gets changed which makes me feel your
sudo mv NewWtmp /var/log/wtmp
Is probably less wanted.
I was actually thinking to use your earlier “normal log” solution, modified to byte count:
echo "$(tail -c 19200 /var/log/wtmp)” > /var/log/wtmp
Which should give me 50 entires as 19200=50x384
I’m not trying now though. The moment I start doing so few hours pass by very quick and that does not fit the weekdays.
-
Hi Stefann
... They claim “better to overwrite than to remove” to avoid inode number gets changed which makes me feel your
sudo mv NewWtmp /var/log/wtmp
Is probably less wanted. ...
I tried that initially but it won't work. The echo command strips out
all the zero chars (0x00) from the stream.
Try this:
Entries=100 ; tail -c $(($Entries*384)) /var/log/wtmp > NewWtmp && sudo cp NewWtmp /var/log/wtmp; rm -rf NewWtmp
That should leave the inode number unchanged.
See here:
https://stackoverflow.com/questions/62355054/copy-and-moves-command-effect-on-inode
-
Hi rich,
Thanks!
Will do,
As said.. need to wait for weekend
-
hi,
Well... it works :)
Big thanks Rich
I now have below command in my cron file:
1 1 1 * * Entries=100 ; tail -c $(($Entries*384)) /var/log/wtmp > /var/log/NewWtmp && sudo cp /var/log/NewWtmp /var/log/wtmp; rm -rf /var/log/NewWtmp
In addition to your advice I added the full path for NewWtmp to avoid that it got written at some random place.
Tested with * * * * * setting (every minute) and works like a charm. Thanks.
With 100 entries it grows to about 35k which is fine.
I also tried to setup syslog.conf with your other "1 command" proposal:
$outchannel main_log, /var/log/mainlog.txt, 50000, /bin/echo "$(/usr/bin/tail -n 50 /var/log/mainlog.txt)" > /var/log/mainlog.txt
local1.=debug :omfile:$main_log;MyFormat
But that does not work.
I tried to simplify it all the way to
$outchannel main_log, /var/log/mainlog.txt, 50000, /bin/cp /var/log/mainlog.txt /var/log/testlog.txt
But even that does not work.
it looks like syslog does only accept 1 argument to the copy command.
I stopped debugging this.
I currently have rsylog perfectly working like this:
$outchannel main_log, /var/log/mainlog.txt, 100000, /var/log/rotate mainlog.txt
local1.=debug :omfile:$main_log;MyFormat
with /var/log/rotate:
tail -n 500 /var/log/${1} > /var/log/${1}.tmp
cat /var/log/${1}.tmp > /var/log/${1}
rm -f /var/log/${1}.tmp
I do not really like that I now have a script in the /var/log folder that is user-specific because that is something I could "loose"
The beauty of your single line solution is that that would be entirely in the syslog.conf file with no "non standard file needed".
I will however just document the rotate script on some # commented lines in the syslog.conf file.
That way, if I revisit this in few years, I still understand how it works.
-
Hi Stefann
Had you considered using the included busybox syslog:
tc@E310:~$ syslogd --help
BusyBox v1.29.3 (2018-12-19 15:29:37 UTC) multi-call binary.
Usage: syslogd [OPTIONS]
System logging utility
(this version of syslogd ignores /etc/syslog.conf)
-n Run in foreground
-R HOST[:PORT] Log to HOST:PORT (default PORT:514)
-L Log locally and via network (default is network only if -R)
-C[size_kb] Log to shared mem buffer (use logread to read it)
-O FILE Log to FILE (default: /var/log/messages, stdout if -)
-s SIZE Max size (KB) before rotation (default 200KB, 0=off)
-b N N rotated logs to keep (default 1, max 99, 0=purge)
-l N Log only messages more urgent than prio N (1-8)
-S Smaller output
-D Drop duplicates
tc@E310:~$
It appears to support log size limits, log rotation, and remote logging.
-
That's how I started.
unfortunately it does not support syslog.conf and for that reason I cannot set multiple logfiles.
I use 4 now:
- 3 "slow" logfiles with few messages per hour that keep track of how my application is doing, I need multipel days history on that
- 1 "fast" logfile with multiple messages per second for debugging, I only need few minutes history on that
(this version of syslogd ignores /etc/syslog.conf)
My full journey on that is here:
https://forum.tinycorelinux.net/index.php/topic,27306.0.html