자바에서 로그에 줄 번호를 인쇄하는 방법
줄 번호를 로그에 인쇄하는 방법 일부 정보를 로그에 출력 할 때 해당 출력이 소스 코드에있는 줄 번호를 인쇄하고 싶습니다. 스택 추적에서 볼 수 있듯이 예외가 발생한 줄 번호를 표시합니다. 스택 추적은 예외 개체에서 사용할 수 있습니다.
다른 대안은 로그에 인쇄 할 때 줄 번호를 수동으로 포함하는 것과 같습니다. 다른 방법이 있습니까?
에서
Angsuman 차크라보티 :
/** 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);
}
}
}
빠르고 더러운 방법 :
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
나는 당신의 질문에 대답하지 않으면 서 대답해야합니다. 디버깅을 지원하기 위해 줄 번호를 찾고 있다고 가정합니다. 더 좋은 방법이 있습니다. 현재 줄을 얻는 방법이 있습니다. 내가 본 것은 느리다. java.util.logging package 또는 log4j 와 같은 로깅 프레임 워크를 사용하는 것이 좋습니다 . 이 패키지를 사용하면 클래스 이름에 대한 컨텍스트를 포함하도록 로깅 정보를 구성 할 수 있습니다. 그런 다음 각 로그 메시지는 그 출처를 알 수있을만큼 고유합니다. 결과적으로 코드에는 '로거'변수가 있습니다.
logger.debug("a really descriptive message")
대신에
System.out.println("a really descriptive message")
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] + " " );
}
log4j 와 같은 로깅 툴킷을 사용하는 것이 좋습니다 . 런타임시 속성 파일을 통해 로깅을 구성 할 수 있으며 줄 번호 / 파일 이름 로깅과 같은 기능을 설정 / 해제 할 수 있습니다.
PatternLayout 에 대한 javadoc을 살펴보면 옵션의 전체 목록을 볼 수 있습니다. 다음은 % L입니다.
특히 릴리스 용으로 컴파일 된 경우 코드와 줄 번호 일관성을 보장 할 수 없습니다. 어쨌든 그 목적으로 줄 번호를 사용하지 않는 것이 좋습니다. 예외가 발생한 장소의 페이로드를 제공하는 것이 좋습니다 (메소드 메소드는 메시지를 메소드 호출의 세부 사항을 포함하도록 설정하는 것이 좋습니다).
예외 처리 향상을위한 기술로 예외 강화를보고 싶을 수도 있습니다. http://tutorials.jenkov.com/java-exception-handling/exception-enrichment.html
릴리스 용으로 컴파일 된 경우 불가능합니다. Log4J와 같은 것을 살펴보고 로그 된 코드가 발생한 위치를 정확하게 결정할 수있는 충분한 정보를 자동으로 제공 할 수 있습니다.
먼저 일반적인 방법 (유틸리티 클래스, 일반 오래된 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;
}
우리가 사용하는 로거는 다음과 같습니다.
그것은 안드로이드 로거를 감싸고 클래스 이름, 메소드 이름 및 줄 번호를 표시합니다.
http://www.hautelooktech.com/2011/08/15/android-logging/
Look at this link. In that method you can jump to your line code, when you double click on LogCat's row.
Also you can use this code to get line number:
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();
}
These all get you the line numbers of your current thread and method which work great if you use a try catch where you are expecting an exception. But if you want to catch any unhandled exception then you are using the default uncaught exception handler and current thread will return the line number of the handler function, not the class method that threw the exception. Instead of using Thread.currentThread() simply use the Throwable passed in by the exception handler:
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
if(fShowUncaughtMessage(e,t))
System.exit(1);
}
});
In the above use e.getStackTrace()[0] in your handler function (fShowUncaughtMessage) to get the offender.
Below code is tested code for logging line no class name and method name from where logging method is called
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;
}
}
The stackLevel
depends on depth you call this method. You can try from 0 to a large number to see what difference.
If stackLevel
is legal, you will get string like java.lang.Thread.getStackTrace(Thread.java:1536)
public static String getCodeLocationInfo(int stackLevel) {
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
if (stackLevel < 0 || stackLevel >= stackTraceElements.length) {
return "Stack Level Out Of StackTrace Bounds";
}
StackTraceElement stackTraceElement = stackTraceElements[stackLevel];
String fullClassName = stackTraceElement.getClassName();
String methodName = stackTraceElement.getMethodName();
String fileName = stackTraceElement.getFileName();
int lineNumber = stackTraceElement.getLineNumber();
return String.format("%s.%s(%s:%s)", fullClassName, methodName, fileName, lineNumber);
}
This is exactly the feature I implemented in this lib XDDLib. (But, it's for android)
Lg.d("int array:", intArrayOf(1, 2, 3), "int list:", listOf(4, 5, 6))
One click on the underlined text to navigate to where the log command is
That StackTraceElement
is determined by the first element outside this library. Thus, anywhere outside this lib will be legal, including lambda expression
, static initialization block
, etc.
My way it works for me
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;
}
you can use -> Reporter.log("");
참고URL : https://stackoverflow.com/questions/115008/how-can-we-print-line-numbers-to-the-log-in-java
'programing tip' 카테고리의 다른 글
Firebase 앱에 공동 작업자를 추가하는 방법 (0) | 2020.07.03 |
---|---|
아파치 가상 호스트 구성을 디버깅하는 방법? (0) | 2020.07.03 |
Spring Security를 사용한 단위 테스트 (0) | 2020.07.03 |
TypeScript 주석의 구문은 어디에 기록되어 있습니까? (0) | 2020.07.03 |
.NET에서 매핑 및 축소 (0) | 2020.07.03 |