GVKun编程网logo

Node.js 日志处理模块log4js(nodejs日志管理)

14

在本文中,我们将详细介绍Node.js日志处理模块log4js的各个方面,并为您提供关于nodejs日志管理的相关解答,同时,我们也将为您带来关于Java日志相关记录(Juljcllog4jlog4j

在本文中,我们将详细介绍Node.js 日志处理模块log4js的各个方面,并为您提供关于nodejs日志管理的相关解答,同时,我们也将为您带来关于Java日志相关记录 (Jul jcl log4j log4j2 Logback SLF4J)、koa-log4 管理nodeJs访问日志、系统日志、koa2学习笔记02 - 给koa2添加系统日志 —— node日志管理模块log4js、log4j 日志输出到日志文件中和控制台中 +log4j 配置详解的有用知识。

本文目录一览:

Node.js 日志处理模块log4js(nodejs日志管理)

Node.js 日志处理模块log4js(nodejs日志管理)

log4js 是 Node.js 日志处理中的数一数二的模块。比起 console 或者 TJ 的 debug 有其优势,尤其针对投入生产的 Node.js 项目来说下面这些是不可少的:

  1. 日志分级
  2. 日志分类
  3. 日志落盘

本文将会给你一个 log4js 的全面介绍,让你可以在项目中驾轻就熟的使用 log4js,开发调试容易,线上更好地监控或排查问题。

牛刀小试

下面这三行代码为你展示了 log4js 最简单的用法:

// file: simplest.js
var log4js = require(''log4js'');
var logger = log4js.getLogger();
logger.debug("Time:", new Date());

调用 .getLogger() 可以获得 log4js 的 Logger 实例,这个实例的用法与 console 是一致的,可以调用 .debug (也有 .info 、 .error 等方法)来输出日志。

运行 node simplest.js ,输出如下:

$node simplest.js
[2016-08-21 00:01:24.852] [DEBUG] [default] - Time: 2016-08-20T16:01:24.852Z

Time: 2016-08-20T16:01:24.852Z 是我们想要输出的内容,前面的包含说明符 [2016-08-21 00:01:24.852] [DEBUG] [default] 后文再表。

使用起来是不是也很简单,好了,在我们深入到 log4js 高级用法之前,我们先来熟悉一下几个 log4js 中的概念。

Level

这个理解起来不难,就是日志的分级。日志有了分级,log4js 才能更好地为我们展示日志(不同级别的日志在控制台中采用不同的颜色,比如 error 通常是红色的),在生产可以有选择的落盘日志,比如避免一些属于 .debug 才用的敏感信息被泄露出来。

log4js 的日志分为九个等级,各个级别的名字和权重如下:

{
 ALL: new Level(Number.MIN_VALUE, "ALL"),
 TRACE: new Level(5000, "TRACE"),
 DEBUG: new Level(10000, "DEBUG"),
 INFO: new Level(20000, "INFO"),
 WARN: new Level(30000, "WARN"),
 ERROR: new Level(40000, "ERROR"),
 FATAL: new Level(50000, "FATAL"),
 MARK: new Level(9007199254740992, "MARK"), // 2^53
 OFF: new Level(Number.MAX_VALUE, "OFF")
}

上个图:

ALL OFF 这两个等级并不会直接在业务代码中使用。剩下的七个即分别对应 Logger 实例的七个方法, .trace .debug .info ... 。也就是说,你在调用这些方法的时候,就相当于为这些日志定了级。因此,之前的 [2016-08-21 00:01:24.852] [DEBUG] [default] - Time: 2016-08-20T16:01:24.852Z 中的 DEBUG 既是这条日志的级别。

类型

log4js 还有一个概念就是 category(类型),你可以设置一个 Logger 实例的类型,按照另外一个维度来区分日志:

// file: set-catetory.js
var log4js = require(''log4js'');
var logger = log4js.getLogger(''example'');
logger.debug("Time:", new Date());

在通过 getLogger 获取 Logger 实例时,唯一可以传的一个参数就是 loggerCategory(如 ''example'' ),通过这个参数来指定 Logger 实例属于哪个类别。这与 TJ 的 debug 是一样的:

var debug = require(''debug'')(''worker'');

setInterval(function(){
 debug(''doing some work'');
}, 1000);

在 debug 中 ''worker'' ,同样也是为日志分类。好了,回来运行 node set-catetory.js :

[2016-08-21 01:16:00.212] [DEBUG] example - Time: 2016-08-20T17:16:00.212Z
与之前的 [2016-08-21 00:01:24.852] [DEBUG] [default] - Time: 2016-08-20T16:01:24.852Z 唯一不同的地方就在于, [default] 变成了 example 。

那类别有什么用呢,它比级别更为灵活,为日志了提供了第二个区分的维度,例如,你可以为每个文件设置不同的 category,比如在 set-catetory.js 中:

// file: set-catetory.js
var log4js = require(''log4js'');
var logger = log4js.getLogger(''set-catetory.js'');
logger.debug("Time:", new Date());

就可以从日志 [2016-08-21 01:24:07.332] [DEBUG] set-catetory.js - Time: 2016-08-20T17:24:07.331Z 看出,这条日志来自于 set-catetory.js 文件。又或者针对不同的 node package 使用不同的 category,这样可以区分日志来源于哪个模块。

Appender

好了,现在日志有了级别和类别,解决了日志在入口处定级和分类问题,而在 log4js 中,日志的出口问题(即日志输出到哪里)就由 Appender 来解决。

默认 appender

下面是 log4js 内部默认的 appender 设置:

// log4js.js
defaultConfig = {
 appenders: [{
  type: "console"
 }]
}

可以看到,在没有对 log4js 进行任何配置的时候,默认将日志都输出到了控制台。

设置自己的 appender

我们可以通过 log4js.configure 来设置我们想要的 appender。

// file: custom-appender.js
var log4js = require(''log4js'');
log4js.configure({
 appenders: [{
  type: ''file'',
  filename: ''default.log''
 }]
})
var logger = log4js.getLogger(''custom-appender'');
logger.debug("Time:", new Date());

在上例中,我们将日志输出到了文件中,运行代码,log4js 在当前目录创建了一个名为 default.log 文件, [2016-08-21 08:43:21.272] [DEBUG] custom-appender - Time: 2016-08-21T00:43:21.272Z 输出到了该文件中。

log4js 提供的 appender

Console 和 File 都是 log4js 提供的 appender,除此之外还有:

DateFile:日志输出到文件,日志文件可以安特定的日期模式滚动,例如今天输出到 default-2016-08-21.log ,明天输出到 default-2016-08-22.log ;
SMTP:输出日志到邮件;
Mailgun:通过 Mailgun API 输出日志到 Mailgun;
levelFilter 可以通过 level 过滤;
等等其他一些 appender,到 这里 可以看到全部的列表。

过滤级别和类别

我们可以调整 appender 的配置,对日志的级别和类别进行过滤:

// file: level-and-category.js
var log4js = require(''log4js'');
log4js.configure({
 appenders: [{
  type: ''logLevelFilter'',
  level: ''DEBUG'',
  category: ''category1'',
  appender: {
   type: ''file'',
   filename: ''default.log''
  }
 }]
})
var logger1 = log4js.getLogger(''category1'');
var logger2 = log4js.getLogger(''category2'');
logger1.debug("Time:", new Date());
logger1.trace("Time:", new Date());
logger2.debug("Time:", new Date());

运行,在 default.log 中增加了一条日志:

[2016-08-21 10:08:21.630] [DEBUG] category1 - Time: 2016-08-21T02:08:21.629Z
来看一下代码:

使用 logLevelFilter 和 level 来对日志的级别进行过滤,所有权重大于或者等于 DEBUG 的日志将会输出。这也是之前提到的日志级别权重的意义;
通过 category 来选择要输出日志的类别, category2 下面的日志被过滤掉了,该配置也接受一个数组,例如 [''category1'', ''category2''] ,这样配置两个类别的日志都将输出到文件中。

Layout

Layout 是 log4js 提供的高级功能,通过 layout 我们可以自定义每一条输出日志的格式。log4js 内置了四中类型的格式:

messagePassThrough:仅仅输出日志的内容;
basic:在日志的内容前面会加上时间、日志的级别和类别,通常日志的默认 layout;
colored/coloured:在 basic 的基础上给日志加上颜色,appender Console 默认使用的就是这个 layout;
pattern:这是一种特殊类型,可以通过它来定义任何你想要的格式。
一个 pattern 的例子:

// file: layout-pattern.js
var log4js = require(''log4js'');
log4js.configure({
 appenders: [{
  type: ''console'',
  layout: {
   type: ''pattern'',
   pattern: ''[%r] [%[%5.5p%]] - %m%n''
  }
 }]
})
var logger = log4js.getLogger(''layout-pattern'');
logger.debug("Time:", new Date());

%r %p $m $n 是 log4js 内置的包含说明符,可以借此来输出一些 meta 的信息,更多细节,可以参考 log4js 的 文档 。

一张图再来说明一下,Logger、Appender 和 Layout 的定位。

实战:输出 Node 应用的 ACCESS 日志 access.log

为了方便查问题,在生产环境中往往会记录应用请求进出的日志。那使用 log4js 怎么实现呢,直接上代码:

// file: server.js
var log4js = require(''log4js'');
var express = require(''express'');

log4js.configure({
 appenders: [{
  type: ''DateFile'',
  filename: ''access.log'',
  pattern: ''-yyyy-MM-dd.log'',
  alwaysIncludePattern: true,
  category: ''access''
 }]
});

var app = express();
app.use(log4js.connectLogger(log4js.getLogger(''access''), { level: log4js.levels.INFO }));
app.get(''/'', function(req,res) {
 res.send(''前端外刊评论'');
});
app.listen(5000);

看看我们做了哪些事情:

配置了一个 appender,从日志中选出类别为 access 的日志,输出到一个滚动的文件中;
log4js.getLogger(''access'') 获取一个类别为 access 的 Logger 实例,传递给 log4js.connectLogger 中间件,这个中间件收集访问信息,通过这个实例打出。
启动服务器,访问 http://localhost:5000,你会发现目录中多了一个名为 access.log-2016-08-21.log 的文件,里面有两条日志:

[2016-08-21 14:34:04.752] [INFO] access - ::1 - - "GET / HTTP/1.1" 200 18 "" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36"
[2016-08-21 14:34:05.002] [INFO] access - ::1 - - "GET /favicon.ico HTTP/1.1" 404 24 "http://localhost:5000/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36"

通过 log4js 日志的分类和appender功能,我们把访问日志输出到了一个滚动更新的文件之中。

总结

本文为大家全面地介绍了 log4js 的用法,与 console 或者简单的日志工具相比,log4js 使用起来更复杂,当然功能更强大,适合生产级应用的使用。如果大家有兴趣的话,请留言告诉外刊君,接下来可能为大家介绍如何在 Node 应用中做配置管理。

您可能感兴趣的文章:
  • nodejs 日志模块winston的使用方法
  • Nodejs Express 通过log4js写日志到Logstash(ELK)
  • 使用koa-log4管理nodeJs日志笔记的使用方法
  • NodeJS读取分析Nginx错误日志的方法
  • Node.js中使用Log.io在浏览器中实时监控日志(等同tail -f命令)
  • Node.js利用console输出日志文件的方法示例
  • Node.js利用debug模块打印出调试日志的方法
  • Node.js和MongoDB实现简单日志分析系统
  • Node.js log4js日志管理详解
  • node错误处理与日志记录的实现
  • nodejs实现日志读取、日志查找及日志刷新的方法分析

Java日志相关记录 (Jul jcl log4j log4j2 Logback SLF4J)

Java日志相关记录 (Jul jcl log4j log4j2 Logback SLF4J)

一、写在前面

在java 中实现记录日志的方式有很多种
1. 最初的方式,就是system.print.out ,err 这样直接在控制台打印消息,缺点太多了,这样与业务逻辑无关的代码会变得更多,不能按日志等及输出,以及那些不输出等。
2. JUL,java util logging在jdk的java.util.logging包中,也叫jkdLog或者jdk14log; 在JDK 1.4 版本之后,java提供了日志的API ,可以往文件中写日志了,最方便不需要第三方包,其实际使用人较少。
3. log4j , 最强大的记录日志的方式。 可以通过配置 .properties 或是 .xml 的文件, 配置日志的目的地,格式等等,基于老的jdk性能不高,该项目现在已经停止维护,但是用的人还是最多的。
4. Log4j2 该项目是log4j的升级版,性能较好,也吸收了logback等日志记录组件的优点。
5. commons-logging是一个日志接口,最综合和常见的日志记录方式, 经常是和log4j或者log4j2 结合起来使用。
6. Slf4j也是一个日志接口,最常见的是和logback一起使用。
7. 日志等级其实最常用的就是这四个等级(debug,info,warn,error)。

二、JUL(java util logger)

使用java 自带的logger最方便的作用提无需引入第三方包
直接上代码:

package com.xxx.test;
import java.io.IOException;
import java.util.Date;
import java.util.logging.FileHandler;
import java.util.logging.Formatter;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;

public class TestLogJava {
    public static void main(String[] args) throws IOException{
        Logger log = Logger.getLogger("tesglog");
        log.setLevel(Level.ALL);
        FileHandler fileHandler = new FileHandler("testlog.log");
        fileHandler.setLevel(Level.ALL);
        fileHandler.setFormatter(new LogFormatter());
        log.addHandler(fileHandler);
        log.info("This is test java util log"); 
        log.warning("warning .........");
        log.log(Level.FINE, "fine...");
        log.finer("finer ....");
    }
}
 
class LogFormatter extends Formatter {
    @Override
    public String format(LogRecord record) {
        Date date = new Date();
        String sDate = date.toString();
        return "[" + sDate + "]" + "[" + record.getLevel() + "]"
                + record.getClass() + record.getMessage() + "\n";
    }
}



Java util logger使用的日志级别:SEVERE(最高值),WARNING,INFO,CONFIG,FINE,FINER,FINEST(最低值)以及OFF和ALL
先通地Logger工厂获得一个log实例,日志记当格是默认是xml 使用前最好先自己格式化自己所要的格式(上面的LogFormatter就是自定义格式)。log的Handler有许多可以使用常见是写到文件也就是FileHandler。
使用步骤:new 一个FileHandler 实例,设定fileHandler的等级和格式,并添加到log实例上,然后就是直接使用log.info()写入了。

三、JCL(Jakarta commons logger)

说的是java 通用日志,其实是apache出品的通用日志接口,是一个接口。
提供的是一个日志(Log)接口(interface),同时兼顾轻量级和不依赖于具体的日志实现工具。它提供给中间件/日志工具开发者一个简单的日志操作抽象,允许程序开发人员使用不同的具体日志实现工具。
JCL有两个基本的抽象类:Log(基本记录器)和LogFactory(负责创建Log实例)。当commons-logging.jar被加入到 CLASSPATH之后,它会合理地猜测你想用的日志工具,然后进行自我设置,用户根本不需要做任何设置。默认的LogFactory是按照下列的步骤去发现并决定那个日志工具将被使用的(按照顺序,寻找过程会在找到第一个工具时中止):
   1. 寻找当前factory中名叫org.apache.commons.logging.Log配置属性的值
   2. 寻找系统中属性中名叫org.apache.commons.logging.Log的值
   3. 如果应用程序的classpath中有log4j,则使用相关的包装(wrapper)类(Log4JLogger)
   4. 如果应用程序运行在jdk1.4的系统中,使用相关的包装类(Jdk14Logger)
   5. 使用简易日志包装类(SimpleLog)
org.apache.commons.logging.Log的具体实现有如下:
-org.apache.commons.logging.impl.Jdk14Logger 使用JDK1.4。
-org.apache.commons.logging.impl.Log4JLogger 使用Log4J。
-org.apache.commons.logging.impl.LogKitLogger 使用 avalon-Logkit。
-org.apache.commons.logging.impl.SimpleLog common-logging自带日志实现类。它实现了Log接口,把日志消息都输出到系统错误流System.err 中。 
-org.apache.commons.logging.impl.NoOpLog common-logging自带日志实现类。它实现了Log接口。 其输出日志的方法中不进行任何操作。

package com.xxx.test;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.*;
public class TestCommonLog {
	private static Log log = LogFactory.getLog(TestCommonLog.class);
	public static void main(String[] args) {
		log.debug("debug ......");
		log.info("info ......");
		log.warn("warn ......");
		log.error("error ......");
		log.fatal("fatal ......");
	}
}


四、log4j(log4j版本1)

Log4j是java开发用得最多最常见的日志组件,这个是组件,是有完整的实现。可以完整的独立使用。
直接上代码:

Log4j.properties

### \u8BBE\u7F6E###
log4j.rootLogger = debug,stdout,D,E

### \u8F93\u51FA\u4FE1\u606F\u5230\u63A7\u5236\u62AC ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

### \u8F93\u51FADEBUG \u7EA7\u522B\u4EE5\u4E0A\u7684\u65E5\u5FD7\u5230=E://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = E://logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG 
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

### \u8F93\u51FAERROR \u7EA7\u522B\u4EE5\u4E0A\u7684\u65E5\u5FD7\u5230=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E://logs/error.log 
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR 
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n



Log4jTest.java

package com.xxx.test;
import org.apache.log4j.Logger;
public class Log4jTest {
	private static Logger logger = Logger.getLogger(Log4jTest.class);
	public static void main(String args[]) {
		// 记录debug级别的信息
		logger.debug("debug");
		// 记录info级别的信息
		logger.info("info");
		// 记录error级别的信息
		logger.error("error");
	}
}



五、log4j2使用

Log4j2是log4j的重构升级版,他改进了log4j性能和不足,吸取了logback优点
不说了直接上代码:

Log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
	<Appenders>
		<Console name="Console" target="SYSTEM_OUT">
			<PatternLayout pattern="%m%n" />
		</Console>
	</Appenders>
	<Loggers>
		<Root level="DEBUG">
			<AppenderRef ref="Console" />
		</Root>
	</Loggers>
</Configuration>


Log4j2Test.java

package com.xxx.test;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; 
public class Log4j2Test {
	private static Logger logger = LogManager.getLogger(Log4j2Test.class);
	public static boolean hello() {
        logger.entry();   //trace级别的信息,单独列出来是希望你在某个方法或者程序逻辑开始的时候调用,和logger.trace("entry")基本一个意思
        logger.error("Did it again!");   //error级别的信息,参数就是你输出的信息
        logger.info("我是info信息");    //info级别的信息
        logger.debug("我是debug信息");
        logger.warn("我是warn信息");
        logger.fatal("我是fatal信息");
        logger.log(Level.DEBUG, "我是debug信息");   //这个就是制定Level类型的调用:谁闲着没事调用这个,也不一定哦!
        logger.exit();    //和entry()对应的结束方法,和logger.trace("exit");一个意思
        return false;
    }
	public static void main(String[] args) {
		hello();
	}
}

log4j2在没有任何配置的情况下文件时会自动使用默认的配置:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
        </Console>
    </Appenders>
    <Loggers>
        <Root level="error">
            <AppenderRef ref="Console" />
        </Root>
    </Loggers>
</Configuration>


该配置只有一个Appender:Console,目标是SYSTEM_OUT,即日志内容,都会打印在eclipse控制台上。Root Logger的级别是error,即:所有error及以上级别的日志才会记录。(注:日志级别顺序为 TRACE < DEBUG < INFO < WARN < ERROR < FATAL ),所以最终只有2日志会输出(error,fatal)


再来Log4j2的详细一点的配置

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="OFF">
	<Appenders>
		<Console name="Console" target="SYSTEM_OUT">
			<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
		</Console>

		<File name="ERROR" fileName="logs/error.log">
			<ThresholdFilter level="error" onMatch="ACCEPT"
				onMismatch="DENY" />
			<PatternLayout
				pattern="%d{yyyy.MM.dd ''at'' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n" />
		</File>

		<RollingFile name="RollingFile" fileName="logs/app.log"
			filePattern="log/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
			<PatternLayout
				pattern="%d{yyyy-MM-dd ''at'' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n" />
			<SizeBasedTriggeringPolicy size="50MB" />
		</RollingFile>

		<RollingFile name="ROLLING" fileName="d:/logs/howsun.log"
			filePattern="d:/logs/howsun_%d{yyyy-MM-dd}_%i.log">
			<PatternLayout pattern="%d %p %c{1.} [%t] %m%n" />
			<Policies>
				<TimeBasedTriggeringPolicy modulate="true"
					interval="24" />
				<SizeBasedTriggeringPolicy size="51200 KB" />
			</Policies>
			<DefaultRolloverStrategy max="20" />
		</RollingFile>

		<properties>
			<property name="filenameLog">logs/payPlatform.log</property>
		</properties>

		<!-- 定义后台文档日志记录 -->
		<RollingFile name="RollingFile" fileName="${filenameLog}"
			filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
			<PatternLayout>
				<Pattern>%d{yyyy-MM-dd HH:mm:ss} [%p] [%t] %c{1}.%M(%L) | %m%n
				</Pattern>
			</PatternLayout>
			<Policies>
				<!-- 定义log文件封存的周期 -->
				<TimeBasedTriggeringPolicy interval="1"
					modulate="true" />
				<SizeBasedTriggeringPolicy size="100 MB" />
			</Policies>
			<DefaultRolloverStrategy fileIndex="max" max="2" />
		</RollingFile>

	</Appenders>
	<Loggers>
		<Root level="DEBUG">
			<AppenderRef ref="Console" />
			<appender-ref ref="ROLLING" />
			<appenderRef ref="RollingFile" />
		</Root>
	</Loggers>
</Configuration>



六、SLF4J与Logback 

SLF4J全名Simple Logging Facade for Java
不是具体的日志解决方案,它只服务于各种各样的日志系统。按照官方的说法,SLF4J是一个用于日志系统的简单Facade,允许最终用户在部署其应用时使用其所希望的日志系统。
SLF4J同apache的commons-logger一样,都是供示一个简单的接口,不是一个完格的日志解决方案他一般需要和其它日志系统进行配合使用。
SLF4J创建项目在包中引入SLF4J的核心接口slf4j-api.jar包
上代码:

package com.xxx.test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LogbackTest {
	private static Logger logger = LoggerFactory.getLogger(LogbackTest.class);
	public static void main(String[] args) {
		System.out.println("-----");
		logger.trace("trace");  
        logger.debug("debug");  
        logger.info("info");  
        logger.warn("warn");  
        logger.error("error");
	}
}



如果没有引入其它包,是打印不出日志的,


这里必须在再引入一个现实的包可以使用slf4j-simple.jar,这样slf4j-api会调用slf4j-simple.jarsimple现实(全部打印在console上),也可以使用slf4j-nop.jar就是无任何操作的实现。
同理,也可以在jdk1.4上使用slf4j-jdk14.jar包来使用jdk14logger的实现,也可使用slf4j-jcl.jarJakarta commons logger的实现,虽然他自身也是一个通用日志接口),同样可以使用slf4j-logj12.jar的实现了。只是在使用其它实现是需要加入其它相应日志系统的jar 包并同时做好相应日志系统的配置,例使用了slf4j-log4j12.jar则还需要加入log4j-1.2.7.jar 包,并且在写好相应的log4j.properties配置文件。

