How do I enable/disable log levels in Android?

后端 未结 18 2022
无人共我
无人共我 2020-11-22 16:42

I am having lots of logging statements to debug for example.

Log.v(TAG, \"Message here\");
Log.w(TAG, \" WARNING HERE\");

while deploying t

相关标签:
18条回答
  • 2020-11-22 17:20

    Another way is to use a logging platform that has the capabilities of opening and closing logs. This can give much of flexibility sometimes even on a production app which logs should be open and which closed depending on which issues you have for example:

    • LumberJack
    • Shipbook (disclaimer: I'm the author of this package)
    0 讨论(0)
  • 2020-11-22 17:21

    A common way is to make an int named loglevel, and define its debug level based on loglevel.

    public static int LOGLEVEL = 2;
    public static boolean ERROR = LOGLEVEL > 0;
    public static boolean WARN = LOGLEVEL > 1;
    ...
    public static boolean VERBOSE = LOGLEVEL > 4;
    
        if (VERBOSE) Log.v(TAG, "Message here"); // Won't be shown
        if (WARN) Log.w(TAG, "WARNING HERE");    // Still goes through
    

    Later, you can just change the LOGLEVEL for all debug output level.

    0 讨论(0)
  • 2020-11-22 17:22

    https://limxtop.blogspot.com/2019/05/app-log.html

    Read this article please, where provides complete implement:

    1. For debug version, all the logs will be output;
    2. For release version, only the logs whose level is above DEBUG (exclude) will be output by default. In the meanwhile, the DEBUG and VERBOSE log can be enable through setprop log.tag.<YOUR_LOG_TAG> <LEVEL> in running time.
    0 讨论(0)
  • 2020-11-22 17:24

    Here is a more complex solution. You will get full stack trace and the method toString() will be called only if needed(Performance). The attribute BuildConfig.DEBUG will be false in the production mode so all trace and debug logs will be removed. The hot spot compiler has the chance to remove the calls because off final static properties.

    import java.io.ByteArrayOutputStream;
    import java.io.PrintStream;
    import android.util.Log;
    
    public class Logger {
    
        public enum Level {
            error, warn, info, debug, trace
        }
    
        private static final String DEFAULT_TAG = "Project";
    
        private static final Level CURRENT_LEVEL = BuildConfig.DEBUG ? Level.trace : Level.info;
    
        private static boolean isEnabled(Level l) {
            return CURRENT_LEVEL.compareTo(l) >= 0;
        }
    
        static {
            Log.i(DEFAULT_TAG, "log level: " + CURRENT_LEVEL.name());
        }
    
        private String classname = DEFAULT_TAG;
    
        public void setClassName(Class<?> c) {
            classname = c.getSimpleName();
        }
    
        public String getClassname() {
            return classname;
        }
    
        public boolean isError() {
            return isEnabled(Level.error);
        }
    
        public boolean isWarn() {
            return isEnabled(Level.warn);
        }
    
        public boolean isInfo() {
            return isEnabled(Level.info);
        }
    
        public boolean isDebug() {
            return isEnabled(Level.debug);
        }
    
        public boolean isTrace() {
            return isEnabled(Level.trace);
        }
    
        public void error(Object... args) {
            if (isError()) Log.e(buildTag(), build(args));
        }
    
        public void warn(Object... args) {
            if (isWarn()) Log.w(buildTag(), build(args));
        }
    
        public void info(Object... args) {
            if (isInfo()) Log.i(buildTag(), build(args));
        }
    
        public void debug(Object... args) {
            if (isDebug()) Log.d(buildTag(), build(args));
        }
    
        public void trace(Object... args) {
            if (isTrace()) Log.v(buildTag(), build(args));
        }
    
        public void error(String msg, Throwable t) {
            if (isError()) error(buildTag(), msg, stackToString(t));
        }
    
        public void warn(String msg, Throwable t) {
            if (isWarn()) warn(buildTag(), msg, stackToString(t));
        }
    
        public void info(String msg, Throwable t) {
            if (isInfo()) info(buildTag(), msg, stackToString(t));
        }
    
        public void debug(String msg, Throwable t) {
            if (isDebug()) debug(buildTag(), msg, stackToString(t));
        }
    
        public void trace(String msg, Throwable t) {
            if (isTrace()) trace(buildTag(), msg, stackToString(t));
        }
    
        private String buildTag() {
            String tag ;
            if (BuildConfig.DEBUG) {
                StringBuilder b = new StringBuilder(20);
                b.append(getClassname());
    
                StackTraceElement stackEntry = Thread.currentThread().getStackTrace()[4];
                if (stackEntry != null) {
                    b.append('.');
                    b.append(stackEntry.getMethodName());
                    b.append(':');
                    b.append(stackEntry.getLineNumber());
                }
                tag = b.toString();
            } else {
                tag = DEFAULT_TAG;
            }
        }
    
        private String build(Object... args) {
            if (args == null) {
                return "null";
            } else {
                StringBuilder b = new StringBuilder(args.length * 10);
                for (Object arg : args) {
                    if (arg == null) {
                        b.append("null");
                    } else {
                        b.append(arg);
                    }
                }
                return b.toString();
            }
        }
    
        private String stackToString(Throwable t) {
            ByteArrayOutputStream baos = new ByteArrayOutputStream(500);
            baos.toString();
            t.printStackTrace(new PrintStream(baos));
            return baos.toString();
        }
    }
    

    use like this:

    Loggor log = new Logger();
    Map foo = ...
    List bar = ...
    log.error("Foo:", foo, "bar:", bar);
    // bad example (avoid something like this)
    // log.error("Foo:" + " foo.toString() + "bar:" + bar); 
    
    0 讨论(0)
  • 2020-11-22 17:26

    The better way is to use SLF4J API + some of its implementation.

    For Android applications you can use the following:

    1. Android Logger is the lightweight but easy-to-configure SLF4J implementation (< 50 Kb).
    2. LOGBack is the most powerful and optimized implementation but its size is about 1 Mb.
    3. Any other by your taste: slf4j-android, slf4android.
    0 讨论(0)
  • 2020-11-22 17:28

    The Android Documentation says the following about Log Levels:

    Verbose should never be compiled into an application except during development. Debug logs are compiled in but stripped at runtime. Error, warning and info logs are always kept.

    So you may want to consider stripping the log Verbose logging statements out, possibly using ProGuard as suggested in another answer.

    According to the documentation, you can configure logging on a development device using System Properties. The property to set is log.tag.<YourTag> and it should be set to one of the following values: VERBOSE, DEBUG, INFO, WARN, ERROR, ASSERT, or SUPPRESS. More information on this is available in the documentation for the isLoggable() method.

    You can set properties temporarily using the setprop command. For example:

    C:\android>adb shell setprop log.tag.MyAppTag WARN
    C:\android>adb shell getprop log.tag.MyAppTag
    WARN
    

    Alternatively, you can specify them in the file '/data/local.prop' as follows:

    log.tag.MyAppTag=WARN
    

    Later versions of Android appear to require that /data/local.prop be read only. This file is read at boot time so you'll need to restart after updating it. If /data/local.prop is world writable, it will likely be ignored.

    Finally, you can set them programmatically using the System.setProperty() method.

    0 讨论(0)
提交回复
热议问题