java 로그로 행 번호를 인쇄하려면 어떻게 해야 합니까?
로그에 행 번호를 인쇄하는 방법.예를 들어, 로그에 정보를 출력할 때 소스 코드에서 해당 출력이 있는 라인 번호도 출력하고 싶습니다.스택 트레이스에서 알 수 있듯이 예외가 발생한 회선 번호가 표시됩니다.스택 트레이스는 예외 개체에서 사용할 수 있습니다.
또, 로그에 인쇄할 때에 행 번호를 수동으로 추가하는 방법도 있습니다.다른 방법은 없습니까?
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);
}
}
}
빠르고 더러운 방법:
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 패키지 또는 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이 게시한 코드입니다.부찬이가...
Thread.currentThread().getStackTrace()[2].getLineNumber()
그러나 메서드로 호출하면 메서드 내의 회선 번호가 항상 반환되므로 코드 스니펫을 인라인으로 사용합니다.
log4j 등의 로깅 툴킷 사용을 권장합니다.런타임에 속성 파일을 통해 로깅을 구성할 수 있으며 줄 번호/파일 이름 로깅 등의 기능을 켜거나 끌 수 있습니다.
PatternLayout용 javadoc을 보면 전체 옵션 목록이 나타납니다. 원하는 옵션은 %L입니다.
호출한 메서드의 트레이스와 회선 번호를 출력하는 이 작은 메서드를 사용합니다.
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] + " " );
}
특히 릴리스용으로 컴파일된 경우 코드와의 라인 번호 일관성을 보장할 수 없습니다.이 목적으로 회선 번호를 사용하는 것은 권장하지 않습니다.예외가 발생한 장소의 payload를 지정하는 것이 좋습니다(메시지 호출의 상세 내용을 포함하도록 메시지를 설정하는 간단한 방법입니다).
예외 처리를 개선하기 위한 기술로 예외 강화를 검토할 수 있습니다.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;
}
여기 우리가 사용하는 로거가 있습니다.
Android Logger와 디스플레이 클래스 이름, 메서드 이름 및 라인 번호를 둘러싼다.
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();
}
이 모든 기능을 통해 현재 스레드 및 메서드의 라인 번호를 얻을 수 있습니다.이러한 번호는 예외가 예상되는 트라이 캐치를 사용하는 경우 매우 효과적입니다.그러나 처리되지 않은 예외를 탐지할 경우 기본 수집되지 않은 예외 핸들러를 사용하고 있으며 현재 스레드는 예외를 발생시킨 클래스 메서드가 아닌 핸들러 함수의 행 번호를 반환합니다.Thread.current를 사용하는 대신Thread()는 예외 핸들러에 의해 전달된 Throwable을 사용합니다.
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
if(fShowUncaughtMessage(e,t))
System.exit(1);
}
});
위에서는 핸들러 함수(fShowUncaughtMessage)에서 e.getStackTrace()[0]를 사용하여 위반자를 가져옵니다.
다음 코드는 line no class name 및 메서드 이름을 로깅 메서드가 호출되는 테스트 코드입니다.
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;
}
}
stackLevel
이 방법이라고 부르는 깊이에 따라 달라집니다.0부터 큰 숫자까지 시도하면 어떤 차이가 있는지 확인할 수 있습니다.
ifstackLevel
법적음음, 음음음음음음음 like like, 음음 like like like like like like like like like like like 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);
}
이것이 바로 제가 이 lib XDDLib에 실장했던 기능입니다.(단, 안드로이드용입니다)
Lg.d("int array:", intArrayOf(1, 2, 3), "int list:", listOf(4, 5, 6))
밑줄 친 텍스트를 한 번 클릭하면 log 명령어가 있는 곳으로 이동합니다.
★★★StackTraceElement
는 이 라이브러리 외부의 첫 번째 요소에 의해 결정됩니다.이의 장소에서는, 「lib」, 「lib」, 「lib」, 「lib」를 한 모든 입니다.lambda expression
,static initialization block
등등.
, 금の inの 。getStackTrace()[3]
method는 실행 행을 제외한 실제 .getStackTrace() 메서드까지 트리거 행이 이동하는 스레드의 양을 나타냅니다.
, 이 경우, 이 경우,Thread.currentThread().getStackTrace()[X].getLineNumber();
행은 위의 세 개의 중첩된 메서드에서 실행되며, 인덱스 번호는 3이어야 합니다.
예제:
제1층
private static String message(String TAG, String msg) {
int lineNumber = Thread.currentThread().getStackTrace()[3].getLineNumber();
return ".(" + TAG + ".java:"+ lineNumber +")" + " " + msg;
}
제2층
private static void print(String s) {
System.out.println(s);
}
제3층
public static void normal(
String TAG,
String message
) {
print(
message(
TAG,
message
)
);
}
행 실행 중:
Print.normal(TAG, "StatelessDispatcher");
IT에 관한 정식 교육을 받은 적이 없는 사람으로서 컴파일러의 동작에 대한 첫걸음이었습니다.
이것은 회선 번호를 인쇄하는 코드입니다.
Thread.currentThread().getStackTrace()[2].getLineNumber()
글로벌 퍼블릭 스태틱 메서드를 생성하여 로그를 보다 쉽게 인쇄할 수 있습니다.
public static void Loge(Context context, String strMessage, int strLineNumber) {
Log.e(context.getClass().getSimpleName(), strLineNumber + " : " + strMessage);
}
내 방식대로 작동한다
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("")를 사용할 수 있습니다.
언급URL : https://stackoverflow.com/questions/115008/how-can-we-print-line-numbers-to-the-log-in-java
'programing' 카테고리의 다른 글
라라벨에서 마리아와 천천히 많은 관계를 맺는다.DB (0) | 2022.09.04 |
---|---|
Java String에서 토큰 세트를 바꾸려면 어떻게 해야 합니까? (0) | 2022.09.04 |
매니페스트 사용Java의 MF 파일 (0) | 2022.09.04 |
Java 8 비교기 유형 추론에 매우 혼란스럽다. (0) | 2022.09.04 |
클래스의 모든 변수 이름 가져오기 (0) | 2022.09.04 |