SLF4J这种机制还可以把原来用的不是slf4j这种日志接口的直接转换成slf4j。例原来使用的是commons-logging可以把原来的commons-logging.jar包删除,把jcl-over-slf4j.jar添加到项目即可。

提到slf4j就不得不提一下logback

Logback同也是由log4j主创人创立,slf4j也是他搞的。改写了log4j的核心提高了性能,意在替换log4j(指log4j-v1)。logback项目主要有三个部分core, classic, access, corelogback的核心,classicslf4japi的实现,而access则是配使servlet容器配合提供http访问记录。

使用同上,需要加入slf4j-api.jarlogback-core.jar,logback-classic.jar,logback-access.jar

Slf4jLogbackTest.java

package com.xxx.test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LogbackTest {
	private static Logger logger = LoggerFactory.getLogger(LogbackTest.class);
	public static void main(String[] args) {	
	 logger.trace("======trace");  
        logger.debug("======debug");  
        logger.info("======info");  
        logger.warn("======warn");  
        logger.error("======error");
	}
}



Logback.xml

<?xml version="1.0" encoding="UTF-8" ?>
<configuration debug="true">
  <appender name="STDOUT">
    <!-- encoders are assigned by default the type
         ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
  </appender>
  <root level="debug">
    <appender-ref ref="STDOUT" />
  </root>
