How to setup MongoDB log rotation on Windows? - mongodb

I have a conf file for mongod where I am trying to set log rotation, the log file size, and the number of old instances to be kept.
I have added logRotate: rename to the conf file as follows:
systemLog:
timeStampFormat: ctime
destination: file
logAppend: true
logRotate: rename
path: C:\Program Files\ApplicationName\logs\db.log
But I cannot find any documentation or examples that show how to specify the max size of the log file before it rotates and how many old instances to keep.
Also I don't know how to test this.
Apperently you need setup some kind of external process to send SIGUSR1 signal from OS to trigger rotation.
Any ideas? Has anyone actually done this successfully?

There is nothing available in MongoDB itself. Either you write all logs into one file:
systemLog
logAppend: true
or you create a new log file every time you start MonogDB server:
systemLog
logAppend: true
logRotate: rename
In either case you have to delete/compress old log files manually with a 3rd party tool or by script.
In Linux you can trigger a log rotate by kill -USR1 but I am not aware this would be available in Windows. You need to initiate log rotate from Mongo shell:
use admin
db.runCommand({ logRotate: 1 })
or
db.getSiblingDB('admin').runCommand({ logRotate: 1 })
db.adminCommand({ logRotate: 1 })
You can run it from command line with
mongo --eval "db.adminCommand({ logRotate: 1 })"
Setup such task with Windows Task Scheduler. You may have a look at LogRotateWin which is an implementation of logrotate utility for Windows Platform. I never tried it, but it seems to work as supposed to be. For sample logrotate configuration see How can I disable the logging of MongoDB?
Note, for Linux in order not to lose any logs, you first have to rename the logfile and afterwards initiate the log rotate command. I don't know whether Windows behaves in the same way.

