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 ...
随机推荐
- It's about trust
所有问题, 最后,它归结为:信任. 你能相信别人? 我不是Low esteem.相反,我有信心.问题是.我有一个别人缺乏信任的. Daria家长们说,伪君子:我们必须相信你. Daria马上问:然后, ...
- WPF中StringFormat的用法--显示特定位数的数字
原文:WPF中StringFormat的用法--显示特定位数的数字 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/huangli321456/art ...
- 从零开始学习 asp.net core 2.1 web api 后端api基础框架(二)-创建项目
原文:从零开始学习 asp.net core 2.1 web api 后端api基础框架(二)-创建项目 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.ne ...
- Android 5.0(L) ToolBar(替代ActionBar) 现实(四)
经过三天休息,我回来了,我们继续讨论Toolbar. 在此之前假设您正在步步紧跟下来的序列,然后,你应该注意到MainActivity据说他已被警告.因为他们,我们声明toolbar对象.但一直没有用 ...
- asp .net Cookies
Request.Cookies和Response.Cookies When validating cookies or cookie data from the browser you should ...
- 【转】关于在.Net开发中使用Sqlite的版本选择问题
如果一个.NET应用要自适应32位/64位系统,只需要在项目的“目标平台”设置为“Any CPU”.但是如果应用中使用了SQLite,情况就不同了. SQLite的.NET开发包来自是System.D ...
- ORM 集合
1.EF https://github.com/aspnet 2.Chloe.ORM http://www.cnblogs.com/so9527/p/5809089.html http://www ...
- HTTP、FTP状态码 汇总
原文:HTTP.FTP状态码 汇总 HTTP1xx - 信息提示(这些状态代码表示临时的响应.客户端在收到常规响应之前,应准备接收一个或多个 1xx 响应. ) • 100 - 继续.• 101 - ...
- .NET 图片像素比较
/// <summary> /// 图像比较.用于找出两副图片之间的差异位置 /// </summary> public class ImageComparer { /// & ...
- DBLINK学习
1.连接本地scott用户查看拥有的表 [oracle@ORADG ~]$ sqlplus scott/tiger SQL> select * from tab; TNAME ...