</configuration>



这个是logback的配置文件,其实不配logback.xml也是可以的,程序会自动加载一个默认BasicConfigurator的配置,最 小化 配置 由 一个 关联 到 根 logger ConsoleAppender 组成。 输出用模式为%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36}- %msg%n 的 PatternLayoutEncoder 进行格式化,根 logger 默认级别是 DEBUG
说到这里也说一下logback读取配置文件规则:,先读取logback-test.xml,没有则查找logback.xml如果也没有就加载BasicConfigurator配置。

写在最后:

jdkLog就是JUL,在项目实际中用得较少,小的项目中都是直接使用log4j或者log4j2,或都使用commons-logging再配合log4j或者log4j2。也有许多项目直接使用slf4j+logback
一般建议是使用commons-logging+log4j或者slf4j+logback吧,如果项目的其它组件充许要不直接上log4j2也是可以的。


koa-log4 管理nodeJs访问日志、系统日志

koa-log4 管理nodeJs访问日志、系统日志

使用nodeJs koa2框架开发后端应用,使用koa-log4中间件管理nodeJs访问日志、系统日志。

一、安装koa-log4

因为项目使用了koa2,所以安装的高版本的log4,

$ npm i --save koa-log4@2

如果使用koa1,请使用指令

$ npm i --save koa-log4@1