With the help of Wernfried-Domscheit answer, a lot of research, weeks of trial and error and frustration I figured out a working solution on windows.
Prerequisites
You have a MongoDB-Service running with a configuration file mongod.cfg
LogRotateWin is installed. This is a third party package to rotate the logfiles, based on the unix implementation. It provides many customizable functionalities like compression, when rotating is applied, old file deletion and more. You can find a full option list here LogRotateWin Configuration.
Basic knowledge of Windows Taskscheduler.
Very basic knowledge of bat files.
1. Adjust the configuration file of the MongoDB-Service
Stop the service
Open the mongod.cfg and find the code lines where the systemLog is configured:
# where to write logging data.
systemLog:
destination: file
logAppend: true
path: E:\MongoDB\Server\4.4\log\mongod.log
logRotate: reopen
Be sure, that you overwrite the path to your mongod.log. Be also sure, that logAppend: true and logRotate: reopen are set.
Delete the current mongod.log file
Restart the service
2. Configure the logrotate configuration
This is my configuration. You can customize that to your own needs. But dont use copy, copytruncate and create and dont remove the postrotate commands!
E:\MongoDB\Server\4.4\log\mongod.log {
nocompress
daily
size 100m
missingok
rotate 50
postrotate
E:\logrotate\notify_mongodb_service.bat
endscript
}
This configuration rotates the logs uncompressed every day or if the size exceeded 100 megabyte. Maximum of 50 logs are stored, older files will be deleted. The postrotate script will be executed when the rotation succeeded.
3. Create the notify_mongodb_service.bat file
This file sends a command to the MongoDB-Service, that a new file will be used. If you enabled authorization you can add -u username -p password aswell.
E:\MongoDB\Server\4.4\bin\mongo.exe --eval "db.adminCommand({ logRotate: 1 })"
Change the path to mongo.exe to the location on your system.
Save the file and be sure that the path in the logrotate configuration is the same! (the line between postrotate and endscript
The command is stored in an extra file, because the LogRotateWin interprets the Brackets ({}) of the mongo command and throws an Exception.
4. Check that all is working
Open the folder of the logs. You should see a single file mongod.log.
Open a terminal and check that logrotation is working ( -f forces the logrotation even if no trigger was triggered):
logrotate logrotate.conf -f
A new log file should occur. (for me it is mongod.log.1)
The mongod.log should be empty.
Trigger something that will be logged. For example connect with monogdbCompass to your MongoDB.
Check mongod.log. The connection should be logged there.
5. Create a Taskscheduler Job to run logrotation periodically
I wont talk about taskscheduler creation but here is an example of my configuration. You can import that file and modify it to your needs.
Also change the path of the logrotate.exe to your location of your system.
This job runs every hour to check if one or multiple triggers of logrotate triggered:
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Date>2021-12-02T17:57:55.9541897</Date>
<Author>Grayknife</Author>
<Description>Execute Logrotate Hourly</Description>
<URI>\docker\LogRotate</URI>
</RegistrationInfo>
<Triggers>
<CalendarTrigger>
<Repetition>
<Interval>PT1H</Interval>
<StopAtDurationEnd>false</StopAtDurationEnd>
</Repetition>
<StartBoundary>2021-12-02T18:00:00</StartBoundary>
<ExecutionTimeLimit>PT30M</ExecutionTimeLimit>
<Enabled>true</Enabled>
<ScheduleByDay>
<DaysInterval>1</DaysInterval>
</ScheduleByDay>
</CalendarTrigger>
</Triggers>
<Principals>
<Principal id="Author">
<UserId>1234</UserId>
<LogonType>Password</LogonType>
<RunLevel>LeastPrivilege</RunLevel>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>false</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession>
<UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>PT0S</ExecutionTimeLimit>
<Priority>7</Priority>
</Settings>
<Actions Context="Author">
<Exec>
<Command>E:\logrotate\logrotate.exe</Command>
<Arguments>logrotate.conf</Arguments>
<WorkingDirectory>E:\logrotate</WorkingDirectory>
</Exec>
</Actions>
</Task>
I hope i could help someone with that guide.
Edit 2022-05-01
I faced the issue that logrotate throws exception when there are more than 9 files:
E:\logrotate>E:\logrotate\logrotate.exe logrotate.conf -f
logrotate: Force option set to true
logrotate: Exception: Cannot create a file when that file already exists.
logrotate: StackTrace: at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.__Error.WinIOError()
at System.IO.File.InternalMove(String sourceFileName, String destFileName, Boolean checkHost)
at logrotate.Program.AgeOutRotatedFiles(logrotateconf lrc, FileInfo fi, String rotate_path)
at logrotate.Program.RotateFile(logrotateconf lrc, FileInfo fi)
at logrotate.Program.Main(String[] args)
E:\logrotate>E:\logrotate\logrotate.exe logrotate.conf -f
logrotate: Force option set to true
logrotate: Exception: Access to the path 'E:\MongoDB\Server\4.4\log\mongod.log.10' is denied.
logrotate: StackTrace: at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.File.InternalDelete(String path, Boolean checkHost)
at System.IO.File.Delete(String path)
at logrotate.Program.DeleteRotateFile(String m_filepath, logrotateconf lrc)
at logrotate.Program.AgeOutRotatedFiles(logrotateconf lrc, FileInfo fi, String rotate_path)
at logrotate.Program.RotateFile(logrotateconf lrc, FileInfo fi)
at logrotate.Program.Main(String[] args)
E:\logrotate>
Quickfix for now is to set a maximum of 9 files.

Create a python file logrotate.py with content:
import os
# path to your mongod.log file
path = 'D:/MongoDB/Server/5.0/log/'
# you can insert a condition here that checks the size of mongod.log first
# ...
# send logrotate command through terminal
# if you don't have mongosh(ell) installed, replace by mongo / mongod
os.system('cmd /c "mongosh --eval "db.adminCommand({ logRotate: 1 })"')
# delete rotated log file
for file in os.listdir(path):
if file.startswith('mongod.log.'):
os.remove(path+file)
quit()
Create a batch file logrotate.bat with content:
python logrotate.py
Create a task in Windows task scheduler that runs this program every X hours.

Related

Use local socket with mpd

I'm trying to switch from using the local network to a UNIX socket with mpd.To do so, i have my config file:
# Recommended location for database
db_file "~/.config/mpd/database"
# If running mpd using systemd, delete this line to log directly to systemd.
#log_file "syslog"
# The music directory is by default the XDG directory, uncomment to amend and choose a different directory
music_directory "~/Music"
# Uncomment to refresh the database whenever files in the music_directory are changed
auto_update "yes"
auto_update_depth "5"
# Uncomment to enable the functionalities
playlist_directory "~/.config/mpd/playlists"
pid_file "~/.config/mpd/pid"
state_file "~/.config/mpd/state"
#sticker_file "~/.config/mpd/sticker.sql"
bind_to_address "~/.config/mpd/socket"
restore_paused "yes"
audio_output {
type "pipewire"
name "PipeWire Sound Server"
}
I created a socket file in the folder ~/.config/mpd/socket
I also export MPD_HOST=~/.config/mpd/socket in order to be the default host. Nevertheless if i run the command:
mpc play , i have the error MPD error: Failed to resolve host name
But if i run MPD_HOST=~/.config/mpd/socket mpc play it work. I don't understand what i'm missing?

Rundeck show log flag as error but it's not

I got a question about log output on rundeck.
I've cron a multiple oracle EXPDP and all the log are flagged as ERROR but it's not.
I've try to put a log handler but i don't understand how to dot it.
My job:
export ORACLE_PDB_SID=XXXXXXXX
expdp "/ as sysdba" schemas=XXX#option.CODE#SCH001 directory=DUMPSTORAGE_PROD dumpfile=#option.CLIENT##option.CODE#SCH001"date +"%d-%m-%Y"".dump logfile=#option.CLIENT#expdp#option.CODE#SCH001.log job_name=#option.CLIENT#
gzip -9 /mnt/DUMPSTORAGE/#option.CLIENT##option.CODE#SCH001"date +"%d-%m-%Y"".dump &&\
SCREENSHOT

how to specify multiple log files pattern in fail2ban jail?

I have log files on my server as follows
vpn_20191007.log
vpn_20191008.log
vpn_20191009.log
vpn_20191010.log
vpn_20191011.log
vpn_20191012.log
vpn_20191013.log
vpn_20191014.log
vpn_20191015.log
vpn_20191016.log
Is it possible to add log files pattern in fail2ban jail config?
[application]
enabled = false
filter = example
action = iptables
logpath = /var/log/vpn_%D.log
maxretry = 1
Well, conditionally it is possible...
Although wildcards are basically allowed at the moment, so :
logpath = /var/log/vpn_*.log
will do the job, but it is a bit ugly in your case:
fail2ban cumulate the list of files only by start of service, so the list remains obtained in fail2ban (unless it gets reloaded) - this means you should notify fail2ban that the log file name got changed (see https://github.com/fail2ban/fail2ban/issues/1379, the work is in progress).
since only one file will get new messages, the monitoring of other files is unneeded, especially if polling backend is used.
So better create some logrotate rules for that:
in order to rename/compress all previous log-files (to avoid match for obsolete files);
either create hard- or sym-link for last/active file with a fixed name (so fail2ban is always able to find it with the same name, and you'd not need wildcard at all);
or to notify fail2ban to reload the jail if logfile-name got changed(fail2ban-client reload vpn).
Here is an example for logrotate amendment:
postrotate
nfn="/var/log/vpn_$(date +%Y%m%d).log"
touch "$nfn"
ln -fs "$nfn" /var/log/vpn.log
You can add wilcard :
logpath = /var/log/vpn_*.log
and/or you can use multiple lines :
logpath = /var/log/vpn_20191007.log
/var/log/vpn_20191008.log
/var/log/vpn_20191009.log
/var/log/vpn_20191010.log
/var/log/vpn_20191011.log
/var/log/vpn_20191012.log
/var/log/vpn_20191013.log
/var/log/vpn_20191014.log
/var/log/vpn_20191015.log
/var/log/vpn_20191016.log
(You can combine the two)

How can I turn on the Kodi webserver from the command line?

My Kodi is running as root (for better or for worse). This means the user folder is:
/root/.kodi/userdata/guisettings.xml
A quick search for web-related junk:
cat guisettings.xml | grep web
yields
<webserver default="true">false</webserver>
<webserverpassword default="true"></webserverpassword>
<webserverport default="true">8080</webserverport>
<webserverusername default="true">kodi</webserverusername>
<webskin default="true">webinterface.default</webskin>
Looks good to me. I just have to turn on the webserver.
Steps Taken
systemctl stop kodi
perl -i -pe 's/<webserver default="true">false<\/webserver>/<webserver default="true">true<\/webserver>/' /root/.kodi/userdata/guisettings.xml # (I actually used vim)
systemctl start kodi
Guess what happens, the guisettings.xml gets overwritten each time I start Kodi. I also tried adding the following file: /root/.kodi/userdata/advancedsettings.xml with the following contents:
<advancedsettings>
<loglevel hide="attribute">3</loglevel>
<webserver default="true">true</webserver>
<webserverpassword default="true"></webserverpassword>
<webserverport default="true">8080</webserverport>
<webserverusername default="true">kodi</webserverusername>
<webskin default="true">webinterface.default</webskin>
</advancedsettings>
This also does not work.
Are you by any chance trying to enable the web server to allow using Kodi remote?
I encountered the same issue too, "guisettings.xml gets overwritten".
According to kodi.wiki, you need to configure 2 more XML elements.
To be complete, having the following in advancedsettings.xml should help:
<advancedsettings>
<services>
<esallinterfaces>true</esallinterfaces>
<webserver>true</webserver>
<zeroconf>true</zeroconf>
</services>
</advancedsettings>

logrotate working but ignoring size

CentOS v.7
Logrotate v.3.8.6
I set logrotate to rotate when file reaches 5M but it ignores it, if I add daily it will rotate daily regardless of size, i tried with size, minsize and maxsize all the same the only difference is with "size" it doesnt even refer to it in the output, here is my config and output of logrotate -vdf /etc/logrotate.d/maillog
(the actual log file size when running the following tests was 45K)
(the conf file is the same for all tests only the size parameter changed)
/var/log/maillog {
size 5M
rotate 50
create 644 root root
dateext
dateformat -%Y-%m-%d_%H_%s
notifempty
postrotate systemctl restart rsyslog
systemctl restart postfix
endscript }
SIZE:
logrotate -vdf /etc/logrotate.d/maillog
reading config file /etc/logrotate.d/maillog
Allocating hash table for state file, size 15360 B
Handling 1 logs
rotating pattern: /var/log/maillog forced from command line (50 rotations)
empty log files are not rotated, old logs are removed
considering log /var/log/maillog
log needs rotating
rotating log /var/log/maillog, log->rotateCount is 50
Converted ' -%Y-%m-%d_%H_%s' -> '-%Y-%m-%d_%H_%s'
dateext suffix '-2017-12-19_13_1513689486'
glob pattern '-[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]_[0-9][0-9]_[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
fscreate context set to unconfined_u:object_r:var_log_t:s0
renaming /var/log/maillog to /var/log/maillog-2017-12-19_13_1513689486
creating new /var/log/maillog mode = 0644 uid = 0 gid = 0
running postrotate script
running script with arg /var/log/maillog: "
systemctl restart rsyslog
systemctl restart postfix
"
No reason for "log needs rotating" is given.
MINSIZE:
logrotate -vdf /etc/logrotate.d/maillog
reading config file /etc/logrotate.d/maillog
Allocating hash table for state file, size 15360 B
Handling 1 logs
rotating pattern: /var/log/maillog forced from command line (50 rotations)
empty log files are not rotated, only log files >= 5242880 bytes are rotated, old logs are removed
considering log /var/log/maillog
log needs rotating
rotating log /var/log/maillog, log->rotateCount is 50
Converted ' -%Y-%m-%d_%H_%s' -> '-%Y-%m-%d_%H_%s'
dateext suffix '-2017-12-19_13_1513689869'
glob pattern '-[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]_[0-9][0-9]_[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
fscreate context set to unconfined_u:object_r:var_log_t:s0
renaming /var/log/maillog to /var/log/maillog-2017-12-19_13_1513689869
creating new /var/log/maillog mode = 0644 uid = 0 gid = 0
running postrotate script
running script with arg /var/log/maillog: "
systemctl restart rsyslog
systemctl restart postfix
"
Here it shows, "only log files >= are rotated" but no reason for "log needs rotating" is given.
MAXSIZE:
reading config file /etc/logrotate.d/maillog
Allocating hash table for state file, size 15360 B
Handling 1 logs
rotating pattern: /var/log/maillog forced from command line (50 rotations)
empty log files are not rotated, log files >= 5242880 are rotated earlier, old logs are removed
considering log /var/log/maillog
log needs rotating
rotating log /var/log/maillog, log->rotateCount is 50
Converted ' -%Y-%m-%d_%H_%s' -> '-%Y-%m-%d_%H_%s'
dateext suffix '-2017-12-19_13_1513690859'
glob pattern '-[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]_[0-9][0-9]_[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
fscreate context set to unconfined_u:object_r:var_log_t:s0
renaming /var/log/maillog to /var/log/maillog-2017-12-19_13_1513690859
creating new /var/log/maillog mode = 0644 uid = 0 gid = 0
running postrotate script
running script with arg /var/log/maillog: "
systemctl restart rsyslog
systemctl restart postfix
"
Here it shows, "log files => are rotated" but no reason for "log needs rotating" is given.
Why is it ignoring file size when rotating?
You're running logrotate with -f, in that scenario it's always going to force a rotation with a complete lack of regard for your other options:
https://manpages.debian.org/jessie/logrotate/logrotate.8.en.html
-f, --force
Tells logrotate to force the rotation, even if it doesn't think this is necessary.
It gives you no reason because you in fact were the reason-giver.