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. 31 反射方式给类的属性赋值 和 对象赋值(clone)

    1.配置类 package com.da.tool.util.configuration.reflect; /** */ public class JobInfo { private String j ...

  2. H5不支持的标签

    <acronym> 定义首字母缩写. <applet>  定义applet <basefont> 定义文档中所有文本的默认颜色.大小和字体.请用CSS代替  < ...

  3. Linux 下安装 FFmpeg

    1. 下载源代码: git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg 2. 编译 ./configure --enable-shared --pre ...

  4. Eclipse传递main函数参数

    在项目上右击 Run As->Run Configurations...->Arguments->在Program arguments:的文本框中输入你要传入的参数,若有几个参数则在 ...

  5. [Linux] day02——什么是Linux

    什么是linux? 一种操作系统计算机 = 硬件 +软件系统软件 = 内核 + 驱动应用软件 编程 上网 linux系统构成linux内核基本库 应用程序-------------------常见的操 ...

  6. Wordpress综合检测和爆破工具

    WordPress是一种使用PHP语言开发的博客平台,用户可以在支持PHP和MySQL数据库的服务器上架设属于自己的网站. 也可以把 WordPress当作一个内容管理系统(CMS)来使用.WordP ...

  7. 第1节 storm编程:1、storm第一天上次课程内容回顾

    上次课程内容回顾:1.kafka的基本介绍:kafka是一个消息队列2.消息队列的作用:解耦3.kafka与传统消息队列的对比: 传统消息队列:支持事务 kafka的特点:比较快,比较快的两个原因:顺 ...

  8. Java的clone方法效率问题

    在Java中,经常会需要新建一个对象,很多情况下,需要这个新建的对象和现有的某个对象保持属性一致. 那么,就有两种方式来实现这个对象的构造: ①通过新建一个对象,为这个对象的属性根据原有对象的属性来进 ...

  9. Python 多进程 multiprocessing.Pool类详解

    Python 多进程 multiprocessing.Pool类详解 https://blog.csdn.net/SeeTheWorld518/article/details/49639651

  10. Java自动检测文件编码(字符集)

    // 使用之前请调用getAllDetectableCharsets()检查是否满足要求,中文仅有{gb18030, big5,utf-*}import com.ibm.icu.text.Charse ...