koa-log4 Npm主页

二、新建log4.js文件来配置log4

const path = require(''path'');//引入原生path模块
const log4js = require(''koa-log4'');//引入koa-log4

log4js.configure({
  appenders: {
    //访问日志
    access: {
      type: ''dateFile'',
      pattern: ''-yyyy-MM-dd.log'', //通过日期来生成文件
      alwaysIncludePattern: true, //文件名始终以日期区分
      encoding:"utf-8",
      filename: path.join(''logs/'', ''access.log'') //生成文件路径和文件名
    },
    //系统日志
    application: {
      type: ''dateFile'',
      pattern: ''-yyyy-MM-dd.log'', //通过日期来生成文件
      alwaysIncludePattern: true, //文件名始终以日期区分
      encoding:"utf-8",
      filename: path.join(''logs/'', ''application.log'') //生成文件路径和文件名
    },
    out: {
      type: ''console''
    }
  },
  categories: {
    default: { appenders: [ ''out'' ], level: ''info'' },
    access: { appenders: [ ''access'' ], level: ''info'' },
    application: { appenders: [ ''application'' ], level: ''WARN''}
  }
});

exports.accessLogger = () => log4js.koaLogger(log4js.getLogger(''access'')); //记录所有访问级别的日志
exports. systemLogger = log4js.getLogger(''application'');  //记录所有应用级别的日志

