it-swarm-eu.dev

Jak lze tisknout čísla řádků do protokolu v javě

Jak tisknout čísla řádků do protokolu. Řekněme, že při výstupu některých informací do protokolu, také chci vytisknout číslo řádku, kde je výstup ve zdrojovém kódu. Jak můžeme vidět ve stopě zásobníku, zobrazí číslo řádku, kde došlo k výjimce. Trasování zásobníku je k dispozici na objektu výjimky.

Jiná alternativa může být jako ruční včetně čísla řádku při tisku do protokolu. Existuje nějaká jiná cesta?

123
Bobby Kumar

Z Angsuman Chakraborty :

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

Nakonec jsme použili vlastní třídu podobnou vaší práci se systémem 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);
  }
 }
}
70
Michael Baltaks

Rychlý a špinavý způsob:

System.out.println("I'm in line #" + 
    new Exception().getStackTrace()[0].getLineNumber());

Další podrobnosti:

StackTraceElement l = new Exception().getStackTrace()[0];
System.out.println(
    l.getClassName()+"/"+l.getMethodName()+":"+l.getLineNumber());

Tím se zobrazí něco takového:

com.example.mytest.MyClass/myMethod:103
30
Juan

Jsem nucen odpovědět odpovědí na vaši otázku. Předpokládám, že hledáte číslo linky pouze pro podporu ladění. Jsou lepší způsoby. Existují hackish způsoby, jak získat aktuální řádek. Všechno, co jsem viděl, je pomalé. Je lepší použít logovací framework jako v balíčku Java.util.logging nebo log4j . Pomocí těchto balíčků můžete konfigurovat informace o protokolování tak, aby zahrnovaly kontext do názvu třídy. Každá logická zpráva by pak byla natolik jedinečná, aby věděla, odkud pochází. V důsledku toho bude mít váš kód proměnnou „logger“, kterou voláte přes

logger.debug("a really descriptive message")

namísto 

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

24
James A Wilson

Log4J umožňuje zahrnout číslo řádku jako součást jeho výstupního vzoru. Podrobnosti o tom, jak postupovat (viz klíčový prvek ve vzorci převodu je "L") viz http://logging.Apache.org/log4j/1.2/apidocs/org/Apache/log4j/PatternLayout.html . Javadoc však zahrnuje následující:

VAROVÁNÍ Generování informací o místě volajícího Je velmi pomalé. Je třeba se vyvarovat , Pokud rychlost Není problém.

14
Jim Kiley

Používám tuto malou metodu, která vydává stopu a číslo řádku metody, která ji volala. 

 Log.d(TAG, "Where did i put this debug code again?   " + Utils.lineOut());

Dvojitým kliknutím na výstup přejdete na řádek zdrojového kódu!

Pravděpodobně bude nutné upravit hodnotu úrovně v závislosti na tom, kam kód vložíte.

public static String lineOut() {
    int level = 3;
    StackTraceElement[] traces;
    traces = Thread.currentThread().getStackTrace();
    return (" at "  + traces[level] + " " );
}
7
Sydwell

Kód přidaný uživatelem @ simon.buchan bude fungovat ...

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

Pokud tomu ale říkáte metodu, vždy vrátí číslo řádku řádky v metodě, takže raději použijte útržek kódu. 

7
Ron Tuffin

Doporučil bych použít sadu nástrojů pro protokolování, například log4j . Protokolování je konfigurovatelné pomocí souborů vlastností za běhu a můžete zapnout/vypnout funkce, jako je například číslo řádku/protokolování názvu souboru.

Podíváme-li se na javadoc pro PatternLayout , získáte úplný seznam možností - po tom co je% L.

6
user7094

stackLevel závisí na hloubce, kterou nazýváte touto metodou. Můžete zkusit od 0 do velkého čísla, abyste zjistili, jaký rozdíl.

Pokud je stackLevel legální, dostanete řetězec jako 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
Loyea

Podívejte se na tento odkaz . V této metodě můžete přeskočit na linkový kód, když dvakrát kliknete na řádek LogCat.

Tento kód můžete také použít k získání čísla řádku:

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
Bobs

Zde je záznamník, který používáme. 

obtočí kolem Android Logger a zobrazí název třídy, název metody a číslo řádku.

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

0
jimmy.hautelook
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
Raymond

Nelze zaručit konzistenci čísla řádku s kódem, zejména pokud je kompilován pro vydání. Nedoporučoval bych používat čísla linek pro tento účel stejně, bylo by lepší dát užitečné zatížení místa, kde byla výjimka zvýšena (triviální metoda je nastavit zprávu tak, aby zahrnovala podrobnosti o volání metody).

Možná se budete chtít podívat na obohacení výjimky jako techniku ​​ke zlepšení zpracování výjimek http://tutorials.jenkov.com/Java-exception-handling/exception-enrichment.html

0
UberAlex

Pokud je to pro kompilaci, není to možné. Možná se budete chtít podívat na něco jako Log4J, který vám automaticky poskytne dostatek informací, abyste mohli přesně určit, kde se zaznamenaný kód vyskytl.

0
GBa

nejprve obecnou metodu (ve třídě nástrojů, v prostém starém kódu Java1.4, možná ji budete muset přepsat pro jazyk Java1.5 a další)

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

Pak bude specifická metoda utility získat správný 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;
  }
0
VonC

To vše vám poskytne čísla řádků vašeho aktuálního vlákna a metody, které fungují skvěle, pokud použijete pokus o úlovek, kde očekáváte výjimku. Pokud však chcete zachytit jakoukoliv neošetřenou výjimku, pak používáte výchozí obslužný program neuzavřené výjimky a aktuální vlákno vrátí číslo řádku funkce handleru, nikoli metodu třídy, která výjimku vyvolala. Namísto použití Thread.currentThread () jednoduše použijte Throwable předaný obslužným programem výjimek:

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

Ve výše uvedeném použijte e.getStackTrace () [0] ve vaší funkci handleru (fShowUncaughtMessage), abyste dostali pachatele.

0
Mark

Pod kódem je testován kód pro logovací řádek bez názvu třídy a názvu metody, odkud se nazývá metoda protokolování

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
Rahul