如何将来自不同用户的日志附加到 SQLite table 中的同一文本文件?

How to append logs from different users to the same text file in a SQLite table?

我使用 log4j2 是为了有一个审计跟踪文件,用于存储用户执行的每个操作的日志。

所有这些用户都连接到 SQLite 数据库 table。目前,我所有的日志都存储在一个 audit.log 文件中,但我希望它存储在数据库中,以便每个用户的日志都附加到同一个 audit.log 文件中。

我的log4j2.xml如下(与官方log4j站点简单fileAppender示例基本一致):

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <File name="auditFile" fileName="logs/audit.log">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
    </File>


  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="auditFile"/>
    </Root>
    <Root level="info">
      <AppenderRef ref="auditFile"/>
    </Root>
  </Loggers>
</Configuration>

我成功了。因此,我当前的 log4j2.xml 没有发生任何相关变化,但这里是:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <File name="auditFile" fileName="./audit.log">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
    </File>

  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="auditFile"/>
    </Root>
    <Root level="info">
      <AppenderRef ref="auditFile"/>
    </Root>
  </Loggers>
</Configuration>

为了让它工作,这是我为我的应用程序编写的代码(为了记录,我只调用 saveLog(String context) 方法):

public void saveLog(String context) throws ClassNotFoundException, IOException {
        Class.forName(classForName);
        Connection connection = null;
        logger.info(context);

        try
        {
          // create a database connection
          connection = DriverManager.getConnection(connectionPath); 
          //connectionPath is the path to my database

          Statement statement = connection.createStatement();
          statement.setQueryTimeout(30);  // set timeout to 30 sec.

          File file = new File("audit.log"); 
          FileInputStream fis = new FileInputStream(file);

          PreparedStatement ps = connection.prepareStatement("UPDATE OR REPLACE shell SET audit=? WHERE name='shell.txt'"); 
          //shell is the name of my sqlite table

          ps.setBinaryStream(1, fis, (int)file.length());

          ps.executeUpdate();
          ps.close();
          fis.close();


          System.out.println("SQL save done");
        }
    catch(SQLException e)
    {
      // if the error message is "out of memory", 
      // it probably means no database file is found
      System.err.println(e.getMessage());
    }
    finally
    {
      try
      {
        if(connection != null)
          connection.close();
      }

      catch(SQLException e)
      {
        // connection close failed.
        System.err.println(e);
      }
    }
}

每次我加载我的应用程序时,这是我用来确保每个用户都在使用相同 audit.log 文件的代码:

public void loadLog() throws ClassNotFoundException, SQLException, IOException {

        Class.forName(classForName);
        Connection conn = DriverManager.getConnection(connectionPath);

        String sql = "SELECT audit FROM shell";

        PreparedStatement stmt = conn.prepareStatement(sql);
        ResultSet resultSet = stmt.executeQuery();

        while (resultSet.next()) {
          File audit = new File(fileOutputPath2);
          FileOutputStream fos = new FileOutputStream(audit);

          byte[] buffer = new byte[1];
          InputStream is = resultSet.getBinaryStream(1);

          while (is.read(buffer) > 0) {
            fos.write(buffer);
          }
          fos.close();
        }
        conn.close();

        System.out.println("SQL Load Done");
    }