Proguard removes *trivial* Log calls very well. (with the `assumenosideeffects` keyword)  

But it handles *non-trivial* Log calls poorly.

By "Non-Trivial" I mean anything more than a single String.  

For example: `Log.i(TAG,"velocity="+velocity)`".   

Proguard keeps the `new StringBuilder("velocity=")`, and also the appended variable holing the value, not much obscuring that variable. It removes only the eventual call to Log.  

The strings will remain there, wasting memory, cpu cycles and also help crackers understand the code.

So to solve this, I wrap every *non-trivial* debug Log call in my app with `if(BuildConfig.DEBUG){...}`. 
But wrapping every log with `if(..){..}` is tedious and error prone.  

It's certainly not DRY (Don't repeat yourself).  

Is there a way to mark a method for complete removal by Proguard (or by any other means), including all calling methods?

Something like:

```
@proguard_purge
public static void vanishingDebug(String whatever) {
  Log.i(TAG,whatever);
}

```

So the method will vanish by the obfuscator, and also all calls to this method will vanish recursively as well?

***ELABORATION***

Obfuscation will optimize code and remove unused or excluded methods.  

But code compilation generates extra byte codes *prior* to the method call that will be removed, and that preceding code *will* stay even after obfuscation, and leave behind code such as:

```
new StringBuilder("velocity=").append(a)

```

(Assuming `a` cannot be determined at compile time. To test, use `velocity=Math.random();`)

Which makes the obfuscated code quite trivial to understand.

***EXAMPLE***

```
@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    Log.i("TAG", "Simple Comment"); // << Disappears well!

    double index = Math.random();
    index++;

    Log.i("TAG2", "log_index=" + index); // << hmm... (!)

    // class with only log calls inside
    new ReferencedClass();

    // simple method call
    MyLogger.notLog("no_log" + index); // << stays, as expected

    // simple method call with only Log call inside (aka "Log Wrapper")
    MyLogger.log("log" + index);  // << stays, as expected

    Log.i("TAG2", "This is random:" + Math.random()); // << stays, same as above

    setContentView(R.layout.activity_main);
}

```

Using this obfuscation configuration:

```
-assumenosideeffects class android.util.Log {
    public static *** isLoggable(java.lang.String, int);
    public static *** d(...);
    public static *** v(...);
    public static *** i(...);
    public static *** w(...);
    public static *** e(...);
}

```

It will be obfuscated to a state which can be de-compiled and de-obfuscated to this:

```
  protected void onCreate(Bundle paramBundle)
  {
    super.onCreate(paramBundle);
    double d = 1.0D + Math.random();
    new StringBuilder("log_index=").append(d).toString();
    new b();
    a.a("no_log" + d);
    new StringBuilder("log").append(d).toString();
    a.a();
    new StringBuilder("This is random:").append(Math.random()).toString();
    setContentView(2130903064);
  }

```