有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java从相同jarfile的多个实例记录到一个数据库,但使用log4j2跟踪哪个实例记录了什么

我有三个SpringBootJAR实例,它们都需要使用log4j2登录到一个mysql数据库。那些罐子一模一样。每个jar在启动时加载一个外部配置文件,以便为三个实例中的每个实例获取不同的服务名称

现在,我希望能够以某种方式分离数据库中不同实例的日志条目。到目前为止,我确实尝试:

  1. 根据外部配置文件登录到不同的表
    似乎我需要绕过log4japi,直接使用log4j核心功能。危险
  2. 记录到一个表,但有一列分隔它们
    如何跨线程和所有使用的外部包执行此操作?我查看了标记,但似乎我必须进入每一条线并设置标记。它感觉不是进入每个依赖项并将其添加到代码中的正确方法

对我来说,到目前为止还没有任何结果。我遗漏了什么/有什么想法吗


共 (1) 个答案

  1. # 1 楼答案

    对于方法1。(不同的表)我得到了以下解决方案(几乎)运行

    最终在手册中找到了正确的部分: Log4j2 Manual - Programmatically Modifying the Current Configuration after Initialization

    当我完成数据库appender的编程配置时,将表名更改为log为serverConfig.getName()。我们注意到单一数据库可能不是我们的最佳方法。但我想分享我得到的代码。可悲的是,我无法投入更多的时间,因此这仍然未经测试:/

    DatabaseLoggerAppender.java
    public class DatabaseLogAppender {
    
        @Autowired
        private ServerConfig serverConfig;
    
        public void addDatabaseAppender(Level level) {
            final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
            final Configuration config = ctx.getConfiguration();
    
            ColumnConfig[] columnConfigs = {
                    ColumnConfig.createColumnConfig(config, "EVENT_DATE", null, null, "true", null, null),
                    ColumnConfig.createColumnConfig(config, "LEVEL", "%level", null, null, null, null),
                    ColumnConfig.createColumnConfig(config, "LOGGER", "%logger", null, null, null, null),
                    ColumnConfig.createColumnConfig(config, "THREAD", "%thread", null, null, null, null),
                    ColumnConfig.createColumnConfig(config, "MESSAGE", "%message", null, null, null, null),
                    ColumnConfig.createColumnConfig(config, "THROWABLE", "%xEx{full}", null, null, null, null)
            };
            Appender appender = JdbcAppender.createAppender("databaseAppender", "false", null, ConnectionFactory.Singleton.INSTANCE, "4000", serverConfig.getName(), columnConfigs);
            appender.start();
            config.addAppender(appender);
            config.getRootLogger().addAppender(appender, Level.DEBUG, null);
            ctx.updateLoggers();
        }
    }
    
    
    
    ConnectionFactory.java
    public class ConnectionFactory implements ConnectionSource {
        static interface Singleton {
            final ConnectionFactory INSTANCE = new ConnectionFactory();
        }
    
        private final DataSource dataSource;
    
        private ConnectionFactory() {
            Properties properties = new Properties();
            properties.setProperty("user", "root");
            properties.setProperty("password", "1Systech2"); // or get properties from some configuration file
    
            GenericObjectPool<PoolableConnection> pool = new GenericObjectPool<PoolableConnection>();
            DriverManagerConnectionFactory connectionFactory = new DriverManagerConnectionFactory(
                    "jdbc:mysql://192.168.209.236:3306/logs?serverTimezone=Europe/Berlin", properties
            );
            new PoolableConnectionFactory(
                    connectionFactory, pool, null, "SELECT 1", 3, false, false, Connection.TRANSACTION_READ_COMMITTED
            );
    
            this.dataSource = new PoolingDataSource(pool);
        }
    
        /**
         * This should return a new connection every time it is called.
         *
         * @return the SQL connection object.
         * @throws SQLException if a database error occurs.
         */
        @Override
        public Connection getConnection() throws SQLException {
            return Singleton.INSTANCE.dataSource.getConnection();
        }
    }