How to strip logs with Timber.tag.(...).d(...) format using ProGuard?

1.2k Views Asked by At

I need to strip down all my Timber logs in my production build. I have added the following in my proguard-project.txt :

-assumenosideeffects class timber.log.Timber* {
        public static *** tag(...);
        public static *** v(...);
        public static *** i(...);
        public static *** w(...);
        public static *** d(...);
        public static *** e(...);

-assumenosideeffects class timber.log.Timber.tag* {*;}
}

However only logs with the format Timber.e() or Timber.i() etc is being stripped. Logs with Timber.tag(..).i(...) are not getting stripped.

Is there any way to achieve this? Thank you

2

There are 2 best solutions below

3
Blackbelt On

wouldn't it be easier to do something line

if (BuildConfig.DEBUG) {
  Timber.plant(Timber.DebugTree())
}

in your Application subclass? This way you will the logs only in debug

2
am5a03 On

Stripping Timber.tag(...) cannot be done via Proguard. According to the usage guide,

In the optimization step, ProGuard can then remove calls to such methods, if it can determine that the return values aren't used.

Since Timber.tag(...) will return a Timber.Tree object, Proguard optimizer will not strip it off for you. Therefore, if you really want to strip off the log, you have to wrap it via a function e.g.

fun printDebugLog(tag: String, message: String) {
    Timber.tag(tag).d(message)
}

Then you can use -assumenosideeffects to strip off printDebugLog call. Another thing you have to be aware of that when your class is in Kotlin, the following rules cannot be used to strip off Timber logs also

-assumenosideeffects class timber.log.Timber* {
    public static *** d(...);
    public static *** v(...);
    public static *** i(...);
}

This is because when you decompile the Kotlin class to Java, logging will actually translated to

Timber.Forest.d(...)

Which will not be stripped off for the similar reason.