Rotating a log was simple. First create a config file in /etc/logrotate.d/<ServiceName> ( I'll use my blog as an example ):
/var/www/blog2gen/logs/*.log {
su www-data users
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 640 www-data users
sharedscripts
postrotate
systemctl reload botanical@blog2gen
endscript
}
Mostly copied from apache2's logrotate. But with su www-data users and create 640 www-data users which means the log files will be created with:
rw-rw---- www-data users *.log.X
The crucial part is inside the postrotate block. Which tells logrotate to do systemctl reload botanical@blog2gen. The reload action is defined manually.
But how are we going to implement reload in systemd for node.js? First, let's take a look in botanical@.service file:
[Unit]
Description=Botanical %i servlet
[Service]
ExecStart=/opt/autorun/node-js.service %i
ExecReload=/bin/kill -HUP $MAINPID
Restart=no
User=www-data
Group=www-data
Environment=PATH=/usr/bin:/usr/local/bin
# Environment=NODE_ENV=production
WorkingDirectory=/var/www/%i
[Install]
WantedBy=multi-user.target
You can see the only one option that handles the reload command is "ExecReload". Which uses kill to send an HUP signal to the node.js process.
That means we need to make node.js to listen to this HUP signal, here is the log writer in my blog:
var fs = require( "fs" );
var path = "logs/access.log";
var w = {};
var fwrites;
var ReWrite = () => {
console.log( "Reloading access log" );
if( fwrites ) fwrites.close();
fwrites = fs.createWriteStream( path, { flag: "w+" } )
w.write = fwrites.write.bind( fwrites );
};
process.on( "SIGHUP", ReWrite );
ReWrite();
module.exports = { handler: w };
Very simple isn't it? But this is not THE logger, it is just a writer object for the Logger. No need to worry about the console.log here. The outputs are intended to be caught by systemd.
Anyway, the SIGHUP is also useful for invalidating require.cache. Which I didn't implement regarding to the scale of my blog. The startup speed of my blog is fast enough that doing systemctl restart is just a 2 seconds process. Furthermore, the sessions are also stored in redis, i.e. nothing could go wrong when doing restart.
Just do the god damn restart! 斟酌 鵬兄
Fri Oct 14 2016 03:14:24 GMT+0000 (Coordinated Universal Time)
Last modified: Fri Oct 14 2016 10:00:27 GMT+0000 (Coordinated Universal Time)