জাভা লগতে আমরা কীভাবে লাইন নম্বর প্রিন্ট করতে পারি?


132

লগতে লাইন নম্বর কীভাবে প্রিন্ট করা যায়। লগতে কিছু তথ্য আউটপুট দেওয়ার সময় বলুন, আমি লাইন নম্বরটিও মুদ্রণ করতে চাই যেখানে সেই আউটপুটটি সোর্স কোডে রয়েছে। আমরা স্ট্যাক ট্রেসটিতে দেখতে পাচ্ছি, এটি লাইন নম্বরটি প্রদর্শন করে যেখানে ব্যতিক্রম ঘটেছে। স্ট্যাক ট্রেস ব্যতিক্রম অবজেক্টে উপলব্ধ।

লগতে প্রিন্ট করার সময় অন্যান্য বিকল্প ম্যানুয়ালি লাইন নম্বর সহ থাকতে পারে। অন্য কোন উপায আছে কি?


4
সংক্ষিপ্ত এবং মিষ্টি ওয়ান-লাইনারের জন্য নীচে @ জুয়ানের অপরিবর্তিত উত্তর দেখুন! V এবং upvoting জুয়ান এর: আমি শুধুমাত্র 15 পয়েন্ট প্রতিনিধির সব অন্যান্য উত্তর downvoting ছেড়ে দিল
জান

উত্তর:


102

অ্যাংসুমান চক্রবর্তী থেকে :

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

5
এটি সর্বদা কথিত পদ্ধতিতে রিটার্নের স্টেটমেন্টের লাইন নম্বর প্রদান করবে এবং পদ্ধতি কলের লাইন নম্বরটি অগত্যা নয়।
রন টফিন

[2] getLineNumber () এর উপরে ফ্রেমটি পাবে না? ([1] getLineNumber হচ্ছে (), এবং [0] getStackTrace (), সম্ভবত))
সাইমন

1
আমি কিছুটা ঘুরেছি এবং যদি আপনি blah.getStackTrace [3] .getLineNumber () পদ্ধতি হিসাবে ব্যবহার করেন তবে এটি যেখানে পদ্ধতিটি বলা হয়েছিল তার লাইন নম্বর প্রদান করে।
রন টফিন

12
জেভিএম সংস্করণের উপর ভিত্তি করে সূচকটি পরিবর্তন হবে। আমি বিশ্বাস করি এটি 1.4 থেকে 1.5 এ পরিবর্তিত হয়েছে।
এড টমাস

2
আরে @ সিমন বুচান, লোকটির একটি নাম আছে :) আমি সেই নিবন্ধটি অনেক আগে লিখেছিলাম।
অ্যাঙ্গসুমান চক্রবর্তী

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
হাই মাইকেল, আপনার সমাধানের জন্য ধন্যবাদ, লগ সম্পর্কিত তথ্যের জন্য লাইন নম্বরগুলি প্রদর্শন করা আমার পক্ষে ভাল কাজ করছে .... আবার ধন্যবাদ। আমি অ্যান্ড্রয়েডে আপনার দুর্দান্ত সমাধানগুলির জন্য অপেক্ষা করছি।
সতীশ

3
আমি এই কোডটি ব্যবহার করার আগে আরও কিছু গবেষণা করতাম - যখন আমি কোড পোস্ট করি তখন getStackTrace () [3] কাজ করেছিল। এটি অ্যান্ড্রয়েড বা জেভিএম এর সংস্করণ বা অন্য কোনও ফ্যাক্টরের উপর নির্ভরশীল হতে পারে।
মাইকেল বাল্টাক্স

3
এই উত্তরটি কার্যকর হয় না এটি ডিবাগলগ শ্রেণীর লাইনের নং এবং শ্রেণীর নাম এবং ফাংশনটির নাম দেখায় না অন্য শ্রেণির কলার
রাহুল

@ রাহুল এটির getStackTrace()[3]পরিবর্তে হওয়া উচিতgetStackTrace()[2]
ব্যবহারকারীর 480949

@ user5480949: জেভিএম নির্বিশেষে আপনার কলিং ফাংশনটির জন্য একটি ধারাবাহিক সূচক পেতে "নতুন থ্রোয়েবল ()। 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]);আমার যাবতীয় বিশদ আমাকে দেয় :)
নেক্রোমেন্সার

