大数据必学Java基础(一百零三): log4j日志框架

log4j日志框架

一、什么是日志log

例如:异常信息、登录成功失败的信息、其他重要操作的信息。

日志可以记录程序的运行状态,运行信息,用户的一些常用操作。日志可以帮助我们分析程序的运行状态,帮我们分析用户的操作习惯,进而对程序进行改进。

二、如何记录日志

方式1:System.out.println(.....) e.printStackTrace();

缺点:不是保存到文件,不能长久存储

方式2:IO流 将System.out.println(.....) e.printStackTrace();写入文件

缺点:操作繁琐,IO流操作容易阻塞线程,日志没有等级。日志的格式不能很好的定制,要想实行编程复杂。

方式3:使用现成的日志框架,比如log4j

优点:

  • 长久保存
  • 有等级
  • 格式可以很好的定制
  • 代码编写简单

三、 log4j日志的级别

FATAL:指出现非常严重的错误事件,这些错误可能导致应用程序异常中止。

ERROR:指虽有错误,但仍允许应用程序继续运行。

WARN:指运行环境潜藏着危害。

INFO:指报告信息,这些信息在粗粒度级别上突出显示应用程序的进程。

DEBUG:指细粒度信息事件,对于应用程序的调试是最有用的。

四、使用log4j记录日志

1、加入jar包 log4j-1.2.8.jar

2、加入属性文件 src 下 log4j.properties

log4j.rootLogger=error,logfile
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=d:/msb.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d{yyyy-MM-dd   HH:mm:ss} %l %F %p %m%n


通过属性文件理解log4j的主要API

Appender 日志目的地:ConsoleAppender FileAppender

Layout 日志格式化器 :SimpleLayout PatternLayout

3、代码中记录日志

//创建一个日志记录器
private static final Logger logger =   Logger.getLogger(DBUtil.class.getName());
 
//在合适的地方添加日志
 
logger.info("正确的读取了属性文件:"+prop);

 
logger.debug("正确的关闭了结果集");

 
logger.error("DML操作错误:"+e);


五、理解日志格式化字符的含义

%p:输出日志信息的优先级,即DEBUG,INFO,WARN,ERROR,FATAL。

%d:输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,如:%d{yyyy/MM/dd HH:mm:ss,SSS}。

%r:输出自应用程序启动到输出该log信息耗费的毫秒数。

%t:输出产生该日志事件的线程名。

%l:输出日志事件的发生位置,相当于%c.%M(%F:%L)的组合,包括类全名、方法、文件名以及在代码中的行数。例如:test.TestLog4j.main(TestLog4j.java:10)。

%c:输出日志信息所属的类目,通常就是所在类的全名。 %M:输出产生日志信息的方法名。 %F:输出日志消息产生时所在的文件名称。 %L:输出代码中的行号。 %m:输出代码中指定的具体日志信息。 %n:输出一个回车换行符,Windows平台为"rn",Unix平台为"n"。 %x:输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java servlets这样的多客户多线程的应用中。 %%:输出一个"%"字符。

六、使用log4j记录日志连接池中通过log4j记录日志

package com.lanson.dao;
import com.lanson.util.PropertiesUtil;
import org.apache.log4j.Logger;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
/**
 * @Author: Lansonli
 * @Description: MircoMessage:Mark_7001
 */
