log4j2日志记录到oracle数据库

log4j2日志记录到oracle数据库

1、下载包:jdk1.7 版本用比较老的

commons-dhcp-1.4.jar:https://dlcdn.apache.org//commons/dbcp/binaries/commons-dbcp-1.4-bin.zip

commons-pool-1.6.jar:https://dlcdn.apache.org//commons/pool/binaries/commons-pool-1.6-bin.zip

官网:

https://logging.apache.org/log4j/2.x/manual/appenders.html#JDBCAppender

2、添加到项目中

 

 

 

3.准备连接工厂:ConnectionFactory

package com.lm.tech.schedulejob.logs;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Map;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
import org.apache.commons.dbcp.PoolableConnection;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.PoolingDataSource;
import org.apache.commons.pool.impl.GenericObjectPool;

import cn.hutool.core.codec.Base64;

import com.lm.tech.schedulejob.utils.YWDBUtils;//数据库的连接类,
/**
 * 日志的连接池
 * @author DH03
 *
 */
public class ConnectionFactory {
   private static interface Singleton {
       final ConnectionFactory INSTANCE = new ConnectionFactory();
  }

   private DataSource dataSource;

   private ConnectionFactory() {
  try{
       Properties properties = new Properties();
       
       Map<String, String> map=YWDBUtils.getLogDBMap();//获取配置项的map
       properties.setProperty("user", map.get("user"));
       properties.setProperty("password", Base64.decodeStr(map.get("pwd"))); // or get properties from some configuration file

       GenericObjectPool<PoolableConnection> pool = new GenericObjectPool<PoolableConnection>();
       DriverManagerConnectionFactory connectionFactory = new DriverManagerConnectionFactory(
      YWDBUtils.getLogDBUrl(),//获取配置项的的url
               properties
      );
       new PoolableConnectionFactory(
               connectionFactory, pool, null, "SELECT 1", 3, false, false, Connection.TRANSACTION_READ_COMMITTED
      );

       this.dataSource = new PoolingDataSource(pool);
  }catch(Exception e){
  e.printStackTrace();
           this.dataSource = null;

  }
  }

   public static Connection getDatabaseConnection() throws SQLException {
 
       return Singleton.INSTANCE.dataSource.getConnection();
  }
}
package com.lm.tech.schedulejob.utils;

import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;

import com.teamcenter.rac.aifrcp.AIFUtility;
import com.teamcenter.rac.kernel.TCSession;
import com.teamcenter.rac.util.Registry;

import cn.hutool.core.codec.Base64;
import cn.hutool.db.Db;
import cn.hutool.db.DbUtil;
import cn.hutool.db.Entity;
import cn.hutool.db.Session;
import cn.hutool.db.ds.simple.SimpleDataSource;
import cn.hutool.db.handler.EntityListHandler;
import cn.hutool.db.sql.SqlExecutor;
/**
* 数据库连接类
* @author zyq
*
*/
public class YWDBUtils {

public static SimpleDataSource ds=null;
static Db db=null;
static Connection conn=null;

public static  Map<String, String>  getLogDBMap(){
TCSession tcsession = (TCSession) AIFUtility.getDefaultSession();
String[] values = tcsession.getPreferenceService().getStringArray(0,"cust_db_info");
Map<String, String> map=new HashMap<String, String>();
for (String str : values) {
int indexOf = str.indexOf("=");
map.put(str.substring(0,indexOf), str.substring(indexOf+1));
}
return map;
}
public static String  getLogDBUrl(){
TCSession tcsession = (TCSession) AIFUtility.getDefaultSession();
String[] values = tcsession.getPreferenceService().getStringArray(0,"cust_db_info");
Map<String, String> map=new HashMap<String, String>();
for (String str : values) {
int indexOf = str.indexOf("=");
map.put(str.substring(0,indexOf), str.substring(indexOf+1));
}
//避免ORACEL RAC连接错误
String url="jdbc:oracle:thin:@"
+ "(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)"
+ "(HOST = "+map.get("ip")+")(PORT = 1521))"
+ "(LOAD_BALANCE = yes)(FAILOVER = yes)"
+ "(CONNECT_DATA =(SERVER = DEDICATED)"
+ "(SERVICE_NAME = "+map.get("sid")+")"
+ "(FAILOVER_MODE=(TYPE = SELECT)"
+ "(METHOD = BASIC)"
+ "(RETIRES = 180)"
+ "(DELAY = 15))))";
//StaticTools.log.debug(url);不要加日志输出,这里日志还没有构建
return url;
}
/***
* 获取ds数据源 首选项名称为 cust_db_info pwd 是通过base64加密的字符串
*/
public static void connectDB() {
if(ds==null) {
TCSession tcsession = (TCSession) AIFUtility.getDefaultSession();
String[] values = tcsession.getPreferenceService().getStringArray(0,"cust_db_info");
Map<String, String> map=new HashMap<String, String>();
for (String str : values) {
int indexOf = str.indexOf("=");
map.put(str.substring(0,indexOf), str.substring(indexOf+1));
}
//避免ORACEL RAC连接错误
String url="jdbc:oracle:thin:@"
+ "(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)"
+ "(HOST = "+map.get("ip")+")(PORT = 1521))"
+ "(LOAD_BALANCE = yes)(FAILOVER = yes)"
+ "(CONNECT_DATA =(SERVER = DEDICATED)"
+ "(SERVICE_NAME = "+map.get("sid")+")"
+ "(FAILOVER_MODE=(TYPE = SELECT)"
+ "(METHOD = BASIC)"
+ "(RETIRES = 180)"
+ "(DELAY = 15))))";
StaticTools.log.debug(url);
ds = new SimpleDataSource(url,map.get("user"), Base64.decodeStr(map.get("pwd")));

}
}
//获取db
public static Db getDb() {
if (db==null) {
db=new Db(YWDBUtils.ds);
}
return db;
}
//获取connection
public static Connection getConnection() {
try {
if (conn==null||conn.isClosed()) {
conn=ds.getConnection();
}
} catch (SQLException e) {
StaticTools.log.error(e);
}
return conn;
}
//关闭db
public static void closeDB() {
closeConnection();
if(ds!=null)
try {
ds.close();
} catch (IOException e) {
StaticTools.log.error(e);
}
}
//关闭connection
public static void closeConnection() {
try {
if (conn!=null||!conn.isClosed()) {
conn.close();
}
} catch (SQLException e) {
StaticTools.log.error(e);
}
}


}

