The android app publishing checklist says that I need to delete all Log statements from my code. Does that mean I need to delete them or would just commenting them out do? I would need those Log statements for updation and maintenance purpose later on so i don't want to delete them.Publishing checklist
You don't have to remove your logs from code, just disable them in RELEASE mode. The easiest way to achieve that, check mode before log something
if (BuildConfig.DEBUG) {
Log.i("TAG", "Log");
}
But it will be painful if you have a lot of logs in your code, so good idea is to write your custom wrapper above the Android Log class, with ability to turn on/off logging in one place, for example in Application class.
Or you can use some smart loggers like Timber
EDIT
About log wrapper, to be honest I've never created such wrapper, I prefer to use Timber, but the simplest version may look like this
public class Logger {
public static void e(String tag, String body) {
if (BuildConfig.DEBUG) {
Log.e(tag, body);
}
}
public static void v(String tag, String body) {
if (BuildConfig.DEBUG) {
Log.v(tag, body);
}
}
...
}
and instead of using
Log.e("Tag", "Body");
use
Logger.e("Tag", "Body");
The publishing check list just don't want you to include log statements when your app is published because it may contain some sensitive information and that sort of stuff. So you just need to make sure that it is not executed.
As long as the log statement is not executed, it's fine.
You can do the following:
Delete the statement
comment the statement
add an impossible if statement:
if (0 != 0) {
//log
}
P.S. The second solution the the most recommended.
Related
I just found that using Trace.beginSection can help troubleshoot performance issues while using systrace tool.
The documentation states "This tracing mechanism is independent of the method tracing mechanism offered by Debug#startMethodTracing"
But just like debug logs, do we need to comment/remove Trace API before releasing the app. Or is it allowed/benign to leave Trace API invocations in release code?
Preparing for release checklist does not mention anything about trace API.
But I am doubtful because there are other methods like Trace.setCounter which can be used to log debug info.
Typically I remove the traces when I'm done with them but Google leaves it in for some of the most basic building blocks like RecyclerView so it's probably fine.
Here's an example from the RecyclerView source:
// androidx.recyclerview.widget.RecyclerView
void consumePendingUpdateOperations() {
if (!mFirstLayoutComplete || mDataSetHasChangedAfterLayout) {
TraceCompat.beginSection(TRACE_ON_DATA_SET_CHANGE_LAYOUT_TAG);
dispatchLayout();
TraceCompat.endSection();
return;
}
if (!mAdapterHelper.hasPendingUpdates()) {
return;
}
// if it is only an item change (no add-remove-notifyDataSetChanged) we can check if any
// of the visible items is affected and if not, just ignore the change.
if (mAdapterHelper.hasAnyUpdateTypes(AdapterHelper.UpdateOp.UPDATE) && !mAdapterHelper
.hasAnyUpdateTypes(AdapterHelper.UpdateOp.ADD | AdapterHelper.UpdateOp.REMOVE
| AdapterHelper.UpdateOp.MOVE)) {
TraceCompat.beginSection(TRACE_HANDLE_ADAPTER_UPDATES_TAG);
startInterceptRequestLayout();
onEnterLayoutOrScroll();
mAdapterHelper.preProcess();
if (!mLayoutWasDefered) {
if (hasUpdatedView()) {
dispatchLayout();
} else {
// no need to layout, clean state
mAdapterHelper.consumePostponedUpdates();
}
}
stopInterceptRequestLayout(true);
onExitLayoutOrScroll();
TraceCompat.endSection();
} else if (mAdapterHelper.hasPendingUpdates()) {
TraceCompat.beginSection(TRACE_ON_DATA_SET_CHANGE_LAYOUT_TAG);
dispatchLayout();
TraceCompat.endSection();
}
}
It's okay to leave them in but do not leave any confidential information because it will be exposed to anyone profiling the app.
Is there a way to have non intrusive logs in Android ?, for example, if I have a method like the following one:
public void aMedthod() {
doSmt();
if (mSomeState) {
if (doSmtElse()) {
Log.v("MyApp","Success")
}
}
}
What I'd like to do is replacing that Log line with something as less intrusive as possible, in order to package the app for production without any trace of the Log library and at the same time, not having to delete nor comment any piece of code.
Jake Wharton made an awesome library that can accomplish exactly that. Take a look here.
just use this to init:
if (BuildConfig.DEBUG) {
Timber.plant(new Timber.DebugTree());
}
I have used Log.d() and Log.e() through out my android application for debugging purpose.
I would like to know if I release my application like this, will the user sees all those debug statement that I put in? Do I need to do something special so that user won't see the debug log even if they hook up 'adb logcat'?
Thank you.
Leaving logging statements can, in some cases, be very bad:
http://web.archive.org/web/20121222023201/http://vbsteven.com/archives/535
You can use ProGuard to automatically remove them all:
-assumenosideeffects class android.util.Log {
public static *** d(...);
public static *** e(...);
}
Consider using this : isLoggable()
Checks to see whether or not a log for the specified tag is loggable at the specified level. The default level of any tag is set to INFO. This means that any level above and including INFO will be logged. Before you make any calls to a logging method you should check to see if your tag should be logged. You can change the default level by setting a system property: setprop log.tag.<YOUR_LOG_TAG> <LEVEL> Where level is either VERBOSE, DEBUG, INFO, WARN, ERROR, ASSERT, or SUPPRESS. SUPPRESS will turn off all logging for your tag. You can also create a local.prop file that with the following in it: log.tag.<YOUR_LOG_TAG>=<LEVEL> and place that in /data/local.prop
Personally for releases, I'd remove the debug logs and keep the error logs using Proguard.
It is better to wrap it like so:
public class MyLog {
public static void d(String tag, String msg) {
if (Log.isLoggable(tag, Log.DEBUG)) {
Log.d(tag, msg);
}
}
public static void i(String tag, String msg) {
if (Log.isLoggable(tag, Log.INFO)) {
Log.i(tag, msg);
}
} // and so on...
You can set logging level by issuing an adb command
Not only can the user (or any app with log access) see your logs, but your logs also cause your app to run slower and use more battery power.
Writing a log, especially from Java, is probably much more expensive than you think: just building the string in Java is a lot of work.
There are apps in the Market that allow users to see logs even without hooking up a development environment.
CatLog is one I have personally used and it will show you everything.
What I've done in my app is create a wrapper class that I can turn off myself with a boolean flag. It has the added benefit of having the TAG parameter being common throughput my code.
public class QLog {
private static final String TAG = "MyAppTag";
private static final boolean DEBUG_MODE = true;
public static void d(String msg) {
if(DEBUG_MODE) {
Log.d(TAG, msg);
}
}
...
}
As it is said in android.developer.com
when you're building the string to pass into Log.d, the compiler uses a StringBuilder and at least three allocations occur: the StringBuilder itself, the buffer, and the String object. Realistically, there is also another buffer allocation and copy, and even more pressure on the gc. That means that if your log message is filtered out, you might be doing significant work and incurring significant overhead.
here is the link:
http://developer.android.com/reference/android/util/Log.html
They can be used when developing. When release, it is better to remove or obfuscate the message to protect PII(Personally identifiable information). The answer here is very useful: Android Log.v(), Log.d(), Log.i(), Log.w(), Log.e() - When to use each one?
Here is the one teach you the tool to deal with these logs when release the software.Remove all debug logging calls before publishing: are there tools to do this?
If your user is a developer, and connects the device to a developing machine and have LogCat opened he will se all logs on Logcat if he interracts with that application. When you are going to publish the application to the final user you should remove those logs.
Logging guidelines
Log.v(String tag, String msg) (verbose)
Log.d(String tag, String msg) (debug)
Log.i(String tag, String msg) (information)
Log.w(String tag, String msg) (warning)
Log.e(String tag, String msg) (error)
To only show logs on debug builds:
if (BuildConfig.DEBUG) Log.d(TAG, "The value of x is " + x);
I would to know whether logging can decrease application performance?
Also, please give me some tips to increase android application performance.
Yes. Excessive logging affects the performance of any application not just Android.
The developer guide suggests you to deactivate and disabled logging before release:
Turn off logging and debugging Make sure you deactivate logging and
disable the debugging option before you build your application for
release. You can deactivate logging by removing calls to Log methods
in your source files. You can disable debugging by removing the
android:debuggable attribute from the tag in your
manifest file, or by setting the android:debuggable attribute to false
in your manifest file. Also, remove any log files or static test files
that were created in your project.
Also, you should remove all Debug tracing calls that you added to your
code, such as startMethodTracing() and stopMethodTracing() method
calls.
So, you should suppress the logs in "release" or "production" build of your App.
Turn off it in Android Manifest by setting debuggable:
<application android:icon="#drawable/icon"
android:label="#string/app_name"
android:debuggable="false">
Another way
Create your own logger class and check for debugging mode before executing log. It allows single point modification between debugging mode and deployed application and allows extra things to do such as writing to log file.
import android.util.Log;
public class MyLog {
private static final boolean isDebug = false;;
public static void i(String tag, String msg) {
if (isDebug) {
Log.i(tag, msg);
}
}
public static void e(String tag, String msg) {
if (isDebug) {
Log.e(tag, msg);
}
}
}
For further info read http://rxwen.blogspot.com/2009/11/logging-in-android.html
and The SO QAs :
Log.d and impact on performance
Android Logging - How to clear for better performance
use 'if' statement before log writing.
you can disable log when application release.
example :
public class LogTest extends Activity {
private static final String TAG = "YOUR_LOG_TAG_NAME";
private static final boolean mDebug = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//--[Start Log example]-----------------------------------------
if(mDebug) Log.d(TAG, "Log Write Test");
//--[End Log example]-----------------------------------------
}
}
Any text output in excess will slow down your application, even with a desktop application. Excessive logging does slow things down, but you would basically need an insane amount of data being sent through, which by the way, isn't that hard to do with a for or while loop. Things that happen in the background while logging sometime include string manipulation, text rendering, cache management, data filtering, log length limiting, and the list goes on.
There's several ways to remove logcat from your final app, especially those involving ProGuard. ProGuard didn't work for me, but there's plenty of brilliant ideas out there on how to remove them including scripting programs like sed.
I'm not entirely sure about what I'm reading in the documentation. Is it ok to leave a bunch of log.d pieces of code scattered about, or should I comment them out so that they don't impact my app's performance.
Thanks,
I'm a little confused because if you read about the log object (documentation) you see this:
"The order in terms of verbosity, from least to most is ERROR, WARN,
INFO, DEBUG, VERBOSE. 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. "
It almost sounded like it's ok to leave debug messages in there because they are "stripped." Anyway, thanks for the answers, I'll comment them out when I'm done. Not like I need them in there once the app is completed.
Thanks
Log has impact on performance, so it's recommended that you comment it out or log with conditional statements.
For example
public class MyActivity extends Activity {
// Debugging
private static final String TAG = "MyApp";
private static final boolean D = true;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(D) Log.e(TAG, "MyActivity.onCreate debug message");
}
Then in when you publish your release version just change "D" to false
My solution:
Add unguarded log statements wherever you like
Strip them out for release builds
Definitely comment them out. They add up quickly and could noticeably slow down your app, especially if you have them in loops.
Simply use code guard methods.
if (Log.isLoggable(LOG_TAG, Log.DEBUG)) {
Log.d(LOG_TAG, "Your log here");
}
Yes print, println, Log.d, Log.e and all similar methods affect performance.
The solution
create a class named C
class C{
public static String TAG="My_debug_tag";
public static boolean isInTesting=true;
public static void log(String tag, String msg){
if(!isInTesting) return;
Log.d(tag==null?TAG:tag, msg);
}
}
and use these methods for all your logs, and when you are ready to generate final .apk/.aab just set isInTesting=false to disable all logs from this method.