हम जावा में लॉग करने के लिए लाइन नंबर कैसे प्रिंट कर सकते हैं


133

लॉग में लाइन नंबर कैसे प्रिंट करें। यह कहें कि लॉग में कुछ जानकारी देते समय, मैं उस लाइन नंबर को भी प्रिंट करना चाहता हूं, जहां वह आउटपुट सोर्स कोड में है। जैसा कि हम स्टैक ट्रेस में देख सकते हैं, यह लाइन नंबर प्रदर्शित करता है जहां अपवाद हुआ है। स्टैक ट्रेस अपवाद ऑब्जेक्ट पर उपलब्ध है।

अन्य विकल्प मैन्युअल रूप से लॉग इन करते समय लाइन नंबर सहित हो सकते हैं। क्या कोई और तरीका है?


4
एक छोटे और मीठे वन-लाइनर के लिए नीचे @ जुआन का अविकसित उत्तर देखें! मैंने अभी 15 अंक दिए हैं जो सभी अन्य उत्तरों को नीचा दिखा रहा है: v और अपवॉटिंग जुआन के
नेक्रोमन्ट

जवाबों:


102

से Angsuman चक्रवर्ती :

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

5
यह हमेशा कॉल विधि में रिटर्न स्टेटमेंट की लाइन नंबर को लौटाएगा और जरूरी नहीं कि मेथड कॉल की लाइन नंबर ही हो।
रॉन टफिन

क्या GetLineNumber () के ऊपर [2] फ्रेम नहीं मिलता है? ([1] getLineNumber (), और [0] getStackTrace (), संभवतया)
साइमन बुकान

1
मैं एक बिट के आसपास खेला जाता है और यदि आप blah.getStackTrace [3] .getLineNumber () का उपयोग करते हैं, तो विधि बॉडी के रूप में यह उस पंक्ति संख्या को लौटा देती है, जहाँ विधि को बुलाया गया था।
रॉन टफिन

12
जेवीएम संस्करण के आधार पर सूचकांक बदल जाएगा। मेरा मानना ​​है कि यह 1.4 से 1.5 में बदल गया।
एड थॉमस

2
अरे @SimonBuchan, आदमी का एक नाम है :) मैंने वह लेख बहुत पहले लिखा था।
अंग्सुमन चक्रवर्ती

74

हमने अपने एंड्रॉइड काम के लिए इस तरह एक कस्टम वर्ग का उपयोग किया:

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

1
हाय माइकल, आपके समाधान के लिए धन्यवाद, यह मेरे लिए लॉग इन जानकारी के लिए लाइन नंबर प्रदर्शित करने के लिए ठीक काम कर रहा है .... फिर से धन्यवाद। मैं Android में आपके महान समाधानों की प्रतीक्षा कर रहा हूं।
सतीश

3
मैं इस कोड का उपयोग करने से पहले कुछ और शोध करूँगा - जब मैंने कोड पोस्ट किया, getStackTrace () [3] ने काम किया। यह एंड्रॉइड या जेवीएम, या किसी अन्य कारक के संस्करण पर निर्भर हो सकता है।
माइकल बाल्टाकस

3
यह उत्तर काम नहीं करता है यह लाइन नं और वर्ग का नाम दिखाता है और डिबग्लोग वर्ग का फ़ंक्शन नाम अन्य वर्ग के कॉलर की पंक्ति नहीं है
राहुल

@ राहुल इसके getStackTrace()[3]बजाय होना चाहिएgetStackTrace()[2]
user5480949

@ user5480949: JVM की परवाह किए बिना, अपने कॉलिंग फ़ंक्शन के लिए एक सुसंगत इंडेक्स प्राप्त करने के लिए "नए थ्रॉलेबल ()। getStackTrace ()" का उपयोग करें। (थ्रेड.ट्रैकट्र्रेड के बजाय ()। getStackTrace ())
ल्यूक ब्लूम

36

त्वरित और गंदा तरीका:

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

1
System.out.println("i am here: " + new Exception().getStackTrace()[0]);मुझे सभी विवरण मुझे देने की आवश्यकता है :)
necromancer

ध्यान दें कि JVM को स्टैकट्रेस देने की गारंटी नहीं है जहां यह सही है। मुझे विश्वास नहीं है कि हॉटस्पॉट या तो गारंटी देता है (लेकिन इसके स्टैकट्रैक्स सामान्य रूप से सही होते हैं)।
थोर्बोजर्न रेवन एंडरसन

