Web基础之日志

  日志在企业开发中有着不可或缺的作用,它可以用以记录用户操作、系统运行状态和错误信息。日志记录的好坏直接关系到系统出现问题时定位的速度。

  最开始的日志一般使用log4j,后来sun公司心有不甘,在jdk 1.4中加入了一个叫java.util.logging的日志包,简称jul。两种日志的api肯定是不同的,此时日志就出现了混乱。log4j的作者Ceki Gülcü就写了一个叫Jakarta Commons Logging的接口,简称jcl,来共同管理log4j和jul,并且jcl中提供了一个日志实现simplelog。接着又改良了下log4j,写出了logback。再后来Ceki Gülcü觉得jcl不好用(的确用问题),然后写了一个新的接口slf4j,来共同管理这些日志系统。接着呢Ceki Gülcü又觉得logj4性能不够了,又写了一个log4j2,。真是专注日志100年啊。

  所以他们之间的关系是这样的:

  其中slf4j并不提供日志实现,而是使用外观模式创建了一个接口,来统一这些日志的api。

  这也是为什么阿里规范上强制使用slf4j的原因:

【强制】应用中不可直接使用日志系统(Log4j、Logback)中的 API,而应依赖使用日志框架SLF4J 中的 API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

private static final Logger logger = LoggerFactory.getLogger(Test.class);

slf4j + log4j / log4j2

  认识了之后接下来就是使用了,首先在maven中导入依赖:

<!-- log4j依赖,好像不更新了,我看版本还是12年的 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- slf4j的依赖 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.28</version>
</dependency>
<!-- 告诉slf4j使用log4j,也就是绑定 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.28</version>
<scope>test</scope>
</dependency>

  如果使用log4j2的话这么配:

<!-- log4j2的核心 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.12.1</version>
</dependency>
<!-- log4j2的api -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.12.1</version>
</dependency>
<!-- slf4j绑定log4j2 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.12.1</version>
</dependency>
<!-- slf4j的依赖 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.28</version>
</dependency>

  这里我将使用log4j2的xml和properties两种方式来简单配置。


  在resources目录下创建log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<!-- 输出源的配置:日志输出的目的地 -->
<Appenders>
<!--
Console标签;指定这是一个控制台输出源。
name:名称,需要在被引用才会生效
target: 控制台字体的颜色
SYSTEM_ERR:红色字体
SYSTEM_OUT:黑色字体
PatternLayout:布局,输出到控制台日志的格式。
-->
<Console name="myConsole" target="SYSTEM_ERR">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %5level %logger{36} - %msg%n"/>
</Console> <!-- 文件输出源
fileName:指定保存日志的文件的名字和位置。
一般写绝对路径。
-->
<File name="myFile" fileName="D://demo.log">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
</PatternLayout>
</File> <!--
多文件输出源:
fileName:实时记录日志的文件名和位置
filePattern : 文件封存的位置和格式
-->
<RollingFile name="rollingFile" fileName="D://demo2.log" filePattern="D://logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
</PatternLayout>
<!-- 多文件拆分的规则 -->
<Policies>
<!-- 基于时间的 此处interval属性值的单位是由filePattern属性中文件名时间精确的单位 决定的。 -->
<TimeBasedTriggeringPolicy interval="1" />
<!-- 基于文件大小的 -->
<SizeBasedTriggeringPolicy size="512 MB"/>
</Policies>
</RollingFile> </Appenders>
<Loggers>
<!-- 配置日志输出的级别的
将当前级别以及比当前级别高的消息进行输出。
-->
<Root level="trace">
<AppenderRef ref="myConsole"/>
<!-- 可以同时多种方式输出日志 -->
<AppenderRef ref="MyFile"/>
<AppenderRef ref="RollingFile"/> </Root>
</Loggers>
</Configuration>

  log4j使用properties方式:

# 配置输出源的   log4j.appender.输出源名=输出源的实现类
# 属性的配置 log4j.appender.输出源名.属性名=属性值
log4j.appender.a=org.apache.log4j.ConsoleAppender
log4j.appender.a.Target=System.out
log4j.appender.a.layout=org.apache.log4j.PatternLayout
log4j.appender.a.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c]-[%p] %m%n log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=D:/mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c]-[%p] %m%n ### log4j.rootLogger=输出级别,输出源1,输出源2....
log4j.rootLogger=debug,a,file

log4j2的properties(参考):

status = warn
name = MyApp appender.console.type = Console
appender.console.name = consoleLogDemo
appender.console.filter.threshold.type = ThresholdFilter
appender.console.filter.threshold.level = debug
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %m%n
appender.console.target = System_out appender.rolling.type = File
appender.rolling.name = fileLogDemo
appender.rolling.filter.threshold.type = ThresholdFilter
appender.rolling.filter.threshold.level = error
appender.rolling.layout.type = PatternLayout
appender.rolling.layout.pattern = %d-%m%n
appender.rolling.append = true
appender.rolling.fileName = e:\\propertiesTest.log rootLogger.level = debug
rootLogger.appenderRef.consolelogdemo.ref = consoleLogDemo
rootLogger.appenderRef.filelogdemo.ref = fileLogDemo

输出格式参数为:

%p:输出日志信息的优先级,即DEBUG,INFO,WARN,ERROR,FATAL
%d:输出日志时间点的日期或时间,默认格式为ISO8601,可以指定格式如:%d{yyyy/MM/dd HH:mm:ss,SSS}
%r:输出自应用程序启动到输出该log信息耗费的毫秒数
%t:输出产生该日志事件的线程名
%l:输出日志事件的发生位置,相当于%c.%M(%F:%L)的组合,包括类全名、方法、文件名以及在代码中的行数
%c:输出日志信息所属的类目,通常就是类全名
%M:输出产生日志信息的方法名
%F:输出日志消息产生时所在的文件名
%L:输出代码中的行号
%m:输出代码中指定的具体日志信息
%n:输出一个回车换行符,Windows平台为"rn",Unix平台为"n"
%x:输出和当前线程相关联的NDC(嵌套诊断环境)
%%:输出一个"%"字符

  这是几种常用的配置,如果觉得不够的话可以查看官方文档

  顺便这里推荐个讲的很详细的博客

