logrotate with node.js and systemd
Since logrotate and systemd are both default to debian based OS. I would like to share the way I achieve logrotate for logging in node.js

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!
Profile picture
斟酌 鵬兄
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)
Comments
No comments here.
Do you even comment?
website: 
Not a valid website
Invalid email format
Please enter your email
*Name: 
Please enter a name
Submit
抱歉,Google Recaptcha 服務被牆掉了,所以不能回覆了