নোট করুন যে JVM যেখানে স্ট্যাকট্রেস দেওয়ার এটি গ্যারান্টিযুক্ত নয় যেখানে এটি সঠিক। আমি বিশ্বাস করি না হটস্পট সেই গ্যারান্টিটি দেয় (তবে এর স্ট্যাকট্রেসগুলি সাধারণত সঠিক)।
থরবজর্ন রাভন অ্যান্ডারসন

খুব পরিষ্কার, ক্লাস স্ট্যাকট্রেসএলিমেন্ট l = নতুন ব্যতিক্রম ()। গেটস্ট্যাকট্রেস () [1]; আমার সাথে কাজ করুন
vuhung3990

@ থরবজর্নরভানএন্ডারসন: জেভিএম নির্বিশেষে আপনার কলিং ফাংশনটির জন্য একটি ধারাবাহিক সূচক পেতে "নতুন থ্রোয়েবল ()। গেটস্ট্যাক ট্রেস ()" ব্যবহার করুন। (থ্রেড.কন্ট্রেন্টথ্রেডের পরিবর্তে) (গেটস্ট্যাকট্রেস ())
লুক ব্লুম

পুরানো দিনগুলিতে @ লাকব্লুম আপনার গ্যারান্টিযুক্ত ছিল না যে স্ট্যাকের চিহ্নটি সঠিক ছিল।
থরবজর্ন রাভন অ্যান্ডারসন

25

আমি আপনার প্রশ্নের উত্তর না দিয়ে উত্তর দিতে বাধ্য am আমি ধরে নিচ্ছি যে আপনি কেবলমাত্র ডিবাগিং সমর্থন করার জন্য লাইন নম্বরটি সন্ধান করছেন। আরও ভাল উপায় আছে। বর্তমান লাইন পেতে হ্যাকিশ উপায় আছে। আমি সব দেখেছি ধীর। Java.util.logging প্যাকেজ বা লগ 4 জে এর মতো লগিং ফ্রেমওয়ার্ক ব্যবহার করা আপনি ভাল । এই প্যাকেজগুলি ব্যবহার করে আপনি ক্লাস নামের সাথে প্রসঙ্গ অন্তর্ভুক্ত করতে আপনার লগিং তথ্য কনফিগার করতে পারেন। তারপরে প্রতিটি লগ বার্তাটি কোথা থেকে এসেছে তা জানার পক্ষে যথেষ্ট অনন্য হবে। ফলস্বরূপ, আপনার কোডটিতে একটি 'লগার' ভেরিয়েবল থাকবে যা আপনি কল করে

logger.debug("a really descriptive message")

পরিবর্তে

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


15

লগ 4 জে আপনাকে আউটপুট প্যাটার্নের অংশ হিসাবে লাইন নম্বর অন্তর্ভুক্ত করতে দেয়। কীভাবে এটি করা যায় তার বিশদ জানতে http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PatternLayout.html দেখুন (রূপান্তর প্যাটার্নটির মূল উপাদানটি "এল")। তবে জাভাডোকের মধ্যে নিম্নলিখিতগুলি অন্তর্ভুক্ত রয়েছে:

সতর্কতা কলার অবস্থানের তথ্য উত্পন্ন করা অত্যন্ত ধীর। মৃত্যুদন্ড কার্যকর করার গতি কোনও সমস্যা না হলে এর ব্যবহার এড়ানো উচিত।


অন্তর্নিহিত প্রক্রিয়াটি জেভিএমের আরও সাম্প্রতিক সংস্করণগুলিতে আরও দ্রুত গতিতে পরিণত হয়েছে, তবে এটি এখনও খুব কম ব্যবহার করা উচিত।
থরবজর্ন রাভন অ্যান্ডারসন

7

@ সায়মন.বুকান পোস্ট করা কোডটি কাজ করবে ...

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

তবে আপনি যদি এটি কোনও পদ্ধতিতে কল করেন তবে এটি সর্বদা পদ্ধতিতে লাইনের লাইন নম্বরটি ফিরিয়ে দেবে তাই কোড স্নিপেট ইনলাইনটি ব্যবহার করুন।


আমি অনুমান করেছি যে '2'টি getLineNumber () কলারের লাইন নম্বর পেয়েছিল।
সাইমন বুচান