打日志

在log4j2中可以这么用:

public class MyApp {
private static final Logger logger = LoggerFactory.getLogger(MyApp.class); public static void main(String[] args) {
logger.warn("Hello, {}","slf4j");
}
}

使用{}作为占位符,性能要比log4j直接字符串拼接性能好(毕竟字符串拼接的底层原理是创建StringBuilder)


至于一大堆jar包的关系如下:



关于log4j2的如下:

参考关于slf4j log4j log4j2的jar包配合使用的那些事

Web基础之日志的更多相关文章

  1. 20145215《网络对抗》Exp8 Web基础

    20145215<网络对抗>Exp8 Web基础 基础问题回答 什么是表单? 表单是一个包含表单元素的区域,表单元素是允许用户在表单中(比如:文本域.下拉列表.单选框.复选框等等)输入信息 ...

  2. 20155201 网络攻防技术 实验八 Web基础

    20155201 网络攻防技术 实验八 Web基础 一.实践内容 Web前端HTML,能正常安装.启停Apache.理解HTML,理解表单,理解GET与POST方法,编写一个含有表单的HTML. We ...

  3. 20155202《网络对抗》Exp8 Web基础

    20155202<网络对抗>Exp8 Web基础 基础问题回答 什么是表单? 表单是一个包含表单元素的区域,表单元素是允许用户在表单中(比如:文本域.下拉列表.单选框.复选框等等)输入信息 ...

  4. 2017-2018 Exp8 Web基础 20155214

    目录 Exp8 Web基础 实验内容 建站过程 SQL注入 知识点 Exp8 Web基础 实验内容 实验环境 主机 Kali 靶机 Kali 实验工具 后台语言 'PHP' 服务器 'Apache' ...

  5. 20155318 《网络攻防》 Exp9 Web基础

    20155318 <网络攻防> Exp9 Web基础 基础问题 SQL注入攻击原理,如何防御 就是通过把SQL命令插入到"Web表单递交"或"输入域名&quo ...

  6. 20145220韩旭飞《网络对抗》Exp8 Web基础

    20145220韩旭飞<网络对抗>Exp8 Web基础 Web前端:HTML基础 首先,我们的Web开发是基于Apache服务器进行的,所以对于Apache的基本操作我们是应该要掌握的,对 ...

  7. Nginx web基础入门

    目录 Nginx web基础入门 如何升级nginx或者添加功能 使用systemd管理nginx nginx相关配置文件 nginx的配置文件详解 日志格式 game日志记录实战 日志切割 手写虚拟 ...

  8. 2018-2019-2 《网络对抗技术》Exp8 Web基础 20165326

    Web基础 实验要求 本实践的要求: Web前端HTML,能正常安装.启停Apache.理解HTML,理解表单,理解GET与POST方法,编写一个含有表单的HTML. Web前端javascipt.理 ...

  9. Web基础之http协议

    第6章 Web基础之http协议 第6章 Web基础之http协议一.http协议介绍 1.1)什么是超文本 1.2)什么是URL 1.3)什么是超文本传输协议二.访问网站分析三.页面请求信息解析(仅 ...

随机推荐

  1. Jsp和Servlet关系

    为什么会出现Jsp? 其实对于服务器来说它只认识Servlet,我们完全可以在Servlet用resp.getWriter().write("");画出网页的界面,但是仅仅一个很简 ...

  2. Servlet简单的登陆窗口

    web.xml配置: jsp代码: 注意:action书写的是为这次登陆做处理类的别名,method就是请求的方式 Get请求方式没有请求实体 //如果只是看效果就光写一下service方法就行了 p ...

  3. 你知道Verilog HDL程序是如何构成的吗

    本节通过硬件描述语言Verilog HDL对二十进制编码器的描述,介绍Verilog HDL程序的基本结构及特点. 二十进制编码器及Verilog HDL描述 二十进制编码器是数字电路中常用的电路单元 ...

  4. Ideone:在线多语言编程执行器工具

    Ideone:在线多语言编程执行器工具此网站提供40种编程语言以上, 能在线直接做编译和执行的动作,该工具是一款简易的编程测试工具,虽然不能替代专业版的工具,但是其功能非常全面. Ideone,一款在 ...

  5. Random Variables

    可测空间(Measurable Space)和测度空间(Measure Space) 集合X,X上的一个σ-algebra A,则(X,A)被称为可测空间(measurable space) 再在A上 ...

  6. Windows驱动开发-IRP结构体

    IRP的全名是I/O Request Package,即输入输出请求包,它是Windows内核中的一种非常重要的数据结构. 上层应用程序与底层驱动程序通信时,应用程序会发出I/O请求,操作系统将相应的 ...

  7. Day2-O-Coloring a Tree CodeForces-902B

    You are given a rooted tree with n vertices. The vertices are numbered from 1 to n, the root is the ...

  8. Python入门知识总结【新手必学】

    Python 基础学习输入和输出list 和 tuple条件判断循环dict 和 set感觉python这门语言用途较广,先熟悉下其语法.PS:另外很多人在学习Python的过程中,往往因为没有好的教 ...

  9. 073、Java面向对象之利用构造方法为属性赋值

    01.代码如下: package TIANPAN; class Book { // 定义一个新的类 private String title; // 书的名字 private double price ...

  10. 7.2 Varnish 模式