4.log4j2的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Properties>
<property name="log_level" value="debug" />
<Property name="log_dir" value="$${env:TMP}/tech/logs" />
<property name="log_pattern"
value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%p] - [%t] %logger - %m%n" />
<property name="file_name" value="test" />
<property name="every_file_size" value="100 MB" />
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="${log_pattern}" />
</Console>
<RollingFile name="RollingFile"
filename="${log_dir}/${file_name}.log"
filepattern="${log_dir}/$${date:yyyy-MM}/${file_name}-%d{yyyy-MM-dd}-%i.log">
<ThresholdFilter level="DEBUG" onMatch="ACCEPT"
onMismatch="DENY" />
<PatternLayout pattern="${log_pattern}" />
<Policies>
<SizeBasedTriggeringPolicy
size="${every_file_size}" />
<TimeBasedTriggeringPolicy modulate="true"
interval="1" />
</Policies>
<DefaultRolloverStrategy max="20" />
</RollingFile>

<RollingFile name="RollingFileErr"
fileName="${log_dir}/${file_name}-warnerr.log"
filePattern="${log_dir}/$${date:yyyy-MM}/${file_name}-%d{yyyy-MM-dd}-warnerr-%i.log">
<ThresholdFilter level="WARN" onMatch="ACCEPT"
onMismatch="DENY" />
<PatternLayout pattern="${log_pattern}" />
<Policies>
<SizeBasedTriggeringPolicy
size="${every_file_size}" />
<TimeBasedTriggeringPolicy modulate="true"
interval="1" />
</Policies>
</RollingFile>
   <JDBC name="databaseAppender" tableName="CUST.APPLICATION_LOG">
     <ConnectionFactory class="com.lm.tech.schedulejob.logs.ConnectionFactory" method="getDatabaseConnection" />
     <Column name="EVENT_ID" literal="CUST.APPLICATION_LOG_SEQUENCE.NEXTVAL" />
     <Column name="EVENT_DATE" isEventTimestamp="true" />
     <Column name="LOG_LEVEL" pattern="%level" />
     <Column name="LOGGER" pattern="%logger" />
     <Column name="MESSAGE" pattern="%message" />
     <Column name="THROWABLE" pattern="%ex{full}" />
   </JDBC>
</Appenders>
<Loggers>
<Root level="${log_level}">
<AppenderRef ref="Console" />
<AppenderRef ref="RollingFile" />
<appender-ref ref="RollingFileErr" />
<appender-ref ref="databaseAppender"/>
</Root>
</Loggers>
</Configuration>

5.创建日志表

-- Create table
create table APPLICATION_LOG
(
event_id   VARCHAR2(128),
event_date DATE,
log_level VARCHAR2(32),
logger     VARCHAR2(32),
message   VARCHAR2(512),
throwable VARCHAR2(512)
)
tablespace IDATA
pctfree 10
initrans 1
maxtrans 255
 storage
 (
  initial 64K
   next 1M
  minextents 1
  maxextents unlimited
 );

 

[2021-11-28 10:10:26.947] [DEBUG] - [pool-2-thread-3] com.lm.tech.schedulejob.utils.StaticTools - 任务:分发任务1:ScheduleDisJobRunnable1开始执行 [2021-11-28 10:10:26.947] [DEBUG] - [pool-2-thread-3] com.lm.tech.schedulejob.utils.StaticTools - 任务:分发任务1:ScheduleDisJobRunnable1完成 [2021-11-28 10:10:26.947] [DEBUG] - [pool-2-thread-3] com.lm.tech.schedulejob.utils.StaticTools - 任务:设计文件分发任务:ScheduleDocDisJobRunnable开始执行 [2021-11-28 10:10:26.947] [DEBUG] - [pool-2-thread-10] com.lm.tech.schedulejob.utils.StaticTools - 任务:工艺审查分发任务:ScheduleTechWfDisJobRunnable开始执行 [2021-11-28 10:10:26.962] [DEBUG] - [pool-2-thread-3] com.lm.tech.schedulejob.utils.StaticTools - 开始处理发布流程:sCcuTAEhw5CDP_410_1的文件分发 [2021-11-28 10:10:26.979] [DEBUG] - [pool-2-thread-3] com.lm.tech.schedulejob.utils.StaticTools - 调用kostech的包,执行分发gOqF5m0i4rVVWC的版本分发 [2021-11-28 10:10:26.979] [DEBUG] - [pool-2-thread-10] com.lm.tech.schedulejob.utils.StaticTools - 开始处理:sCcuTAEhw5CDP_410_1工艺会签流程

 

posted @   张永全-PLM顾问  阅读(255)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示