From 8af356f09bc24ef84a076b2016dad2d8b599656e Mon Sep 17 00:00:00 2001 From: cgeek <cem.moreau@gmail.com> Date: Thu, 6 Apr 2017 13:22:34 +0200 Subject: [PATCH] [fix] #865 #938 `logs` is now a module command and has a `--loglevel` option --- app/lib/constants.js | 3 ++ app/lib/logger/index.js | 37 ++++++++++++------------ app/modules/daemon.js | 63 +++++++++++++++++++++++++++++++++++++++-- bin/duniter | 2 +- index.js | 6 +++- package.json | 1 + 6 files changed, 89 insertions(+), 23 deletions(-) diff --git a/app/lib/constants.js b/app/lib/constants.js index 58a53c465..4418b4da7 100644 --- a/app/lib/constants.js +++ b/app/lib/constants.js @@ -327,6 +327,9 @@ module.exports = { ACCOUNT_MINIMUM_CURRENT_BASED_AMOUNT: 100, + // With `logs` command, the number of tail lines to show + NB_INITIAL_LINES_TO_SHOW: 100, + // INDEXES M_INDEX: 'MINDEX', I_INDEX: 'IINDEX', diff --git a/app/lib/logger/index.js b/app/lib/logger/index.js index 81f9e37da..320f1117f 100644 --- a/app/lib/logger/index.js +++ b/app/lib/logger/index.js @@ -63,25 +63,26 @@ logger.addCallbackLogs = (callbackForLog) => { // Singletons let loggerHomeAttached = false; -logger.addHomeLogs = (home) => { - if (!loggerHomeAttached) { - loggerHomeAttached = true; - logger.add(winston.transports.File, { - level: 'info', - levels: customLevels.levels, - handleExceptions: false, - colorize: true, - tailable: true, - maxsize: 50 * 1024 * 1024, // 50 MB - maxFiles: 3, - //zippedArchive: true, - json: false, - filename: path.join(home, 'duniter.log'), - timestamp: function () { - return moment().format(); - } - }); +logger.addHomeLogs = (home, level) => { + if (loggerHomeAttached) { + logger.remove(winston.transports.File); } + loggerHomeAttached = true; + logger.add(winston.transports.File, { + level: level || 'info', + levels: customLevels.levels, + handleExceptions: false, + colorize: true, + tailable: true, + maxsize: 50 * 1024 * 1024, // 50 MB + maxFiles: 3, + //zippedArchive: true, + json: false, + filename: path.join(home, 'duniter.log'), + timestamp: function () { + return moment().format(); + } + }); }; let muted = false; diff --git a/app/modules/daemon.js b/app/modules/daemon.js index d70ede03f..5b059b443 100644 --- a/app/modules/daemon.js +++ b/app/modules/daemon.js @@ -1,12 +1,27 @@ "use strict"; -const co = require('co'); +const co = require('co'); +const qfs = require('q-io/fs'); +const directory = require('../lib/system/directory'); +const constants = require('../lib/constants'); +const path = require('path'); +const Tail = require("tail").Tail module.exports = { duniter: { - service: { - process: (server) => ServerService(server) + cliOptions: [ + { value: '--loglevel <level>', desc: 'Logs level, either [error,warning,info,debug,trace]. default to `info`.' } + ], + + config: { + + /***** + * Tries to load a specific parameter `conf.loglevel` + */ + onLoading: (conf, program) => co(function*(){ + conf.loglevel = program.loglevel || conf.loglevel || 'trace' + }) }, cli: [{ @@ -54,6 +69,15 @@ module.exports = { } }) }, { + + name: 'logs', + desc: 'Follow duniter logs.', + logs: false, + onConfiguredExecute: (server, conf, program, params) => co(function*() { + printTailAndWatchFile(directory.INSTANCE_HOMELOG_FILE, constants.NB_INITIAL_LINES_TO_SHOW) + // Never ending command + return new Promise(res => null) + }) }, { name: 'direct_start', @@ -93,4 +117,37 @@ function stopDaemon(daemon) { resolve() })) } + +function printTailAndWatchFile(file, tailSize) { + return co(function*() { + if (yield qfs.exists(file)) { + const content = yield qfs.read(file) + const lines = content.split('\n') + const from = Math.max(0, lines.length - tailSize) + const lastLines = lines.slice(from).join('\n') + console.log(lastLines) + } + watchFile(file) + }) +} + +function watchFile(file) { + const tail = new Tail(file); + + // Specific errors handling + process.on('uncaughtException', (err) => { + if (err.code === "ENOENT") { + console.error('EXCEPTION: ', err.message); + setTimeout(() => watchFile(file), 1000) // Wait a second + } + }); + + // On new line + tail.on("line", function(data) { + console.log(data); + }); + + tail.on("error", function(error) { + console.error('ERROR: ', error); + }); } diff --git a/bin/duniter b/bin/duniter index 153524c40..639437438 100755 --- a/bin/duniter +++ b/bin/duniter @@ -10,7 +10,7 @@ return co(function*() { // Specific errors handling process.on('uncaughtException', (err) => { // Dunno why this specific exception is not caught - if (err.code !== "EADDRNOTAVAIL" && err.code !== "EINVAL") { + if (err.code !== "EADDRNOTAVAIL" && err.code !== "EINVAL" && err.code !== "ENOENT") { duniter.statics.logger.error(err); process.exit(2); } diff --git a/index.js b/index.js index e82aa0f80..5837f1bc9 100644 --- a/index.js +++ b/index.js @@ -164,7 +164,7 @@ function Stack(dependencies) { } // Add log files for this instance - logger.addHomeLogs(home); + logger.addHomeLogs(home, program.loglevel); const server = new Server(home, program.memory === true, commandLineConf(program)); @@ -208,6 +208,10 @@ function Stack(dependencies) { }); const conf = yield server.loadConf(); + + // Eventually change the log level + logger.addHomeLogs(home, conf.loglevel); + // Auto-configuration default yield configure(program, server, server.conf || {}); // Autosave conf diff --git a/package.json b/package.json index 1e98372bf..91278d03b 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "sha1": "1.1.1", "sqlite3": "3.1.4", "superagent": "3.5.2", + "tail": "^1.2.1", "underscore": "1.8.3", "unzip": "0.1.11", "unzip2": "0.2.5", -- GitLab