बहुत साफ, वर्ग StackTraceElement l = नया अपवाद ()। getStackTrace () [1]; मेरे साथ काम करें
vuhung3990

@ ThorbjørnRavnAndersen: JVM की परवाह किए बिना, अपने कॉलिंग फ़ंक्शन के लिए एक सुसंगत इंडेक्स प्राप्त करने के लिए "नए थ्रॉलेबल ()। GetStackTrace ()" का उपयोग करें। (थ्रेड.कोर्ट्रेड्रेड () की जगह। getStackTrace ())
लुक ब्लूम

@LucBloom पुराने दिनों में आपको गारंटी नहीं थी कि स्टैक ट्रेस सटीक था।
थोरबजोरन रावन एंडरसन

25

मैं आपके सवाल का जवाब न देकर जवाब देने के लिए मजबूर हूं। मैं मान रहा हूं कि आप डिबगिंग का समर्थन करने के लिए पूरी तरह से लाइन नंबर की तलाश कर रहे हैं। बेहतर तरीके हैं। वर्तमान लाइन को प्राप्त करने के लिए हैकिंग तरीके हैं। मैंने देखा है कि सभी धीमे हैं। आप java.util.log पैकेज या log4j जैसे लॉगिंग फ्रेमवर्क का उपयोग करने से बेहतर हैं । इन पैकेजों का उपयोग करके आप अपने लॉगिंग जानकारी को वर्ग नाम के नीचे संदर्भ शामिल करने के लिए कॉन्फ़िगर कर सकते हैं। फिर प्रत्येक लॉग संदेश यह जानने के लिए पर्याप्त होगा कि वह कहां से आया है। परिणामस्वरूप, आपके कोड में एक 'लकड़हारा' चर होगा जिसे आप कॉल करते हैं

logger.debug("a really descriptive message")

के बजाय

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


15

Log4J आपको इसके आउटपुट पैटर्न के भाग के रूप में लाइन नंबर को शामिल करने की अनुमति देता है। यह कैसे करें (रूपांतरण पैटर्न में प्रमुख तत्व "L") के विवरण के लिए http://log.apache.org/log4j/1.2/apidocs/org/apache/log4j/PatternLayout.html देखें । हालाँकि, Javadoc में निम्नलिखित शामिल हैं:

चेतावनी उत्पन्न करने वाले स्थान की जानकारी बेहद धीमी है। इसका उपयोग तब तक किया जाना चाहिए जब तक निष्पादन की गति एक मुद्दा नहीं है।


जेवीएम के हाल के संस्करणों में अंतर्निहित तंत्र बहुत तेज हो गया है, लेकिन इसे अभी भी संयम से इस्तेमाल किया जाना चाहिए।
थोर्बोजर्न रेवन एंडरसन

7

@ Simon.buchan द्वारा पोस्ट किया गया कोड काम करेगा ...

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

लेकिन अगर आप इसे एक विधि में कहते हैं, तो यह विधि की पंक्ति संख्या को हमेशा विधि में लौटाएगा, इसलिए कोड स्निपेट इनलाइन का उपयोग करें।


मैंने अनुमान लगाया कि '2' गेटलाइनलाइनर () कॉलर की लाइन नंबर प्राप्त करना था।
साइमन बुकान सेप

@ simon.buchan - अपना उत्तर संपादित करें (मेरी अंतिम टिप्पणी के अनुसार)। मैं आपके जवाब के लिए आपका रेप नहीं चुराना चाहता।
रॉन टफिन

या 2 को दूसरी संख्या में बदलें। निर्भर करता है कि यह कितना गहरा है।
clankill3r

7

मैं log4j जैसे लॉगिंग टूलकिट का उपयोग करने की सलाह दूंगा । लॉगिंग रनटाइम पर गुण फ़ाइलों के माध्यम से कॉन्फ़िगर करने योग्य है, और आप लाइन नंबर / फ़ाइल नाम लॉगिंग जैसी सुविधाओं को चालू / बंद कर सकते हैं।

PatternLayout के लिए javadoc को देखने से आपको विकल्पों की पूरी सूची मिलती है - आप इसके बाद क्या हैं% L।


7

मैं इस छोटी विधि का उपयोग करता हूं जो उस पद्धति के ट्रेस और लाइन नंबर को आउटपुट करता है जो इसे कहते हैं।

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

1
यह कहां Utilसे आता है?
बेन्ज

@बेनज यूटिल्स सिर्फ सामान्य वर्ग है जिस पर आपका नियंत्रण है। आप विधि को किसी भी वर्ग में रख सकते हैं (ध्यान दें कि विधि स्थिर है)।
सिडवेल

