3

每当 Apache Derby 在我们的应用程序中抛出 SQLException 时,我们的应用程序就会将 derby.log 文件的内容发送到我们的服务器。

为了获得详细的日志,我们将 'derby.infolog.append' 属性设置为 true。

但是,我们注意到日志文件非常大,因为每次连接到数据库时日志还包含启动输出。

注意:我们在嵌入式模式下使用 Derby。

有没有办法让 derby 限制它记录到 derby.log 文件的总行数?

例如,只记录最近的 1000 行日志,然后开始覆盖最旧的条目。

我们的目标是从最终用户那里获得有用的调试信息,但要防止日志文件增长到无法管理的大小。

提前致谢,

吉姆

4

3 回答 3

1

我对德比不是很熟悉,但我找不到一种“简单”的方法来做到这一点。

但是您可以设置一些 derby 属性来自己实现它。

检查这些

derby.stream.error.field

derby.stream.error.file

derby.stream.error.method

derby.stream.error.logSeverityLevel

所以我想你写一些子类java.io.OutputStreamjava.io.Writer然后你要么

  • 实现想要的行为或
  • 类似于如何限制日志文件的大小?+ 包装为上述之一或
  • 您从其他项目(RollingFileAppender log4j,RollingFileWriter clapper,...)中获得了一些关于 RollingFileLoggerClass 的想法
于 2009-10-21T08:31:59.730 回答
1

您可以创建一个自定义日志记录类,并使用上面提到的 derby.stream.error.field 指定它。日志类不必实现为文件 - 如果您要限制日志数据的大小,您可以轻松地将其保存在内存中。

这样做的第二个好处是,当遇到问题时,您可以灵活地处理日志数据。也许压缩(或加密)数据并在您的帮助系统中自动打开一张票(例如)。

这是一个非常简单的自定义日志记录解决方案的示例:

import java.io.CharArrayWriter;

public class CustomLog {

    public static CharArrayWriter log = new CharArrayWriter();

    public static void dump() {
        System.out.println(log.toString());
    }
}

您可以将 CharArrayWriter 替换为某种大小有限的缓冲区,并添加 dump() 的实现以对生成的日志数据执行您将执行的操作。

一个简短的示例程序演示了这一点:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

public class DerbyLoggingExample {

    public DerbyLoggingExample() {
        System.setProperty( "derby.stream.error.field", "CustomLog.log");

        String driver = "org.apache.derby.jdbc.EmbeddedDriver";
        String dbName = "logdemoDB";
        String connectionURL = "jdbc:derby:" + dbName + ";create=true";

        String createCommand = "create table test_table ("
            + "test_id int not null generated always as identity, "
            + "test_name varchar(20)"
            + ")";

        try {
            Class.forName(driver);
        }
        catch( java.lang.ClassNotFoundException e ) {
            System.out.println( "Could not load Derby driver." );
            return;
        }

        Connection conn = null;
        Statement statement = null;

        try {
            conn = DriverManager.getConnection(connectionURL);
            statement = conn.createStatement();

            statement.execute(createCommand);
        }
        catch( SQLException sqle ) {
            sqle.printStackTrace();
            System.out.println( "SQLException encountered. Dumping log.");
            CustomLog.dump();
            return;
        }
        finally {
            try {
                statement.close();
                conn.close();
            }
            catch( SQLException e ) {
                // Do nothing.
            }
        }

        System.out.println( "Processing done. Dumping log." );
        CustomLog.dump();
    }

    public static void main(String[] argv) {
        DerbyLoggingExample thisApp = new DerbyLoggingExample();
    }
}
于 2009-10-22T17:34:32.210 回答
0

处理此问题的另一种方法是编写您自己的代码,在 Derby 运行之间旋转、截断、压缩或以其他方式削减 derby.log 文件。

您没有提及您正在运行的 Derby 版本,但我认为在最近的版本中删除了每连接行输出。或者它只是从网络服务器输出中删除,而不是从 derby.log 输出中删除?

如果是每个连接的线路输出使您的 derby.log 膨胀,那么您可能会考虑使用连接池技术,这样您就不会建立这么多的连接。通常,您可以在应用程序的整个生命周期内保持连接;您不必经常创建和销毁它们。

如果您认为 derby.log 中有多余的不必要输出,您可以在 Derby 社区错误跟踪器中记录增强请求并附上示例,以确保 Derby 的未来版本不会记录不需要的内容。

于 2009-10-21T14:28:37.143 回答