CORE
HOME > JAVA > J2SE > CORE
2020.09.21 / 10:56

ÀÚ¹Ù¿¡¼­ ·Î±×¿¡ ÁÙ ¹øÈ£¸¦ ÀμâÇÏ´Â ¹æ¹ý

XMaLL°ü¸®ÀÚ
Ãßõ ¼ö 197

ÀÚ¹Ù¿¡¼­ ·Î±×¿¡ ÁÙ ¹øÈ£¸¦ ÀμâÇÏ´Â ¹æ¹ý


ÁÙ ¹øÈ£¸¦ ·Î±×¿¡ ÀμâÇÏ´Â ¹æ¹ý ÀϺΠÁ¤º¸¸¦ ·Î±×¿¡ Ãâ·Â ÇÒ ¶§ ÇØ´ç Ãâ·ÂÀÌ ¼Ò½º Äڵ忡ÀÖ´Â ÁÙ ¹øÈ£¸¦ ÀμâÇÏ°í ½Í½À´Ï´Ù. ½ºÅà ÃßÀû¿¡¼­ º¼ ¼ö ÀÖµíÀÌ ¿¹¿Ü°¡ ¹ß»ýÇÑ ÁÙ ¹øÈ£¸¦ Ç¥½ÃÇÕ´Ï´Ù. ½ºÅà ÃßÀûÀº ¿¹¿Ü °³Ã¼¿¡¼­ »ç¿ëÇÒ ¼ö ÀÖ½À´Ï´Ù.

´Ù¸¥ ´ë¾ÈÀº ·Î±×¿¡ Àμâ ÇÒ ¶§ ÁÙ ¹øÈ£¸¦ ¼öµ¿À¸·Î Æ÷ÇÔÇÏ´Â °Í°ú °°½À´Ï´Ù. ´Ù¸¥ ¹æ¹ýÀÌ ÀÖ½À´Ï±î?


¿¡¼­ 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))

enter image description here

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 expressionstatic 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