@ সাইমন.বুকান - আপনার উত্তর সম্পাদনা করুন (আমার শেষ মন্তব্য অনুসারে) আমি আপনার উত্তরের জন্য আপনার প্রতিনিধি চুরি করতে চাই না।
রন টফিন

অথবা 2টিকে অন্য সংখ্যায় পরিবর্তন করুন। এটি কতটা বাসা বেঁধে রয়েছে তার উপর নির্ভর করে।
clankill3r

7

আমি লগ 4j এর মতো লগিং টুলকিট ব্যবহার করার পরামর্শ দেব । রানটাইম সময়ে লগইন বৈশিষ্ট্য ফাইলগুলির মাধ্যমে কনফিগারযোগ্য এবং আপনি লাইন নম্বর / ফাইল নাম লগিংয়ের মতো বৈশিষ্ট্যগুলি চালু / বন্ধ করতে পারেন।

প্যাটার্নলআউটের জাভাডোকের দিকে তাকানো আপনাকে বিকল্পগুলির পুরো তালিকা দেয় - আপনি যা পরে% 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

কোডের সাথে লাইন নম্বর ধারাবাহিকতার আপনি গ্যারান্টি দিতে পারবেন না, বিশেষত যদি এটি মুক্তির জন্য সংকলিত হয়। আমি সেভাবে লাইন নম্বরগুলি যেভাবেই ব্যবহার করার পরামর্শ দিচ্ছি না, যেখানে ব্যতিক্রম উত্থাপিত হয়েছিল তার স্থানটির একটি পেওলড দেওয়া ভাল (পদ্ধতি কলের বিশদ অন্তর্ভুক্ত করার জন্য তুচ্ছ পদ্ধতিটি বার্তা নির্ধারণ করার জন্য) better

আপনি ব্যতিক্রম হ্যান্ডলিং উন্নত করার একটি পন্থা হিসেবে ব্যতিক্রম সমৃদ্ধি তাকান পছন্দ করতে পারেন http://tutorials.jenkov.com/java-exception-handling/exception-enrichment.html


0

এটি মুক্তির জন্য সংকলিত থাকলে এটি সম্ভব নয়। আপনি লগ 4 জ এর মতো কিছু সন্ধান করতে চাইতে পারেন যা লগড কোডটি কোথায় ঘটেছে তা নিবিড়ভাবে নির্ধারণ করার জন্য স্বয়ংক্রিয়ভাবে আপনাকে যথেষ্ট তথ্য দেবে।


0

প্রথমে সাধারণ পদ্ধতি (ইউটিলিটি ক্লাসে, সরল পুরাতন java1.4 কোডে যদিও আপনাকে জাভা ১.৫ এবং আরও কিছু ক্ষেত্রে এটি পুনরায় লিখতে হতে পারে)

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

তাকান এই লিঙ্কে । সেই পদ্ধতিতে আপনি লাইন কোডের সারিটিতে ডাবল ক্লিক করলে আপনি আপনার লাইন কোডে ঝাঁপিয়ে পড়তে পারেন।

এছাড়াও আপনি লাইন নম্বর পেতে এই কোডটি ব্যবহার করতে পারেন:

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.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
            public void uncaughtException(Thread t, Throwable e) {              
                if(fShowUncaughtMessage(e,t))               
                    System.exit(1);
            }
        });

অপরাধী পেতে আপনার হ্যান্ডলার ফাংশনে (fShowUncaughtMessage) e.getStackTrace () [0] ব্যবহার করুন।


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

এটি এই বৈশিষ্ট্যটি হ'ল আমি এই লাইব এক্সডিডিএলবিতে প্রয়োগ করেছি । (তবে এটি অ্যান্ড্রয়েডের জন্য)

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

এখানে চিত্র বর্ণনা লিখুন

লগ কমান্ডটি কোথায় রয়েছে সেটিতে নেভিগেট করতে আন্ডারলাইন করা পাঠ্যের উপরে একটি ক্লিক করুন

যা StackTraceElementএই লাইব্রেরির বাইরে প্রথম উপাদান দ্বারা নির্ধারিত হয়। সুতরাং, এই liberal এর সংক্ষিপ্ত রূপ বাইরে কোথাও হতে হবে আইনি সহ 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;
  }

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.