java - 获取日志处理程序中的行号

标签 java java.util.logging

我正在编写自己的日志 Handler对于 Java,我想将日志消息的行号插入到我的输出中。

这是我当前的尝试,没有行号:

public class ConsoleHandler extends Handler {

    private static final String SEVERE = "SEVERE";

    private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

    @Override
    public void publish(LogRecord record) {
        StringBuilder output = new StringBuilder();

        // Add time and location of the message
        Date d = new Date(record.getMillis());
        String time = new SimpleDateFormat(DATE_TIME_FORMAT).format(d);

        output.append(time + ": " + record.getSourceClassName() + "."
                + record.getSourceMethodName() + "\t\t\t");

        output.append(record.getLevel() + ": " + record.getMessage());

        switch (record.getLevel().getName()) {
        case SEVERE:
            System.err.println(output);
            break;
        default:
            System.out.println(output);
        }
    }
    public void flush() {}
    public void close() throws SecurityException {}
}

我搜索了LogRecord的界面但无法找出消息记录在哪一行。

编辑: 我改编了 jmehrens 答案中链接的代码;此方法返回日志记录类的堆栈帧,从中我可以获取行号和文件名:

private StackTraceElement getCallerStackFrame(final String callerName) {
    StackTraceElement callerFrame = null;

    final StackTraceElement stack[] = new Throwable().getStackTrace();
    // Search the stack trace to find the calling class
    for (int i = 0; i < stack.length; i++) {
        final StackTraceElement frame = stack[i];
        if (callerName.equals(frame.getClassName())) {
            callerFrame = frame;
            break;
        }
    }

    return callerFrame;
}

用法:

final StackTraceElement callerFrame = getCallerStackFrame(record.getSourceClassName());

if (callerFrame != null) {
    final String fileName = callerFrame.getFileName();
    final int lineNumber = callerFrame.getLineNumber();
    // This creates a link to the line when used in Eclipse
    output.append("(" + fileName + ":" + lineNumber + ")");
}

最佳答案

没有 LogRecord (JDK1.4 - JDK1.7) 方法来获取行号。如果您的处理程序或上游没有发生线程切换,您可以创建一个新的 Throwable().getStackTrace()并使用 java.lang.StackTraceElement获取行号的API。

示例代码可以在 JavaMail API 中找到 MailLogger.inferCaller()/isLoggerImplFrame() 。如果您必须处理线程切换,那么您必须将行号记录为日志记录参数。请记住,计算调用站点在性能方面的成本很高。

关于java - 获取日志处理程序中的行号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19610228/

相关文章:

Java 小程序 : How to make sure destroy is finished before page refresh

web-applications - 如何在Weblogic中显示Java.Util Logger输出?

java - 未显示字符串列表

Java Swing Object[][] getData() 混淆

java - 如果您有一个 String 并且枚举没有 getSomething(String str) 方法,那么如何查找枚举值?

java - 为什么 Log4J (jul) 尝试对来自供应商的字符串消息进行 MessageFormat

java - 是否可以以编程方式覆盖 java.util.logging 属性文件中设置的值?

java - 与 lucene 索引一起使用的最佳跨语言分析器

java - 将平面集合映射到层次结构的最佳方法

java - 从属性文件配置记录器