public class MyConnectionPool {
    private static String driver;
    private static String url;
    private static String user;
    private static String password;
    private static int initSize;
    private static int maxSize;
    private static Logger logger;
    private static LinkedList<Connection> pool;
    static{
        logger=Logger.getLogger(MyConnectionPool.class);
        // 初始化参数
        PropertiesUtil propertiesUtil=new PropertiesUtil("/jdbc.properties");
        driver=propertiesUtil.getProperties("driver");
        url=propertiesUtil.getProperties("url");
        user=propertiesUtil.getProperties("user");
        password=propertiesUtil.getProperties("password");
        initSize=Integer.parseInt(propertiesUtil.getProperties("initSize"));
        maxSize=Integer.parseInt(propertiesUtil.getProperties("maxSize"));
        // 加载驱动
        try {
            Class.forName(driver);
        } catch (ClassNotFoundException e) {
            logger.fatal("找不到数据库驱动类"+driver,e);
        }
        // 初始化pool
        pool=new LinkedList<Connection>();
        // 创建5个链接对象
        for (int i = 0; i <initSize ; i++) {
            Connection connection = initConnection();
            if(null != connection){
                pool.add(connection);
                logger.info("初始化连接"+connection.hashCode()+"放入连接池");
            }
        }
    }
    // 私有的初始化一个链接对象的方法
    private static Connection initConnection(){
        try {
            return DriverManager.getConnection(url,user,password);
        } catch (SQLException e) {
            logger.fatal("初始化连接异常",e);
        }
        return null;
    }
    // 共有的向外界提供链接对象的
    public static Connection getConnection(){
        Connection connection =null;
        if(pool.size()>0){
            connection= pool.removeFirst();// 移除集合中的第一个元素
            logger.info("连接池中还有连接:"+connection.hashCode());
        }else{
            connection = initConnection();
            logger.info("连接池空,创建新连接:"+connection.hashCode());
        }
        return connection;
    }
    // 共有的向连接池归还连接对象的方法
    public static void returnConnection(Connection connection){
        if(null != connection){
            try {
                if(!connection.isClosed()){
                    if(pool.size()<maxSize){
                        try {
                            connection.setAutoCommit(true);// 调整事务状态
                            logger.debug("设置连接:"+connection.hashCode()+"自动提交为true");
                        } catch (SQLException e) {
                            e.printStackTrace();
                        }
                        pool.addLast(connection);
                        logger.info("连接池未满,归还连接:"+connection.hashCode());
                    }else{
                        try {
                            connection.close();
                           logger.info("连接池满了,关闭连接:"+connection.hashCode());
                        } catch (SQLException e) {
                            e.printStackTrace();
                        }
                    }
                }else{
                   logger.info("连接:"+connection.hashCode()+"已经关闭,无需归还");
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }else{
           logger.warn("传入的连接为null,不可归还");
        }
    }
}
0 条评论
请不要发布违法违规有害信息,如发现请及时举报或反馈
还没有人评论呢,速度抢占沙发!
相关文章
  • 1. 类和对象的概念 计算机语言一般分为 面向对象 和 面向过程,Java 是一门面向对象的语言 面向过程编程,追求算法优先,相信算法能解决一切问题,先确定如果操作数据,然后再指定操作数据的步骤 面向...

  • 摘要:保证线程安全是 Java 并发编程必须要解决的重要问题,本文和大家聊聊Java中的并发原子类,看它如何确保多线程的数据一致性。 本文分享自华为云社区《学了这么久的高并发编程,连Java中的并发原...

  • JavaSE 标识符 定义 Java中用于定义名称的都是标识符。例:包名,类名,变量名,方法名等。 组成 由数字、字母、_、$、组成,可以用汉字,但是不建议。 注意 开头不可以是数字 不可以用Java...

  • 1. 性能分析工具 1.1. 必须有足够大的堆来处理数据 1.2. 运行性能分析工具时开启并发GC算法 1.3. 不合时宜的Full GC暂停会导致缓冲区的数据溢出 1.4. 性能分析的一个缺陷就是在...

  • 我是3y,一年CRUD经验用十年的markdown程序员👨🏻‍💻常年被誉为职业八股文选手 开源项目消息推送平台austin仓库地址: 消息推送平台🔥推送下发【邮件】【短信】【微信服务号】【微...

  • 作者:宁海翔1 前言对象拷贝,是我们在开发过程中,绕不开的过程,既存在于Po、Dto、Do、Vo各个表现层数据的转换,也存在于系统交互如序列化、反序列化。Java对象拷贝分为深拷贝和浅拷贝,目前常用的...

  • 1. 术语 1.1. 堆指代Java堆 1.2. 原生内存指代JVM的非堆内存 1.2.1. 包括C堆 1.2.2. 非堆内存就是原生内存 1.2.3. 一些常见的JDK类常常会使用原生内存,请确保正...

  • 作者:京东零售 陈志良 作为一名京东的软件匠人,我们开发的软件支撑着数亿的用户,责任是重大的,因此我们深深地敬畏每一行代码,那如何将我们的失误降到最低呢?那就是单元测试,它会让我们树立对代码的自信心...

  • 1. 集合工厂 1.1. Arrays.asList() 1.1.1. 创建了一个固定大小的列表 1.1.2. 列表的元素可以更新 1.1.3. 不能增加或者删除 1.1.4. 大小固定的可变数组 1...

  • 在分析PowerUsageSummary的时候,其实可以发现主要获取应用和服务电量使用情况的实现是在BatteryStatsHelper.java中 还是在线网站http://androidxref....

  • 重写的要求: 子类方法的形参列表和方法名必须和父类方法的形参列表和方法名一样 子类方法的返回类型必须是父类方法返回类型或为其子类型。例如父类方法返回类型为Object类,那么子类的返回类型可以是Ob...

  • Java新手天坑! 想写一篇新手避坑向的文章很久了,最近来到园子,终于有机会发表这篇文章了(文笔和技术都不咋地,大佬见谅,适用于刚入坑没多久的新手群体) 在java中,经过一段学习的人对数组操作应该是...

  • PDF文档是我们日常办公中使用最频繁的文档格式。但因为大多数PDF文档都包含很多页面图像或大量图片,这就导致PDF文档过大,处理起来较为麻烦。PDF文件过大,就会导致传输或者下载的速度变慢,也会增加传...

  • aliases: [JAVA Lambda] tags : " #Java " summary: [如何使用函数式编程写出优雅高效的JAVA代码] author : [yaenli] date ...

  • 1. 基本信息 Java性能权威指南(第2版) Java Performance,Second Edition [美]斯科特·奥克斯(Scott Oaks) 人民邮电出版社,2022年4月出版 1.1...

  • 概述 背景 函数式编程的理论基础是阿隆佐·丘奇(Alonzo Church)于 1930 年代提出的 λ 演算(Lambda Calculus)。λ 演算是一种形式系统,用于研究函数定义、函数应用和递...

  • 生产者消费者问题 简介 生产者消费者模式并不是GOF提出的23种设计模式之一,23种设计模式都是建立在面向对象的基础之上的,但其实面向过程的编程中也有很多高效的编程模式,生产者消费者模式便是其中之一,...

  • 1. Survivor空间 1.1. 新生代被划分为两个Survivor空间和一个Eden空间的原因 1.1.1. 刚刚被创建并且还在使用中,所以不能被回收,但它们的寿命并没有长到足以进入老年代 ...

  • 面向对象的是三大特性 封装 一.概念 将类的信息隐藏在类的内部,不允许外部程序直接访问,通过类提供的方法实现对隐藏信息的操作和访问 封装的两大原则 尽可能多的东西藏起来对外部提供一个便捷的接口 所有...

  • 需要使用的 技术 工具: idea 2022  开发工具 MySql 5.6  数据库工具 Apache Tomcat 8.5.85   web应用部署工具 主要功能有: 用户登录 用户注册 展...