2013-10-26 27 views
0

我正在爲Java編寫自己的日誌記錄Handler,我想將日誌消息的行號插入到我的輸出中。獲取日誌處理程序中的行號

這是我沒有行號當前的嘗試:

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 + ")"); 
} 

回答

1

沒有的LogRecord(JDK1.4 - JDK1。 7)方法獲取行號。如果處理程序或上游中沒有發生線程切換,則可以創建新的Throwable().getStackTrace()並使用java.lang.StackTraceElement API獲取線路號。

示例代碼可以在JavaMail API中的MailLogger.inferCaller()/isLoggerImplFrame()中找到。如果您必須處理線程切換,則必須將行號記錄爲日誌記錄參數。請記住,在性能方面計算callsite是很昂貴的。

0

你可以使用此代碼是:

StackTraceElement e = Thread.currentThread().getStackTrace()[2]; 
e.getLineNumber(); 
+0

謝謝您的回答,但與指數兩幀不記錄該消息的類。我認爲這是因爲我使用[SLF4J](http://www.slf4j.org/)。 –

+0

然後嘗試使用3;) – kelunik

相關問題