In Node.js is quite easy to read the nginx access log.
Since Node is executed under a specific user account on a typical server, it can't access the nginx access log because it's located in the /var/log/nginx
directory.
We need to copy the access log in the app directory and change its ownership accordingly.
cat /var/log/nginx/access.log > /home/user/app/logs/access.log && chown user:user /home/user/app/logs/access.log
Now we can create a cron job to automate the above task.
export VISUAL=nano; crontab -e
Typically this task can be done once in a day, as shown below.
5 4 * * * cat /var/log/nginx/access.log > /home/user/app/logs/access.log && chown user:user /home/user/app/logs/access.log
Then we can restart the cron service.
service cron restart
You can use this online service for your cron jobs. I recommend to run the above task not too frequently in order to minimize the impact on the server.
In Node we need to read the log file, split it into an array of lines and return the resulting array in reversed order since nginx stores its records in ascending order.
'use strict';
const fs = require('fs');
const readLog = () => {
const logFile = './logs/access.log';
return new Promise((resolve, reject) => {
fs.readFile(logFile, 'utf8', (err, contents) => {
if(err) { reject(err); }
resolve(contents.toString().split(/\n/).reverse());
});
});
};
module.exports = readLog;
Now we can use the above function in our application:
'use strict';
const readLog = require('./readlog');
const app = require('express')();
app.set('view engine', 'ejs');
app.get('/log', async (req, res) => {
try {
const entries = await readLog();
res.render('log', {entries: entries});
} catch(err) { res.sendStatus(500); }
});
app.listen(8080);
Our EJS view may look like the following one:
<% if(entries.length > 0) { %>
<ol>
<% entries.forEach(function(entry) { %>
<li><%= entry %></li>
<% }); %>
</ol>
<% } else { %>
<p>No results to show.</p>
<% } %>
As you can see, once you get all the relevant data everything is really easy to accomplish.