三、如何使用日志

  • 访问日志--记录用户所有访问请求,以中间件的形式在koa入口使用即可
    const Koa = require(''koa'');
    const app = new Koa();
    const {  accessLogger,systemLogger, } = require(''./logger'');
    const router = new KoaRouter();
    app.use(accessLogger()); //中间件
  • 系统日志--记录系统状态的error

       app.on(''error'', err => {logger.error(err); });
    

四、效果

clipboard.png

clipboard.png

clipboard.png

koa2学习笔记02 - 给koa2添加系统日志 —— node日志管理模块log4js

koa2学习笔记02 - 给koa2添加系统日志 —— node日志管理模块log4js

前言

没有日志系统的后台应用是没有灵魂的, 平时工作中每次我们遇到接口报错的时候, 都会叫后台的童鞋看下怎么回事, 这时后台的童鞋都会不慌不忙的打开一个骚骚的黑窗口。 一串噼里啪啦的命令输进去, 哐哐哐,一堆报错信息出现了... 不明觉厉~ so, 我们今天也为我们的应用加上日志系统。

正文

node中写日志一般都用 log4js 具体不详细介绍
请移步 https://www.npmjs.com/package/log4js 废话不多说直接上代码

1.1 安装log4js

npm install --save log4js

1.2 增加配置文件

