我们如何将行号打印到java中的日志中

如何将行号打印到日志中。 说输出一些信息到日志时,我也想打印输出在源代码中的行号。 正如我们在堆栈跟踪中看到的那样,它显示发生exception的行号。 堆栈跟踪在exception对象上可用。

其他的select可以像打印到日志时手动包含行号一样。 有没有其他的方法?

来自Angsuman Chakraborty :

/** Get the current line number. * @return int - Current line number. */ public static int getLineNumber() { return Thread.currentThread().getStackTrace()[2].getLineNumber(); } 

我们结束了使用这样的自定义类为我们的Android工作:

 import android.util.Log; public class DebugLog { public final static boolean DEBUG = true; public static void log(String message) { if (DEBUG) { String fullClassName = Thread.currentThread().getStackTrace()[2].getClassName(); String className = fullClassName.substring(fullClassName.lastIndexOf(".") + 1); String methodName = Thread.currentThread().getStackTrace()[2].getMethodName(); int lineNumber = Thread.currentThread().getStackTrace()[2].getLineNumber(); Log.d(className + "." + methodName + "():" + lineNumber, message); } } } 

我不得不回答你的问题。 我假设你正在寻找行号来支持debugging。 有更好的方法。 有很多方法可以获得目前的线路。 我见过的都很慢 你最好使用类似于java.util.logging包或者log4j的日志框架。 使用这些软件包,您可以configuration您的日志logging信息,以将上下文包括到类名称中。 然后每个日志消息将是唯一足以知道它来自哪里。 因此,你的代码将会有一个你通过调用的“logging器”variables

logger.debug("a really descriptive message")

代替

System.out.println("a really descriptive message")

快速和肮脏的方式:

 System.out.println("I'm in line #" + new Exception().getStackTrace()[0].getLineNumber()); 

有了更多的细节:

 StackTraceElement l = new Exception().getStackTrace()[0]; System.out.println( l.getClassName()+"/"+l.getMethodName()+":"+l.getLineNumber()); 

这将输出这样的东西:

 com.example.mytest.MyClass/myMethod:103 

Log4J允许您将行号作为其输出模式的一部分。 请参阅http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PatternLayout.html ,了解有关如何执行此操作的细节(转换模式中的关键元素是“L”)。 但是,Javadoc包含以下内容:

警告生成呼叫者位置信息非常缓慢。 这应该避免使用,除非执行速度不是问题。

由@ simon.buchan发布的代码将工作…

 Thread.currentThread().getStackTrace()[2].getLineNumber() 

但是如果你在一个方法中调用它,它将总是返回方法中的行的行号,而是使用内联的代码片段。

我用这个小方法输出调用它的方法的轨迹和行号。

  Log.d(TAG, "Where did i put this debug code again? " + Utils.lineOut()); 

双击输出以转到该源代码行!

您可能需要根据放置代码的位置来调整级别值。

 public static String lineOut() { int level = 3; StackTraceElement[] traces; traces = Thread.currentThread().getStackTrace(); return (" at " + traces[level] + " " ); } 

我会build议使用日志工具包,如log4j 。 日志logging可以在运行时通过属性文件进行configuration,您可以打开/closures诸如行号/文件名日志等function。

查看PatternLayout的javadoc, 可以获得完整的选项列表 – 你之后是%L。

你不能保证行号与代码的一致性,特别是如果编译发布。 我不build议为此目的使用行号,最好给出引发exception的地方的有效载荷(简单的方法是设置消息以包含方法调用的细节)。

你可能想看看exception丰富作为一种技术来提高exception处理http://tutorials.jenkov.com/java-exception-handling/exception-enrichment.html

如果已经编译发布,这是不可能的。 你可能想看看像Log4J这会自动给你足够的信息,以确定logging的代码发生的地方。

首先是一般的方法(在一个实用程序类中,尽pipe普通的旧的java1.4代码,你可能不得不重写它的java1.5和更多)

 /** * Returns the first "[class#method(line)]: " of the first class not equal to "StackTraceUtils" and aclass. <br /> * Allows to get past a certain class. * @param aclass class to get pass in the stack trace. If null, only try to get past StackTraceUtils. * @return "[class#method(line)]: " (never empty, because if aclass is not found, returns first class past StackTraceUtils) */ public static String getClassMethodLine(final Class aclass) { final StackTraceElement st = getCallingStackTraceElement(aclass); final String amsg = "[" + st.getClassName() + "#" + st.getMethodName() + "(" + st.getLineNumber() +")] <" + Thread.currentThread().getName() + ">: "; return amsg; } 

