mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-21 18:13:29 +00:00
Improve logger module
This commit is contained in:
+43
-46
@@ -1,6 +1,7 @@
|
||||
var Q = require("q");
|
||||
var _ = require("lodash");
|
||||
var path = require("path");
|
||||
var util = require("util");
|
||||
var lunr = require('lunr');
|
||||
var parsers = require("gitbook-parsers");
|
||||
var color = require('bash-color');
|
||||
@@ -10,6 +11,7 @@ var parseNavigation = require("./utils/navigation");
|
||||
var parseProgress = require("./utils/progress");
|
||||
var pageUtil = require("./utils/page");
|
||||
var links = require("./utils/links");
|
||||
var logger = require("./utils/logger");
|
||||
|
||||
var Configuration = require("./configuration");
|
||||
var TemplateEngine = require("./template");
|
||||
@@ -23,11 +25,16 @@ var Book = function(root, context, parent) {
|
||||
config: {},
|
||||
|
||||
// Log function
|
||||
log: console.log.bind(console),
|
||||
log: function(msg) {
|
||||
process.stdout.write(msg);
|
||||
},
|
||||
|
||||
// Log level
|
||||
logLevel: Book.LOG_LEVELS.INFO
|
||||
})
|
||||
});
|
||||
|
||||
// Log
|
||||
this.log = logger(this.context.log, this.context.logLevel);
|
||||
|
||||
// Root folder of the book
|
||||
this.root = path.resolve(root);
|
||||
@@ -101,7 +108,7 @@ Book.prototype.parse = function() {
|
||||
var multilingual = false;
|
||||
|
||||
|
||||
that.logDebug("start parsing configuration");
|
||||
that.log.debug.ln("start parsing configuration");
|
||||
return this.config.load()
|
||||
|
||||
.then(function() {
|
||||
@@ -112,11 +119,11 @@ Book.prototype.parse = function() {
|
||||
return that.parseLangs()
|
||||
.then(function() {
|
||||
multilingual = that.langs.length > 0;
|
||||
if (multilingual) that.logInfo("Parsing multilingual book, with", that.langs.length, "lanuages");
|
||||
if (multilingual) that.log.info.ln("Parsing multilingual book, with", that.langs.length, "lanuages");
|
||||
|
||||
// Sub-books that inherit from the current book configuration
|
||||
that.books = _.map(that.langs, function(lang) {
|
||||
that.logInfo("Preparing language book", lang.lang);
|
||||
that.log.info.ln("Preparing language book", lang.lang);
|
||||
return new Book(
|
||||
path.join(that.root, lang.path),
|
||||
_.merge({}, that.context, {
|
||||
@@ -165,7 +172,7 @@ Book.prototype.generate = function(generator) {
|
||||
var that = this;
|
||||
that.options.generator = generator || that.options.generator;
|
||||
|
||||
that.logInfo("start generation with", that.options.generator, "generator");
|
||||
that.log.info.ln("start generation with", that.options.generator, "generator");
|
||||
return Q()
|
||||
|
||||
// Clean output folder
|
||||
@@ -197,16 +204,16 @@ Book.prototype.generate = function(generator) {
|
||||
if (!file) return;
|
||||
|
||||
if (file[file.length -1] == "/") {
|
||||
that.logDebug("transferring folder", file);
|
||||
that.log.debug.ln("transferring folder", file);
|
||||
return Q(generator.transferFolder(file));
|
||||
} else if (_.contains(parsers.extensions, path.extname(file)) && that.navigation[file]) {
|
||||
that.logDebug("parsing", file);
|
||||
that.log.debug.ln("parsing", file);
|
||||
return that.parsePage(file)
|
||||
.then(function(content) {
|
||||
return Q(generator.writeParsedFile(content, file));
|
||||
});
|
||||
} else {
|
||||
that.logDebug("transferring file", file);
|
||||
that.log.debug.ln("transferring file", file);
|
||||
return Q(generator.transferFile(file));
|
||||
}
|
||||
})
|
||||
@@ -226,7 +233,7 @@ Book.prototype.generate = function(generator) {
|
||||
return generator.callHook("finish");
|
||||
})
|
||||
.then(function() {
|
||||
that.logInfo("generation is finished");
|
||||
that.log.info.ln("generation is finished");
|
||||
});
|
||||
};
|
||||
|
||||
@@ -274,11 +281,14 @@ Book.prototype.generateFile = function(output, options) {
|
||||
_tmpDir = path.join(_tmpDir, lang);
|
||||
}
|
||||
|
||||
book.logInfo("copy ebook to", output);
|
||||
book.log.info("copy ebook to", output, "...");
|
||||
return fs.copy(
|
||||
path.join(_tmpDir, "index."+options.ebookFormat),
|
||||
_outputFile
|
||||
);
|
||||
)
|
||||
.then(function() {
|
||||
book.log.info.ok();
|
||||
});
|
||||
};
|
||||
|
||||
// Multi-langs book
|
||||
@@ -309,16 +319,18 @@ Book.prototype.parsePlugins = function() {
|
||||
// Load plugins
|
||||
that.plugins = _.map(that.options.plugins, function(plugin) {
|
||||
var plugin = new Plugin(that, plugin.name);
|
||||
that.log.info("Load plugin", plugin.name, "....");
|
||||
|
||||
if (!plugin.isValid()) {
|
||||
that.logError("Failed to load plugin", plugin.name);
|
||||
that.log.info.fail();
|
||||
failed.push(plugin.name);
|
||||
} else {
|
||||
that.logInfo("Load plugin", plugin.name);
|
||||
that.log.info.ok();
|
||||
}
|
||||
return plugin;
|
||||
});
|
||||
|
||||
that.logDebug("load plugins:", that.plugins.length, "loaded, ", failed.length, "failed");
|
||||
that.log.debug.ln("load plugins:", that.plugins.length, "loaded, ", failed.length, "failed");
|
||||
if (_.size(failed) > 0) return Q.reject(new Error("Error loading plugins: "+failed.join(",")+". Run 'gitbook install' to install plugins from NPM."));
|
||||
return Q();
|
||||
};
|
||||
@@ -327,7 +339,7 @@ Book.prototype.parsePlugins = function() {
|
||||
Book.prototype.parseReadme = function() {
|
||||
var that = this;
|
||||
var structure = that.config.getStructure("readme");
|
||||
that.logDebug("start parsing readme:", structure);
|
||||
that.log.debug.ln("start parsing readme:", structure);
|
||||
|
||||
return that.findFile(structure)
|
||||
.then(function(readme) {
|
||||
@@ -337,7 +349,7 @@ Book.prototype.parseReadme = function() {
|
||||
that.readmeFile = readme.path;
|
||||
that._defaultsStructure(that.readmeFile);
|
||||
|
||||
that.logDebug("readme located at", that.readmeFile);
|
||||
that.log.debug.ln("readme located at", that.readmeFile);
|
||||
return that.template.renderFile(that.readmeFile)
|
||||
.then(function(content) {
|
||||
return readme.parser.readme(content);
|
||||
@@ -355,7 +367,7 @@ Book.prototype.parseLangs = function() {
|
||||
var that = this;
|
||||
|
||||
var structure = that.config.getStructure("langs");
|
||||
that.logDebug("start parsing languages index:", structure);
|
||||
that.log.debug.ln("start parsing languages index:", structure);
|
||||
|
||||
return that.findFile(structure)
|
||||
.then(function(langs) {
|
||||
@@ -364,7 +376,7 @@ Book.prototype.parseLangs = function() {
|
||||
that.langsFile = langs.path;
|
||||
that._defaultsStructure(that.langsFile);
|
||||
|
||||
that.logDebug("languages index located at", that.langsFile);
|
||||
that.log.debug.ln("languages index located at", that.langsFile);
|
||||
return that.template.renderFile(that.langsFile)
|
||||
.then(function(content) {
|
||||
return langs.parser.langs(content);
|
||||
@@ -380,7 +392,7 @@ Book.prototype.parseSummary = function() {
|
||||
var that = this;
|
||||
|
||||
var structure = that.config.getStructure("summary");
|
||||
that.logDebug("start parsing summary:", structure);
|
||||
that.log.debug.ln("start parsing summary:", structure);
|
||||
|
||||
return that.findFile(structure)
|
||||
.then(function(summary) {
|
||||
@@ -391,7 +403,7 @@ Book.prototype.parseSummary = function() {
|
||||
that._defaultsStructure(that.summaryFile);
|
||||
that.files = _.without(that.files, that.summaryFile);
|
||||
|
||||
that.logDebug("summary located at", that.summaryFile);
|
||||
that.log.debug.ln("summary located at", that.summaryFile);
|
||||
return that.template.renderFile(that.summaryFile)
|
||||
.then(function(content) {
|
||||
return summary.parser.summary(content, {
|
||||
@@ -411,7 +423,7 @@ Book.prototype.parseGlossary = function() {
|
||||
var that = this;
|
||||
|
||||
var structure = that.config.getStructure("glossary");
|
||||
that.logDebug("start parsing glossary: ", structure);
|
||||
that.log.debug.ln("start parsing glossary: ", structure);
|
||||
|
||||
return that.findFile(structure)
|
||||
.then(function(glossary) {
|
||||
@@ -422,7 +434,7 @@ Book.prototype.parseGlossary = function() {
|
||||
that._defaultsStructure(that.glossaryFile);
|
||||
that.files = _.without(that.files, that.glossaryFile);
|
||||
|
||||
that.logDebug("glossary located at", that.glossaryFile);
|
||||
that.log.debug.ln("glossary located at", that.glossaryFile);
|
||||
return that.template.renderFile(that.glossaryFile)
|
||||
.then(function(content) {
|
||||
return glossary.parser.glossary(content);
|
||||
@@ -437,17 +449,17 @@ Book.prototype.parseGlossary = function() {
|
||||
Book.prototype.parsePage = function(filename) {
|
||||
var that = this;
|
||||
|
||||
that.logDebug("start parsing file", filename);
|
||||
that.log.debug.ln("start parsing file", filename);
|
||||
|
||||
var extension = path.extname(filename);
|
||||
var filetype = parsers.get(extension);
|
||||
|
||||
if (!filetype) return Q.reject(new Error("Can't parse file: "+filename));
|
||||
|
||||
that.logDebug("render template", filename);
|
||||
that.log.debug.ln("render template", filename);
|
||||
return that.template.renderFile(filename)
|
||||
.then(function(content) {
|
||||
that.logDebug("use file parser", filetype.name, "for", filename);
|
||||
that.log.debug.ln("use file parser", filetype.name, "for", filename);
|
||||
return filetype.parser.page(content);
|
||||
})
|
||||
.then(function(page) {
|
||||
@@ -562,7 +574,7 @@ Book.prototype.indexPage = function(page) {
|
||||
var nav = this.navigation[page.path];
|
||||
if (!nav) return;
|
||||
|
||||
this.logDebug("index page", page.path);
|
||||
this.log.debug.ln("index page", page.path);
|
||||
this.searchIndex.add({
|
||||
url: this.contentLink(page.path),
|
||||
title: nav.title,
|
||||
@@ -581,21 +593,6 @@ Book.prototype._defaultsStructure = function(filename) {
|
||||
that.langsFile = that.langsFile || that.config.getStructure("langs")+extension;
|
||||
}
|
||||
|
||||
// Log message
|
||||
Book.prototype.log = function(level) {
|
||||
if (level < this.context.logLevel) return;
|
||||
|
||||
var args = Array.prototype.slice.apply(arguments);
|
||||
var levelKey = _.findKey(Book.LOG_LEVELS, function(v) { return v == args[0]; });
|
||||
|
||||
args[0] = Book.LOG_COLORS[levelKey](levelKey.toLowerCase()+":");
|
||||
this.context.log.apply(null, args);
|
||||
};
|
||||
Book.prototype.logDebug = _.partial(Book.prototype.log, Book.LOG_LEVELS.DEBUG);
|
||||
Book.prototype.logInfo = _.partial(Book.prototype.log, Book.LOG_LEVELS.INFO);
|
||||
Book.prototype.logWarn = _.partial(Book.prototype.log, Book.LOG_LEVELS.WARNING);
|
||||
Book.prototype.logError = _.partial(Book.prototype.log, Book.LOG_LEVELS.ERROR);
|
||||
|
||||
|
||||
// Init and return a book
|
||||
Book.init = function(root) {
|
||||
@@ -616,10 +613,10 @@ Book.init = function(root) {
|
||||
}, []);
|
||||
};
|
||||
|
||||
book.logInfo("init book at", root);
|
||||
book.log.infoLn("init book at", root);
|
||||
return fs.mkdirp(root)
|
||||
.then(function() {
|
||||
book.logInfo("detect structure from SUMMARY (if it exists)");
|
||||
book.log.infoLn("detect structure from SUMMARY (if it exists)");
|
||||
return book.parseSummary();
|
||||
})
|
||||
.fail(function() {
|
||||
@@ -652,7 +649,7 @@ Book.init = function(root) {
|
||||
|
||||
return fs.exists(absolutePath)
|
||||
.then(function(exists) {
|
||||
book.logInfo("create", chapter.path);
|
||||
book.log.infoLn("create", chapter.path);
|
||||
if(exists) return;
|
||||
|
||||
return fs.mkdirp(path.dirname(absolutePath))
|
||||
@@ -663,7 +660,7 @@ Book.init = function(root) {
|
||||
}));
|
||||
})
|
||||
.then(function() {
|
||||
book.logInfo("initialization is finished");
|
||||
book.log.infoLn("initialization is finished");
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ Generator.prototype.prepareTemplates = function() {
|
||||
Generator.prototype.writeSummary = function() {
|
||||
var that = this;
|
||||
|
||||
that.book.logInfo("write SUMMARY.html");
|
||||
that.book.log.info.ln("write SUMMARY.html");
|
||||
return this._writeTemplate(this.templates["summary"], {}, path.join(this.options.output, "SUMMARY.html"));
|
||||
};
|
||||
|
||||
@@ -98,7 +98,7 @@ Generator.prototype.finish = function() {
|
||||
stringUtils.optionsToShellArgs(_options)
|
||||
].join(" ");
|
||||
|
||||
that.book.logInfo("start conversion to", that.ebookFormat);
|
||||
that.book.log.info.ln("start conversion to", that.ebookFormat);
|
||||
exec(command, function (error, stdout, stderr) {
|
||||
if (error) {
|
||||
if (error.code == 127) {
|
||||
|
||||
@@ -132,7 +132,7 @@ Generator.prototype.writeParsedFile = function(page) {
|
||||
var basePath = path.relative(path.dirname(output), this.options.output) || ".";
|
||||
if (process.platform === 'win32') basePath = basePath.replace(/\\/g, '/');
|
||||
|
||||
that.book.logInfo("write parsed file", page.path, "to", relativeOutput);
|
||||
that.book.log.info.ln("write parsed file", page.path, "to", relativeOutput);
|
||||
return that.normalizePage(page)
|
||||
.then(function() {
|
||||
return that._writeTemplate(that.templates["page"], {
|
||||
|
||||
+3
-2
@@ -9,11 +9,12 @@ var Plugin = require("./plugin");
|
||||
var Server = require("./utils/server");
|
||||
var stringUtils = require("./utils/string");
|
||||
var watch = require("./utils/watch");
|
||||
var logger = require("./utils/logger");
|
||||
|
||||
var LOG_OPTION = {
|
||||
name: "log",
|
||||
description: "Minimum log level to display",
|
||||
values: _.chain(Book.LOG_LEVELS).keys().map(stringUtils.toLowerCase).value(),
|
||||
values: _.chain(logger.LEVELS).keys().map(stringUtils.toLowerCase).value(),
|
||||
defaults: "info"
|
||||
};
|
||||
|
||||
@@ -43,7 +44,7 @@ module.exports = {
|
||||
'config': {
|
||||
'output': output
|
||||
},
|
||||
'logLevel': Book.LOG_LEVELS[(kwargs.log).toUpperCase()]
|
||||
'logLevel': kwargs.log
|
||||
}));
|
||||
|
||||
return book.parse()
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ var BookLoader = nunjucks.Loader.extend({
|
||||
.then(function(filepath) {
|
||||
// Is local file
|
||||
if (!filepath) filepath = path.resolve(that.book.root, fileurl);
|
||||
else that.book.logDebug("resolve from git", fileurl, "to", filepath)
|
||||
else that.book.log.debug.ln("resolve from git", fileurl, "to", filepath)
|
||||
|
||||
// Read file from absolute path
|
||||
return fs.readFile(filepath)
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
var _ = require('lodash');
|
||||
var util = require('util');
|
||||
var color = require('bash-color');
|
||||
|
||||
var LEVELS = {
|
||||
DEBUG: 0,
|
||||
INFO: 1,
|
||||
WARNING: 2,
|
||||
ERROR: 3
|
||||
};
|
||||
|
||||
var COLORS = {
|
||||
DEBUG: color.purple,
|
||||
INFO: color.cyan,
|
||||
WARNING: color.yellow,
|
||||
ERROR: color.red
|
||||
};
|
||||
|
||||
module.exports = function(_write, logLevel) {
|
||||
var logger = {};
|
||||
var lastChar = '\n';
|
||||
if (_.isString(logLevel)) logLevel = LEVELS[logLevel.toUpperCase()];
|
||||
|
||||
// Write a simple message
|
||||
logger.write = function(msg) {
|
||||
msg = msg.toString();
|
||||
lastChar = _.last(msg);
|
||||
return _write(msg);
|
||||
};
|
||||
|
||||
// Write a line
|
||||
logger.writeLn = function(msg) {
|
||||
return this.write((msg || "")+"\n");
|
||||
};
|
||||
|
||||
// Write a message with a certain level
|
||||
logger.log = function(level) {
|
||||
if (level < logLevel) return;
|
||||
|
||||
var levelKey = _.findKey(LEVELS, function(v) { return v == level; });
|
||||
var args = Array.prototype.slice.apply(arguments, [1]);
|
||||
var msg = util.format.apply(util, args);
|
||||
|
||||
if (lastChar == '\n') {
|
||||
msg = COLORS[levelKey](levelKey.toLowerCase()+":")+" "+msg;
|
||||
}
|
||||
|
||||
return logger.write(msg);
|
||||
};
|
||||
|
||||
// Write a OK
|
||||
logger.ok = function(level) {
|
||||
return logger.log(level, color.green("OK")+"\n");
|
||||
};
|
||||
|
||||
// Write an "FAIL"
|
||||
logger.fail = function(level) {
|
||||
return logger.log(level, color.red("ERROR")+"\n");
|
||||
};
|
||||
|
||||
_.each(LEVELS, function(level, levelKey) {
|
||||
levelKey = levelKey.toLowerCase();
|
||||
|
||||
logger[levelKey] = _.partial(logger.log, level);
|
||||
logger[levelKey].ln = function() {
|
||||
var args = Array.prototype.slice.apply(arguments);
|
||||
args.push("\n");
|
||||
logger[levelKey].apply(logger, args);
|
||||
};
|
||||
logger[levelKey].ok = _.partial(logger.ok, level);
|
||||
logger[levelKey].fail = _.partial(logger.fail, level);
|
||||
});
|
||||
|
||||
return logger;
|
||||
};
|
||||
module.exports.LEVELS = LEVELS;
|
||||
module.exports.COLORS = COLORS;
|
||||
Reference in New Issue
Block a user