1
ठीक है, मैं सिर्फ यकीन करना चाहता था। कोड के इस अच्छे बिट के लिए धन्यवाद।
बेंज

1

आप कोड के साथ लाइन नंबर स्थिरता की गारंटी नहीं दे सकते, खासकर अगर यह रिलीज के लिए संकलित है। मैं वैसे भी उस उद्देश्य के लिए लाइन नंबरों का उपयोग करने की सिफारिश नहीं करूंगा, उस जगह का पेलोड देना बेहतर होगा जहां अपवाद उठाया गया था (विधि कॉल के विवरण को शामिल करने के लिए संदेश सेट करने के लिए तुच्छ विधि)।

आप अपवाद हैंडलिंग को देखने के लिए एक तकनीक के रूप में अपवाद से निपटने में सुधार कर सकते हैं http://tutorials.jenkov.com/java-exception-handling/exception-enrichment.html


0

यदि इसे जारी करने के लिए संकलित किया गया है तो यह संभव नहीं है। आप Log4J जैसी किसी चीज़ पर गौर करना चाहते हैं जो स्वचालित रूप से आपको पर्याप्त जानकारी निर्धारित करने के लिए पर्याप्त जानकारी देगा जहां लॉग कोड हुआ।


0

पहले सामान्य विधि (एक उपयोगिता वर्ग में, सादे पुराने 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;
}

तब सही स्टैकमेंट प्राप्त करने के लिए विशिष्ट उपयोगिता विधि:

/**
   * 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;
  }

0

यहां वह लकड़हारा है जिसका हम उपयोग करते हैं।

यह एंड्रॉइड लॉगर के चारों ओर घूमता है और क्लास का नाम, विधि का नाम और लाइन नंबर प्रदर्शित करता है।

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


0

देखो इस लिंक । उस विधि में आप अपने लाइन कोड पर कूद सकते हैं, जब आप लॉगकट की पंक्ति पर डबल क्लिक करते हैं।

इसके अलावा, आप लाइन नंबर प्राप्त करने के लिए इस कोड का उपयोग कर सकते हैं:

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;
}

0
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();
}

0

ये सभी आपको आपके वर्तमान थ्रेड और विधि की लाइन नंबर मिलते हैं जो यदि आप एक अपवाद को पकड़ने की कोशिश कर रहे हैं, जहां आप एक अपवाद की उम्मीद कर रहे हैं। लेकिन अगर आप किसी अनहैंड अपवाद को पकड़ना चाहते हैं तो आप डिफॉल्ट अनकैप्ड अपवाद हैंडलर का उपयोग कर रहे हैं और करंट थ्रेड अपवाद को फेंकने वाली क्लास विधि को नहीं, बल्कि हैंडलर फंक्शन की लाइन नंबर लौटाएगा। इसके बजाय Thread.currentThread () का उपयोग करने के बजाय अपवाद हैंडलर द्वारा पारित थ्रोबेबल का उपयोग करें:

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

उपरोक्त उपयोग में e.getStackTrace () [0] अपने हैंडलर फ़ंक्शन (fShowUncaughtMessage) में अपराधी को पाने के लिए।


0

नीचे दिए गए कोड को लॉगिंग लाइन के लिए परीक्षण कोड नहीं वर्ग नाम और विधि का नाम है जहां से लॉगिंग विधि कहा जाता है

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;
}
}

0

stackLevelगहराई पर निर्भर करता है आप इस विधि कहते हैं। क्या अंतर देखने के लिए आप बड़ी संख्या में 0 से कोशिश कर सकते हैं।

यदि stackLevelकानूनी है, तो आपको स्ट्रिंग की तरह मिलेगा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);
}

0

यह बिल्कुल वैसा ही फीचर है जैसा मैंने इस लिबास XDDLib में लागू किया है । (लेकिन, यह Android के लिए है)

Lg.d("int array:", intArrayOf(1, 2, 3), "int list:", listOf(4, 5, 6))

यहाँ छवि विवरण दर्ज करें

जहां लॉग कमांड है वहां नेविगेट करने के लिए रेखांकित पाठ पर एक क्लिक करें

यह StackTraceElementइस पुस्तकालय के बाहर पहले तत्व द्वारा निर्धारित किया जाता है। इस प्रकार, इस lib के बाहर कहीं भी हो जाएगा कानूनी, सहित lambda expression, static initialization blockआदि


-1

मेरा तरीका यह मेरे लिए काम करता है

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;
  }

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.