一个简单的日志module
发布于 14 年前 作者 qingdu 7522 次浏览 最后一次编辑是 8 年前

<br/> <br/>一个简单的日志module, 功能如下 <br/><ul> <br/> <li>时间显示</li> <br/> <li>调用log的文件名与行号显示</li> <br/> <li>不同日志级别使用不同颜色输出</li> <br/> <li>支持stdout输出的同时写入文件日志</li> <br/> <li>文件日志使用缓存以降低io次数</li> <br/></ul> <br/>使用示例 <br/><pre escaped=“true” lang=“javascript”>var log = require(’./log’), <br/> logWithoutFile = log.create(); <br/> logWithFile = log.create(log.WARNING, ‘my.log’), <br/> <br/>logWithoutFile.info(‘info msg’); <br/>logWithoutFile.debug(‘debug msg’); <br/>logWithoutFile.warning(‘warning msg’); <br/>logWithoutFile.error(‘error msg’); <br/>logWithoutFile.trace(‘trace msg’); <br/> <br/>logWithFile.info(‘info msg’); <br/>logWithFile.debug(‘debug msg’); <br/>logWithFile.warning(‘warning msg’); <br/>logWithFile.error(‘error msg’); <br/>logWithFile.trace(‘trace msg’);</pre> <br/>输出效果 <br/> <br/><img title=“cnode-log-demo.jpg” src=“http://static.data.taobaocdn.com/up/nodeclub/2011/03/cnode-log-demo.jpg” border=“0” alt=“cnode-log-demo” width=“579” height=“159” /> <br/> <br/>源码如下 <br/><pre escaped=“true” lang=“javascript”>var fs = require(‘fs’); <br/> <br/>var cwd = process.cwd() + ‘/’, <br/> INFO = 0; <br/> DEBUG = 1; <br/> WARNING = 2; <br/> ERROR = 3; <br/> TRACE = 4; <br/> INIT = 6; <br/> type = [‘INFO’, ‘DEBUG’, ‘WARNING’, ‘ERROR’, ‘TRACE’, ‘’, ‘LOG_INIT’]; <br/> colors = [38, 34, 35, 31, 32, 36, 33]; <br/> bufferSize = 20000; <br/> writeSize = 16384; <br/> <br/>exports.INFO = INFO; <br/>exports.DEBUG = DEBUG; <br/>exports.WARNING = WARNING; <br/>exports.ERROR = ERROR; <br/>exports.TRACE = TRACE; <br/> <br/>function getPos() { <br/> try { <br/> throw new Error(); <br/> } catch(e) { <br/> var pos = e.stack.split(’\n’)[4].split(’(’)[1].split(’)’)[0].split(’:’); <br/> return pos[0].replace(cwd, ‘’) + ‘:’ + pos[1]; <br/> } <br/>} <br/> <br/>function pad2(num) { <br/> return num > 9 ? num : ‘0’ + num; <br/>} <br/> <br/>function getTime() { <br/> var t = new Date(); <br/> return [t.getFullYear(), ‘-’, pad2(t.getMonth() + 1) , ‘-’, pad2(t.getDate()), ’ ‘, <br/> pad2(t.getHours()), ‘:’, pad2(t.getMinutes()), ‘:’, pad2(t.getSeconds())].join(’’); <br/>} <br/> <br/>function formatLog(log, color) { <br/> var tag = head = foot = ‘’; <br/> if (color) { <br/> head = ‘\x1B[’; <br/> foot = ‘\x1B[0m’; <br/> tag = colors[5]+‘m’; <br/> color = colors[log.type]+‘m’; <br/> } <br/> <br/>return [log.time, ’ [’, head, color, type[log.type], foot, ‘] [’, head, tag, log.pos, foot, ‘] ‘, log.msg].join(’’); <br/>} <br/> <br/>exports.create = function(level, file) { <br/> if (!level) { <br/> level = INFO; <br/> } <br/> if (file) { <br/> var buffer = new Buffer(bufferSize); <br/> var pos = 0; <br/> var fd = fs.openSync(file, ‘a’); <br/> process.on(‘exit’, function(){ <br/> fs.writeSync(fd, buffer, 0, pos, null); <br/> }) <br/> } <br/> function log(type, msg) { <br/> if (type < level){ <br/> return; <br/> } <br/> var log = {type:type, msg:msg, time:getTime(), pos:getPos()}; <br/> console.log(formatLog(log, true)); <br/> if (file) { <br/> if (pos >= writeSize) { <br/> fs.writeSync(fd, buffer, 0, pos, null); <br/> pos = 0; <br/> } <br/> pos += buffer.write(formatLog(log) + “\r\n”, pos); <br/> } <br/> } <br/> console.log(formatLog({type:INIT, pos:file, time:getTime(), msg: 'log init with level ’ + type[level]}, true)); <br/> return { <br/> info : function(msg) {log(INFO, msg);}, <br/> debug : function(msg) {log(DEBUG, msg);}, <br/> warning : function(msg) {log(WARNING, msg);}, <br/> error : function(msg) {log(ERROR, msg);}, <br/> trace : function(msg) {log(TRACE, msg);}, <br/> }; <br/>}</pre>

12 回复

实用小模块。buffer是细节,细节体现专业!

buffer的值设置得不专业,清爷迷糊了

偷了个懒而已…

长过3k的单条log毕竟是少数, 这样少做一次bytelength…可以提高点性能

那倒是。如果这个log非常重要,比如计费系统的log,就不能这么搞了

顶个~~不错的东东。。

一般来说,INFO和WARNING的日志级别不应该输出DEBUG级别的log <br/>all < debug < info < waring < error < trace

适当的去做一些偷懒来提高性能,对于某些情况还是必要的( 比如:log长度不可能超过3K)。

求server及client完整代码。

var pos = e.stack.split(’\n’)[4].split(’(’)[1].split(’)’)[0].split(’:’); <br/> <br/>有些情况下 是没有()会导致一个错误 <br/> <br/>某种情况我猜测是在不同的文件夹下的原因. <br/> <br/>这是我的修改 <br/> var pos = e.stack.split(/\n/)[4].split(‘at’)[1].replace(’)’, ‘’).replace(’(’, ‘’).replace(’ ', ‘’); <br/> pos = cwd + pos.split(":")[1]; <br/> return pos.replace("\/", ‘’);

你好 , 初学nodeJS <br/>我试了下…… 不知道为什么 <br/>info : function(msg) {log(INFO, msg);}, <br/>这个位置报语法错误% 求详解

如果是计费log,具体需要考虑那些东西呢。能给个思路吗?TX

回到顶部