Disable LogCat Output COMPLETELY in release Android app?
Asked Answered
K

8

58

Shutting off my own app's LogCat output before releasing an app to the market is straightforward. I also know how to selectively filter LogCat message by tag and/or id for my own debug convenience.

But now I am interested in something that may be much more difficult (perhaps impossible?): Disable all LogCat output, including & especially those coming from 3rd-party services like TtsService, GoogleLoginService, etc.

Is this possible?

To further clarify: I am not interested in filtering out messages for myself. I am rather interested in disabling 3rd-party messages for whoever downloads my app from the Android Market. Is this possible?

Kodak answered 5/4, 2011 at 14:4 Comment(5)
So you want to prevent any app on the user's device from writing LogCat output?Yokefellow
Do you mean the log messages of those third-party libraries that you include (or use) from your app?Fact
@Yokefellow No, I want to prevent any app that is directly or indirectly being used by my app, from writing LogCat output. Sorry for not being clear enough.Kodak
@Fact DSouza Yes, that's exactly what I mean. I don't care about what other apps are showing when they work independently or used by other apps. I only care about them outputing stuff in response to my app's requestes/calls.Kodak
Okay, that makes more sense...Yokefellow
T
199

You can use ProGuard to remove completely any lines where a return value is not used, by telling ProGuard to assume that there will be no problems.

The following proguard.cfg chunk instructs to remove Log.d, Log.v and Log.i calls.

-assumenosideeffects class android.util.Log {
    public static *** d(...);
    public static *** w(...);
    public static *** v(...);
    public static *** i(...);
}

The end result is that these log lines are not in your release apk, and therefore any user with logcat won't see d/v/i logs.

Tuition answered 5/4, 2011 at 14:14 Comment(14)
This tip is incredible. It already deserves a +1. I will accept the answer after making sure that it indeed yields the desired result in my app. Thank you!Kodak
ProGuard is really powerful! You can also use this tip to remove other forms of development code, not just logging.Tuition
in what other scenarios might we want to remove code? And what forms?Fact
Code that enables developer features, like additional menu options, perhaps. Logging is the only common thing I can think of that you SHOULD remove.Tuition
I finally got to testing your solution. It works beautifully. :)Kodak
Will this affect line numbers when trying to match up stacktraces? I've seen some people say it only affects bytecode, so lines will still match, and others say otherwise. Can anyone confirm?Indeterminism
I added that lines in proguard-project.txt and proguard.config=proguard-project.txt to project.properties and with device connected into PC with Eclipse opened i can always retrieve Logs. Is that normal ?Vasilek
You need to be careful with this because you add a comment like Log.d(someStrVar + " sensitive info here"); the sensitive info string will still make it into the classes.dex file in the APK. Because Proguard has issues with optimisation when stringbuilder is used implicitlyTyndareus
They warn in proguard.cfg about problems with allowing proguard optimization and dex. I wasn't able to run it as is. Since I only needed proguard to remove logs, restricting optimization option to removal worked for me (in case someone has similar situation: -optimizations code/removal/*Lice
You have to use proguard-android-optimize.txt, if you want the assumenosideeffects settings to work. In android studio: proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'Mcchesney
@DavidCaunt Is there any way to hide native layer logs?Fortuna
I don't know, but I don't think ProGuard is the way to silence native logs – it removes logs from your own code by literally removing the logging calls.Tuition
@DavidCaunt, Could you plz verify again whether this works or not. Cause IMHO this piece of code does not work anymore. You will have to specify the exact return type ie. int instead of ***. Plz refer - https://mcmap.net/q/219443/-removing-log-call-using-proguardTwain
THIS SHOULD BE ADDED TO THE ANSWER! As @Mcchesney said - the following line should be set to the grade.build file: proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'Catch
E
9

if you don't use proguard, you have to manage the log yourself and in the manifest file make dubuggable false

<application
    android:name="MyApplication"
    android:icon="@drawable/gift"
    android:label="@string/app_name" android:debuggable="@bool/build_log">

Here my custom log class

public class Lol {

    public static final boolean ENABLE_LOG = true & MyApplication.sDebug;

    private static final boolean DEBUG = true & ENABLE_LOG;

    private static final boolean VERBOSE = true & ENABLE_LOG;

