spring boot使用log4j2将日志写入mysql数据库
log4j2官方例子在spring boot中报错而且还是用的是org.apache.commons.dbcp包
我给改了一下使用org.apache.commons.dbcp2包
1.log4j2.xml如下:
- <?xml version="1.0" encoding="UTF-8"?>
- <Configuration status="error">
- <Appenders>
- <Console name="Console" target="SYSTEM_OUT">
- <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
- </Console>
- <JDBC name="DBLogger" tableName="MicroServiceLogHandle">
- <ConnectionFactory class="com.malls.common.tool.LogConnectionFactory"
- method="getDatabaseConnection" />
- <Column name="RequestKey" pattern="${sd:RequestKey}" />
- <Column name="LogType" pattern="${sd:LogType}" />
- <Column name="RequestUrl" pattern="${sd:RequestUrl}" />
- <Column name="UserName" pattern="${sd:UserName}" />
- <Column name="OrderNo" pattern="${sd:OrderNo}" />
- <Column name="Content" pattern="${sd:Content}" />
- <Column name="Keyword" pattern="${sd:Keyword}" />
- <Column name="ClientIP" pattern="${sd:ClientIP}" />
- <Column name="TimeLong" pattern="${sd:TimeLong}" />
- <Column name="LogTime" pattern="${sd:LogTime}" />
- <Column name="DBCreateTime" literal="now()" />
- <Column name="ServerDesc" pattern="${sd:ServerDesc}" />
- <Column name="LogLevel" pattern="${sd:LogLevel}" />
- <Column name="RequestServerIP" pattern="${sd:RequestServerIP}" />
- <Column name="ServerIP" pattern="${sd:ServerIP}" />
- <Column name="CurrentApiRequestKey" pattern="${sd:CurrentApiRequestKey}" />
- </JDBC>
- </Appenders>
- <Loggers>
- <AsyncLogger name="AsyncDBLogger" level="debug"
- includeLocation="true">
- <AppenderRef ref="DBLogger" />
- </AsyncLogger>
- <Root level="info">
- <AppenderRef ref="Console" />
- </Root>
- </Loggers>
- </Configuration>
- AsyncLogger 表示是异步插入.需要在pom.xml中插入disruptor引用
- <dependency>
- <groupId>com.lmax</groupId>
- <artifactId>disruptor</artifactId><!-- log4j异步插入用到 -->
- <version>3.4.1</version>
- </dependency>
2.创建LogConnectionFactory类:
- package com.malls.common.tool;
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.sql.SQLException;
- import java.util.concurrent.locks.Lock;
- import java.util.concurrent.locks.ReentrantLock;
- import javax.sql.DataSource;
- import org.apache.commons.dbcp2.ConnectionFactory;
- import org.apache.commons.dbcp2.DriverManagerConnectionFactory;
- import org.apache.commons.dbcp2.PoolableConnection;
- import org.apache.commons.dbcp2.PoolableConnectionFactory;
- import org.apache.commons.dbcp2.PoolingDataSource;
- import org.apache.commons.pool2.ObjectPool;
- import org.apache.commons.pool2.impl.GenericObjectPool;
- import com.malls.common.model.DBConfig;
- public class LogConnectionFactory {
- private static interface Singleton {
- final LogConnectionFactory INSTANCE = new LogConnectionFactory();
- }
- private DataSource dataSource;
- private LogConnectionFactory() {
- }
- private void initDataSource() {
- try {
- //
- // First, we'll create a ConnectionFactory that the
- // pool will use to create Connections.
- // We'll use the DriverManagerConnectionFactory,
- // using the connect string passed in the command line
- // arguments.
- DBConfig dbConfig = ApplicationConfig.GetDbConfig("dblog");
- ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(dbConfig.getUrl(),
- dbConfig.getUserName(), dbConfig.getPassword());
- //
- // Next we'll create the PoolableConnectionFactory, which wraps
- // the "real" Connections created by the ConnectionFactory with
- // the classes that implement the pooling functionality.
- //
- PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory,
- null);
- //
- // Now we'll need a ObjectPool that serves as the
- // actual pool of connections.
- //
- // We'll use a GenericObjectPool instance, although
- // any ObjectPool implementation will suffice.
- //
- ObjectPool<PoolableConnection> connectionPool = new GenericObjectPool<>(poolableConnectionFactory);
- // Set the factory's pool property to the owning pool
- poolableConnectionFactory.setPool(connectionPool);
- //
- // Finally, we create the PoolingDriver itself,
- // passing in the object pool we created.
- //
- dataSource = new PoolingDataSource<>(connectionPool);
- } catch (Exception e) {
- // TODO 自动生成的 catch 块
- e.printStackTrace();
- dataSource = null;
- }
- }
- int i = 0;
- private static Lock lock = new ReentrantLock();
- public static Connection getDatabaseConnection() throws SQLException {
- if (Singleton.INSTANCE.i == 0) {
- //这儿如果第一次直接返回连接池的话会报错
- //因为PoolableConnectionFactory也使用了log4j记录日志
- //这儿是重点
- Singleton.INSTANCE.i++;
- DBConfig dbConfig = ApplicationConfig.GetDbConfig("dblog");
- return DriverManager.getConnection(dbConfig.getUrl(), dbConfig.getUserName(), dbConfig.getPassword());
- }
- if (Singleton.INSTANCE.dataSource == null) {
- lock.lock();
- try {
- if (Singleton.INSTANCE.dataSource == null) {
- Singleton.INSTANCE.initDataSource();
- }
- } finally {
- lock.unlock();
- }
- }
- return Singleton.INSTANCE.dataSource.getConnection();
- }
- }
要注意注释的地方,第二次才返回连接池
3.创建DBLog类:
- package com.malls.common.tool;
- import java.time.Duration;
- import java.time.LocalDateTime;
- import java.util.UUID;
- import org.apache.logging.log4j.LogManager;
- import org.apache.logging.log4j.Logger;
- import org.apache.logging.log4j.message.StructuredDataMessage;
- import org.springframework.web.context.request.RequestAttributes;
- import org.springframework.web.context.request.RequestContextHolder;
- import com.malls.common.model.RequestModel;
- public class DBLog {
- private static final Logger LOGGER = LogManager.getLogger("AsyncDBLogger");
- public static void process(String logType, String content) {
- process(logType, content, "");
- }
- public static void process(String logType, String content, String keyWord) {
- StructuredDataMessage msg = getataMessage(logType, content, keyWord);
- addMsg(msg, "logLevel", "Process");
- LOGGER.info(msg);
- }
- public static void error(String logType, String content) {
- error(logType, content, "");
- }
- public static void error(String logType, String content, String keyWord) {
- StructuredDataMessage msg = getataMessage(logType, content, keyWord);
- addMsg(msg, "logLevel", "Error");
- LOGGER.error(msg);
- }
- public static void handle(String logType, String content) {
- handle(logType, content, "");
- }
- public static void handle(String logType, String content, String keyWord) {
- StructuredDataMessage msg = getataMessage(logType, content, keyWord);
- addMsg(msg, "LogLevel", "Handle");
- LOGGER.info(msg);
- }
- private static StructuredDataMessage getataMessage(String logType, String content, String keyWord) {
- String confirm = UUID.randomUUID().toString().replace("-", "");
- StructuredDataMessage msg = new StructuredDataMessage(confirm, "", "transfer");
- RequestAttributes req = RequestContextHolder.currentRequestAttributes();
- RequestModel requestModel = null;
- if (req != null) {
- requestModel = (RequestModel) req.getAttribute("RequestModel", RequestAttributes.SCOPE_REQUEST);
- }
- if (requestModel == null) {
- requestModel = new RequestModel();
- }
- addMsg(msg, "RequestKey", requestModel.getRequestKey());
- addMsg(msg, "RequestUrl", requestModel.getRequestUrl());
- addMsg(msg, "UserName", String.valueOf(requestModel.getCurrentUserId()));
- addMsg(msg, "OrderNo", requestModel.getOrderNo());
- addMsg(msg, "LogType", logType);
- addMsg(msg, "Content", content);
- addMsg(msg, "Keyword", keyWord);
- addMsg(msg, "ClientIP", requestModel.getClientIP());
- long timeLong = Duration.between(requestModel.getBeginRequestTime(), LocalDateTime.now()).toMillis();
- addMsg(msg, "TimeLong", String.valueOf(timeLong));
- addMsg(msg, "ServerDesc", "777");
- addMsg(msg, "RequestServerIP", requestModel.getRequestServerIP());
- addMsg(msg, "ServerIP", requestModel.getServerIP());
- addMsg(msg, "CurrentApiRequestKey", requestModel.getCurrentApiRequestKey());
- addMsg(msg, "LogTime", LocalDateTime.now().toString());
- return msg;
- }
- private static void addMsg(StructuredDataMessage msg, String key, String val) {
- if (val == null) {
- msg.put(key, "");
- } else {
- msg.put(key, val);
- }
- }
- }
这样就可以了.
spring boot使用log4j2将日志写入mysql数据库的更多相关文章
- Spring Boot入门(2)使用MySQL数据库
介绍 本文将介绍如何在Spring项目中连接.处理MySQL数据库. 该项目使用Spring Data JPA和Hibernate来连接.处理MySQL数据库,当然,这仅仅是其中一种方式,你也 ...
- Spring Boot项目中使用jdbctemplate 操作MYSQL数据库
不废话,先来代码 pom文件: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http ...
- Spring Boot系列一:默认日志logback配置解析
前言 今天来介绍下Spring Boot如何配置日志logback,我刚学习的时候,是带着下面几个问题来查资料的,你呢 如何引入日志? 日志输出格式以及输出方式如何配置? 代码中如何使用? 正文 Sp ...
- Spring Boot 学习摘要--关于日志框架
date: 2020-01-05 16:20:00 updated: 2020-01-08 15:50:00 Spring Boot 学习摘要--关于日志框架 学习教程来自:B站 尚硅谷 1. 关于日 ...
- spring boot使用slf4j输出日志
spring boot使用slf4j输出日志 https://blog.csdn.net/qq442270636/article/details/79406346 Spring Boot SLF4J日 ...
- Spring Boot Logback几种日志详解
日志对于应用程序来说是非常重要的,Spring框架本身集成了不少其他工具,我们自身的应用也会使用到第三方库,所以我们推荐在Spring应用中使用SLF4J/Logback来记录日志. SLF4J与Lo ...
- Spring Boot中使用logback日志框架
说明:Spring Boot在最新的版本中默认使用了logback框架.一般来说使用时只需在classpath下创建logback.xml即可,而官方推荐使用logback-spring.xml替代, ...
- Spring boot使用log4j打印日志
先将maven中spring-boot-starter的日志spring-boot-starter-logging去掉 <dependency> <groupId>org.sp ...
- spring boot配置druid连接池连接mysql
Spring Boot 集成教程 Spring Boot 介绍 Spring Boot 开发环境搭建(Eclipse) Spring Boot Hello World (restful接口)例子 sp ...
随机推荐
- HTML精确定位:scrollLeft,scrollWidth,clientWidth,offsetWidth完全详细的说明
HTML:scrollLeft,scrollWidth,clientWidth,offsetWidth具体指完全解释究竟哪里的距离scrollHeight: 获取对象的高度滚动. scrollLe ...
- nyoj 92 图片实用面积【bfs】
图像实用区域 时间限制:3000 ms | 内存限制:65535 KB 难度:4 描写叙述 "ACKing"同学曾经做一个图像处理的项目时.遇到了一个问题,他须要摘取出图片中某 ...
- Swift 中使用 SwiftyJSON 制作一个比特币价格 APP
Swift 中处理 JSON 数据有很多种方式,可以使用原生的 NSJSONSerialization,也可以使用很多第三方库.原生的 NSJSONSerialization 方式这篇文章中介绍过.这 ...
- Angular升级流程
执行命令 ng update @angular/cli --migrate-only --from=1.7.1 npm install --save-dev @angular/cli@latest 注 ...
- WPF4.0用tablet实现手写输入(更新XP SP3下也能手写输入方法)
原文:WPF4.0用tablet实现手写输入(更新XP SP3下也能手写输入方法) 由于项目需求一个手写输入的控件,纠结了2天,终于搞定了. 主要是由于本人的英语不过关,一直和ocr混淆在一起,研究了 ...
- Redis进阶实践之十八 使用管道模式提高Redis查询的速度
原文:Redis进阶实践之十八 使用管道模式提高Redis查询的速度 一.引言 学习redis 也有一段时间了,该接触的也差不多了.后来有一天,以为同事问我,如何向redis中 ...
- Win8 Metro(C#)数字图像处理--2.61哈哈镜效果
原文:Win8 Metro(C#)数字图像处理--2.61哈哈镜效果 [函数名称] 哈哈镜效果函数 WriteableBitmap DistortingMirrorProcess(Writea ...
- ArcGIS中Python逆地理编码,根据坐标获取实际的地址
import json import urllib import arcpy def getAddress(lng,lat): url= 'http://restapi.amap.com/v3/geo ...
- Windows实用小工具-问题步骤记录器
今晚给大家介绍个实用的好工具,可以做简单的问题记录,再也不用截图加注释这么辛苦了····· 经测试,这东东在win7,2008 及2008R2里适用,也就是说,在win7以上的系统中才有.好了,下面直 ...
- Android零基础入门第43节:ListView优化和列表首尾使用
原文:Android零基础入门第43节:ListView优化和列表首尾使用 前面连续几期都在学习ListView的各种使用方法,如果细心的同学可能会发现其运行效率是有待提高的,那么本期就来一起学习有哪 ...