根目录下新建config目录 conifg目录下全为配置文件 config目录下 新建文件 logs.js

var path = require(''path'');

//日志根目录
var baseLogPath = path.resolve(__dirname, ''../logs'')

/*报错输出日志*/
//错误日志目录、文件名、输出完整路径
var errorPath = "/error";
var errorFileName = "error";
var errorLogPath = baseLogPath + errorPath + "/" + errorFileName;

/*请求数据得到响应时输出响应日志*/
//响应日志目录、文件名、输出完整路径
var responsePath = "/response";
var responseFileName = "response";
var responseLogPath = baseLogPath + responsePath + "/" + responseFileName;

/*操作数据库进行增删改等敏感操作记录日志*/
//操作日志目录、文件名、输出完整路径
var handlePath = "/handle";
var handleFileName = "handle";
var handleLogPath = baseLogPath + handlePath + "/" + handleFileName;


module.exports = {
    //日志格式等设置
    appenders:
        {
            "rule-console": {"type": "console"},
            "errorLogger": {
                "type": "dateFile",
                "filename": errorLogPath,
                "pattern": "-yyyy-MM-dd-hh.log",
                "alwaysIncludePattern": true,
                "encoding": "utf-8",
                "maxLogSize": 1000,
                "numBackups": 3,
                "path": errorPath
            },
            "resLogger": {
                "type": "dateFile",
                "filename": responseLogPath,
                "pattern": "-yyyy-MM-dd-hh.log",
                "alwaysIncludePattern": true,
                "encoding": "utf-8",
                "maxLogSize": 1000,
                "numBackups": 3,
                "path": responsePath
            },
            "handleLogger": {
                "type": "dateFile",
                "filename": handleLogPath,
                "pattern": "-yyyy-MM-dd-hh.log",
                "alwaysIncludePattern": true,
                "encoding": "utf-8",
                "maxLogSize": 1000,
                "numBackups": 3,
                "path": responsePath
            },
        },
    //供外部调用的名称和对应设置定义
    categories: {
        "default": {"appenders": ["rule-console"], "level": "all"},
        "resLogger": {"appenders": ["resLogger"], "level": "info"},
        "errorLogger": {"appenders": ["errorLogger"], "level": "error"},
        "handleLogger": {"appenders": ["handleLogger"], "level": "all"},
        "http": {"appenders": ["resLogger"], "level": "info"}
    },
    "baseLogPath": baseLogPath
}