    private static final boolean TEMP = true & ENABLE_LOG;

    private static final boolean WARNING = true & ENABLE_LOG;

    private static final boolean INFO = true & ENABLE_LOG;

    private static final boolean ERROR = true & ENABLE_LOG;

    public static void obvious(String tag, String msg) {
        if (DEBUG) {
            msg = "*********************************\n" + msg
                    + "\n*********************************";
            Log.d(tag, msg);
        }
    }

    public static void d(String tag, String msg) {
        if (DEBUG)
            Log.d(tag, msg);
    }

    public static void d(boolean bool, String tag, String msg) {
        if (TEMP&bool)
            Log.d(tag, msg);
    }

    public static void i(String tag, String msg) {
        if (INFO)
            Log.i(tag, msg);
    }

    public static void e(String tag, String msg) {
        if (ERROR)
            Log.e(tag, msg);
    }

    public static void e(boolean bool, String tag, String msg) {
        if (TEMP&bool)
            Log.e(tag, msg);
    }

    public static void v(String tag, String msg) {
        if (VERBOSE)
            Log.v(tag, msg);
    }

    public static void w(String tag, String msg) {
        if (WARNING)
            Log.w(tag, msg);
    }

    public static String getStackTraceString(Exception e) {
        return Log.getStackTraceString(e);
    }

    public static void w(String tag, String msg, Exception e) {
        if (WARNING)
            Log.w(tag, msg,e);
    }
}
Empathize answered 16/3, 2012 at 21:17 Comment(3)
Since SDK Tools 8 it has not been necessary to set the android:debuggable flag manually. This removes the risk of shipping a debuggable release.Tuition
Just curious (I stumbled upon this question just now), is there any reason why you use true & ENABLE_LOG instead of only ENABLE_LOG? I don't see any difference functionality wise...Dillman
you're still trying to call functions and send arguments, don't think it' a good idea, just better to use if (BuildConfig.DEBUG) Log.i(TAG, msg);Terminate
C
3

The great answer provided by David Caunt doesn't seem to work for the rules defined in proguard-android-optimize.txt.

Instead of using the wildcard ***, current versions of ProGuard seem to expect the return parameter's type qualifier:

-assumenosideeffects class android.util.Log {
    public static int   d(...);
    public static int   w(...);
    public static int   v(...);
    public static int   i(...);
    public static int wtf(...);
}
Crib answered 1/8, 2017 at 12:8 Comment(0)
T
3

In app build.gradle file set:

release {
    minifyEnabled true
     ……
}

In proguard-rules.pro put:

-assumenosideeffects class android.util.Log {
  public static *** v(...);
  public static *** d(...);
  public static *** i(...);
  public static *** w(...);
  public static *** e(...);
}
-ignorewarnings

It worked for me.

Turbot answered 3/3, 2018 at 18:48 Comment(0)
T
0

I usually do next:

if (BuildConfig.DEBUG) Log.i(TAG, msg);

though if you have a lot of dependencies (libraries) and they written bad then yeah just use https://mcmap.net/q/218275/-disable-logcat-output-completely-in-release-android-app

making lines shorter:

private final static boolean DEBUG = BuildConfig.DEBUG;

if (DEBUG) Log.i(TAG, msg_1);

if (DEBUG) Log.e(TAG, msg_error_2);
Terminate answered 24/3, 2018 at 16:44 Comment(0)
S
0

I combined David Snabel-Caunt's accepted answer in addition to swapping out the default ProGuard settings ("proguard-android.txt" file) from the Android SDK for the "proguard-android-optimize.txt" optimized file. The file is also available in this Android SDK folder with the same rules but with optimizations enabled.

Scotopia answered 23/2, 2019 at 23:26 Comment(0)
E
0

Instead of enumerating all the class's methods it looks like you can also simply use the <methods> shorthand :

-assumenosideeffects class a.b.c.DebugLogs {
    <methods>;
}

Worked for me with com.android.tools.build:gradle version 4.0.0.

Electrotherapy answered 7/7, 2020 at 16:8 Comment(0)
B
-1

You can put debuggable false on buildTypes release.

buildTypes {

     release {
        debuggable false
        ...
     }

}
Bulb answered 25/9, 2017 at 18:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.