然后具体的实用方法来获得正确的stackElement:

 /** * Returns the first stack trace element of the first class not equal to "StackTraceUtils" or "LogUtils" and aClass. <br /> * Stored in array of the callstack. <br /> * Allows to get past a certain class. * @param aclass class to get pass in the stack trace. If null, only try to get past StackTraceUtils. * @return stackTraceElement (never null, because if aClass is not found, returns first class past StackTraceUtils) * @throws AssertionFailedException if resulting statckTrace is null (RuntimeException) */ public static StackTraceElement getCallingStackTraceElement(final Class aclass) { final Throwable t = new Throwable(); final StackTraceElement[] ste = t.getStackTrace(); int index = 1; final int limit = ste.length; StackTraceElement st = ste[index]; String className = st.getClassName(); boolean aclassfound = false; if(aclass == null) { aclassfound = true; } StackTraceElement resst = null; while(index < limit) { if(shouldExamine(className, aclass) == true) { if(resst == null) { resst = st; } if(aclassfound == true) { final StackTraceElement ast = onClassfound(aclass, className, st); if(ast != null) { resst = ast; break; } } else { if(aclass != null && aclass.getName().equals(className) == true) { aclassfound = true; } } } index = index + 1; st = ste[index]; className = st.getClassName(); } if(isNull(resst)) { throw new AssertionFailedException(StackTraceUtils.getClassMethodLine() + " null argument:" + "stack trace should null"); //$NON-NLS-1$ } return resst; } static private boolean shouldExamine(String className, Class aclass) { final boolean res = StackTraceUtils.class.getName().equals(className) == false && (className.endsWith(LOG_UTILS ) == false || (aclass !=null && aclass.getName().endsWith(LOG_UTILS))); return res; } static private StackTraceElement onClassfound(Class aclass, String className, StackTraceElement st) { StackTraceElement resst = null; if(aclass != null && aclass.getName().equals(className) == false) { resst = st; } if(aclass == null) { resst = st; } return resst; } 

这里是我们使用的logging器。

它围绕Android日志logging器,并显示类名称,方法名称和行号。

http://www.hautelooktech.com/2011/08/15/android-logging/

看看这个链接 。 在这种方法中,当你双击LogCat的行时,你可以跳转到你的行代码。

您也可以使用此代码来获取行号:

 public static int getLineNumber() { int lineNumber = 0; StackTraceElement[] stackTraceElement = Thread.currentThread() .getStackTrace(); int currentIndex = -1; for (int i = 0; i < stackTraceElement.length; i++) { if (stackTraceElement[i].getMethodName().compareTo("getLineNumber") == 0) { currentIndex = i + 1; break; } } lineNumber = stackTraceElement[currentIndex].getLineNumber(); return lineNumber; } 
 private static final int CLIENT_CODE_STACK_INDEX; static { // Finds out the index of "this code" in the returned stack Trace - funny but it differs in JDK 1.5 and 1.6 int i = 0; for (StackTraceElement ste : Thread.currentThread().getStackTrace()) { i++; if (ste.getClassName().equals(Trace.class.getName())) { break; } } CLIENT_CODE_STACK_INDEX = i; } private String methodName() { StackTraceElement ste=Thread.currentThread().getStackTrace()[CLIENT_CODE_STACK_INDEX+1]; return ste.getMethodName()+":"+ste.getLineNumber(); } 

这些都可以帮助您获得当前线程和方法的行号,如果您在预期发生exception的情况下使用try catch,则这些行号和方法非常有用。 但是如果你想捕获任何未处理的exception,那么你正在使用默认的未捕获exception处理程序,当前线程将返回处理程序函数的行号,而不是抛出exception的类方法。 而不是使用Thread.currentThread()只需使用由exception处理程序传入的Throwable:

 Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { public void uncaughtException(Thread t, Throwable e) { if(fShowUncaughtMessage(e,t)) System.exit(1); } }); 

在上面的处理函数(fShowUncaughtMessage)中使用e.getStackTrace()[0]来获得罪犯。

下面的代码是testing代码的日志行没有类名称和方法的名称从调用日志方法

 public class Utils { /* * debug variable enables/disables all log messages to logcat * Useful to disable prior to app store submission */ public static final boolean debug = true; /* * l method used to log passed string and returns the * calling file as the tag, method and line number prior * to the string's message */ public static void l(String s) { if (debug) { String[] msg = trace(Thread.currentThread().getStackTrace(), 3); Log.i(msg[0], msg[1] + s); } else { return; } } /* * l (tag, string) * used to pass logging messages as normal but can be disabled * when debug == false */ public static void l(String t, String s) { if (debug) { Log.i(t, s); } else { return; } } /* * trace * Gathers the calling file, method, and line from the stack * returns a string array with element 0 as file name and * element 1 as method[line] */ public static String[] trace(final StackTraceElement e[], final int level) { if (e != null && e.length >= level) { final StackTraceElement s = e[level]; if (s != null) { return new String[] { e[level].getFileName(), e[level].getMethodName() + "[" + e[level].getLineNumber() + "]" };} } return null; } } 

我的方式对我有用

 String str = "select os.name from os where os.idos="+nameid; try { PreparedStatement stmt = conn.prepareStatement(str); ResultSet rs = stmt.executeQuery(); if (rs.next()) { a = rs.getString("os.n1ame");//<<<----Here is the ERROR } stmt.close(); } catch (SQLException e) { System.out.println("error line : " + e.getStackTrace()[2].getLineNumber()); return a; } 

你可以使用 – > Reporter.log(“”);