1.3 增加工具方法

新建 utils 目录, utils 目录下放置工具类方法 utils 下新建 logs.js 放置输出日志的工具方法

var log4js = require(''log4js'');
var logsConfig = require(''../config/logs.js'');
//加载配置文件
log4js.configure(logsConfig);
//调用预先定义的日志名称
var resLogger = log4js.getLogger("resLogger");
var errorLogger = log4js.getLogger("errorLogger");
var handleLogger = log4js.getLogger("handleLogger");
var consoleLogger = log4js.getLogger();

// 格式化日志文本 加上日志头尾和换行方便查看 ==>  普通日志、请求日志、响应日志、操作日志、错误日志
var formatText = {
    info: function(info) {
        var logText = new String();
        //响应日志头信息
        logText += "\n" + "***************info log start ***************" + "\n";
        //响应内容
        logText += "info detail: " + "\n" + JSON.stringify(info) + "\n";
        //响应日志结束信息
        logText += "*************** info log end ***************" + "\n";
        return logText;
    },
    request: function(req, resTime) {
        var logText = new String();
        var method = req.method;
        //访问方法
        logText += "request method: " + method + "\n";
        //请求原始地址
        logText += "request originalUrl:  " + req.originalUrl + "\n";
        //客户端ip
        logText += "request client ip:  " + req.ip + "\n";
        //开始时间
        var startTime;
        //请求参数
        if (method === ''GET'') {
            logText += "request query:  " + JSON.stringify(req.query) + "\n";
            // startTime = req.query.requestStartTime;
        } else {
            logText += "request body: " + "\n" + JSON.stringify(req.body) + "\n";
            // startTime = req.body.requestStartTime;
        }
        //服务器响应时间
        logText += "response time: " + resTime + "\n";
        return logText;
    },
    response: function(ctx, resTime) {
        var logText = new String();
        //响应日志开始
        logText += "\n" + "*************** response log start ***************" + "\n";
        //添加请求日志
        logText += formatText.request(ctx.request, resTime);
        //响应状态码
        logText += "response status: " + ctx.status + "\n";
        //响应内容
        logText += "response body: " + "\n" + JSON.stringify(ctx.body) + "\n";
        //响应日志结束
        logText += "*************** response log end ***************" + "\n";
        return logText;
    },
    handle: function(info) {
        var logText = new String();
        //响应日志开始
        logText += "\n" + "***************info log start ***************" + "\n";
        //响应内容
        logText += "handle info detail: " + "\n" + JSON.stringify(info).replace(/\\n/g, "\n") + "\n";
        //响应日志结束
        logText += "*************** info log end ***************" + "\n";
        return logText;
    },
    error: function(ctx, err, resTime) {
        var logText = new String();
        //错误信息开始
        logText += "\n" + "*************** error log start ***************" + "\n";
        //添加请求日志
        logText += formatText.request(ctx.request, resTime);
        //错误名称
        logText += "err name: " + err.name + "\n";
        //错误信息
        logText += "err message: " + err.message + "\n";
        //错误详情
        logText += "err stack: " + err.stack + "\n";
        //错误信息结束
        logText += "*************** error log end ***************" + "\n";
        return logText;
    }
}

module.exports = {
    //封装普通日志
    logInfo: function(info) {
        if (info) {
            consoleLogger.info(formatText.info(info));
        }
    },
    //封装响应日志
    logResponse: function(ctx, resTime) {
        if (ctx) {
            resLogger.info(formatText.response(ctx, resTime));
        }
    },
    //封装操作日志
    logHandle: function(res) {
        if (res) {
            handleLogger.info(formatText.handle(res));
        }
    },
    //封装错误日志
    logError: function(ctx, error, resTime) {
        if (ctx && error) {
            errorLogger.error(formatText.error(ctx, error, resTime));
        }
    }
};

1.4 改造app.js

// logger
const logsUtil = require(''./utils/logs.js'');
app.use(async (ctx, next) => {
    const start = new Date();					          // 响应开始时间
    let intervals;								              // 响应间隔时间
    try {
        await next();
        intervals = new Date() - start;
        logsUtil.logResponse(ctx, intervals);	  //记录响应日志
    } catch (error) {
        intervals = new Date() - start;
        logsUtil.logError(ctx, error, intervals);//记录异常日志
    }
})

如图: 在这里插入图片描述

1.5 运行、使用日志系统

大工告成, 运行一下项目吧, 看是否自动在根目录下创建了一个logs目录。 如下 在这里插入图片描述 目前我们现在只记录的响应日志和 错误日志。 下面演示一下 如何打印操作日志。

我们打开 routes 文件夹。 然后打开 index.js 如图所示。 在这里插入图片描述 假装我们做了这些操作。 访问 http://localhost:3000/json
看一下日志文件夹和控制台是否和下面一样?

在这里插入图片描述 在这里插入图片描述 这就是我们在utils中写的四个输出日志的方法。 如果觉得不够用还可以仿照格式继续写其他方法。

ps: .gitignore中已设置忽略上传logs文件夹,git中不可见。

log4j 日志输出到日志文件中和控制台中 +log4j 配置详解

log4j 日志输出到日志文件中和控制台中 +log4j 配置详解

1. 引入 log4j 的 jar 包

https://mvnrepository.com/,可以找到 log4j 的 jar 和依赖。

2. 创建 log4j.properties,并配置 log4j

#设置日志的级别 ,多个以,分开(没有给出的,则不会被输出)
log4j.rootLogger=debug,A,R

#
log4j.appender.logfile.encoding=UTF-8
#DailyRollingFileAppender每天产生一个日志文件
log4j.appender.R=org.apache.log4j.DailyRollingFileAppender

#设置日志文件保存路径
log4j.appender.R.File=D:/Log4j log file storage address/logFile.log  //这里的是你输出到日志文件的路径

#日志输出格式
log4j.appender.R.layout.ConversionPattern=%-d{yyyy-MM-dd HH\:mm\:ss} [%c]-[%p] %m%n

#设置日志文件后缀名,决定着多长时间创建一个新的文件!yyyyMMdd每天一个,yyyyMMddHH第小时一个,...
log4j.appender.R.DatePattern=''.''yyyy-MM-dd

#日志布局格式
log4j.appender.R.layout=org.apache.log4j.PatternLayout
#输出到控制台
log4j.appender.A=org.apache.log4j.ConsoleAppender
log4j.appender.A.layout=org.apache.log4j.PatternLayout
log4j.appender.A.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] %m%n

3. 测试 log4j

public class Test24 {
    Logger logger=Logger.getLogger(Test24.class);
    @Test
    public void log4jTest(){
    logger.error("输出输出输出bbbbbccccassssssQWEQW ");

    }

 

 

 

log4j 配置详解  https://blog.csdn.net/u011781521/article/details/55002553

关于Node.js 日志处理模块log4jsnodejs日志管理的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于Java日志相关记录 (Jul jcl log4j log4j2 Logback SLF4J)、koa-log4 管理nodeJs访问日志、系统日志、koa2学习笔记02 - 给koa2添加系统日志 —— node日志管理模块log4js、log4j 日志输出到日志文件中和控制台中 +log4j 配置详解等相关知识的信息别忘了在本站进行查找喔。

本文标签: