Android - not all logs appear in a logcat output - android

I am using windows cmd terminal to output logs of my application using following command:
adb.exe logcat | find "%part_of_my_apps_name%"
however, not all logs appear in the output. Only messages like this one:
I/AppService(10597): Received start id 1: Intent { cmp=package_name/.AppService(has extras) }
And in my AppService I have the following code:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "Received start id " + startId + ": " + intent);
Log.i(TAG, "Test");
So what am I doing wrong?
UPD: I asked a bit wrong question. I actually used part of my app's name, not package, so it MUST appear in the log output.

Depending on what your TAG variable is, you use the command
adb.exe logcat -s "[tagname]"
For example if in my code, my TAG was declared as:
public static final String TAG = "com.myapp";
my LogCat would be
adb.exe logcat -s "com.myapp"
It also appears the quotes are optional.

Logcat output is not associated with the package name, but with the string TAG you are using in your code. You could change all your tags to be your package name, or you could explicitly add your package name to the message in each Log.i/w/e/v() line, and then you will get the behavior you want. However, I would actually for with #A--C suggestion instead, as it allows you to have more granular filtering of the output of specific classes only.

I used a part of app's name, however, because "find" is basically case sensitive it did show me only that particular output ( name appeared in package name ) , so I came up with the following command:
adb.exe logcat -v time | find "%part_of_my_apps_name%" /I

Related

Setting custom filter in Logcat

I have a method to call Log.d that I use throughout an app for debugging. I noticed that there is an Edit Filter Configuration option in the Logcat submenu there which lets me create a custom filter for a specific Log TAG.
Below is the method I use to call the Log.d. I have tried to add it myself but it didn't show them in the Logcat.
private static final String TAG = "LOG ENTRY: ";
public void LOG_ENTRY(String what) {
Log.d(TAG, what);
}
Does anyone know how to implement this step by step? Is it also possible to include the error messages in the custom filter?
In the attached image (Android Studio "Create New Logcat Filter" dialog) in the question, enter the following values,
Filter name: Any name as per your preference.
In Log Tag field: "LOG ENTRY: " (The Log TAG)(Without the double quotes)
In Package Name: Enter the package name of your application.
In Log Level: Select the "debug" option from the drop-down, since you are using Log.d which is for debugging.
PID & Log message fields can be empty.
You can uncheck the regex option in all the 3 checkboxes.
This should let you filter the logcat as per your requirement.
I was able to solve this by switching the Log Level to verbose and removing the space from the TAG.
private static final String TAG = "LOG";
public void LOG_ENTRY(String what) {
Log.d(TAG, what);
}

uiDevice.executeShellCommand("pm uninstall " + Constants.APP_PACKAGE); does not return output string from shell

I want to uninstall an apk when I execute UiAutomator test.
I am using below command for that and it is working fine. It uninstall the app from the device.
String output = uiDevice.executeShellCommand("pm uninstall " + Constants.APP_PACKAGE);
However, when I check the value of output string it is blank. I want to check if the app is uninstalled or not to perform next steps in the script. How to get the output of the executeShellCommand in this case?
Assumng you are using Uiautomator2.0 . If then I wonder how above code worked without exception. Is uiDevice an instrumentation instance ? UiDevice.getInstance(getInstrumentation()) has a public method executeShellCommand which returns a String.
Try below code-
private UiDevice mDevice = UiDevice.getInstance(getInstrumentation());
String output = mDevice.executeShellCommand("pm uninstall " + Constants.APP_PACKAGE);
Exact code will give Success in case of successful uninstall.

Using adb to broadcast intent with extras

background
i wish to send a broadcast intent (even with root permission) that an app was removed, and for this, i have to broadcast an intent with extras.
problem
i just can't figure out what am i missing, since i can't find the correct way to do it.
what i've done so far
i think I've found where on android the OS broadcasts the intent (the file is called "PackageManagerService.java" ). I've also found out how to get the correct permission using root (and it works) , and also how to put extra data into the intent of the broadcast (link here) , all using the "adb" tool.
now i have to put all of the pieces together.
the code so far is :
String packageOfCurrentApp=..., packageOfAppToReportAbout=... ;
try
{
final java.lang.Process p=
Runtime.getRuntime().exec(
String.format("su -c pm grant %s android.permission.BROADCAST_PACKAGE_REMOVED",packageOfCurrentApp));
final int res=p.waitFor();
Logger.log(LogLevel.DEBUG,"got permission:"+(res==0));
if(res==0)
{
final java.lang.Process p2=Runtime.getRuntime().exec(//
"am broadcast -a android.intent.action.PACKAGE_REMOVED "+//
"--ei android.intent.extra.UID -1 "+//
"-eez android.intent.extra.DATA_REMOVED true"+//
" -d com.syncme.syncmeapp ");
final int res2=p2.waitFor();
Logger.log(LogLevel.DEBUG,"broadcast?"+(res2==0));
}
}
catch(final Exception e)
{
Logger.log(LogLevel.DEBUG,"error:"+e);
}
the permission getting works, but the broadcasting doesn't.
question
what is wrong with the code? what is missing? how can i fix it?
i would also like to know how to do the same via the shell (of the PC).
Like for battery :-
we use below
m broadcast "intent:#Intent;action=android.intent.action.BATTERY_CHANGED;i.status=5;i.voltage=4155;i.level=100;end"
Please refer to the source code of PackageManagerService.java
Bundle extras = new Bundle(1);
extras.putInt(Intent.EXTRA_UID, removedUid);
extras.putBoolean(Intent.EXTRA_DATA_REMOVED, false);
sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
extras, null, null);

Rather odd behaviour of Log

I wrote a very simple Android Activity:
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("TAG", "onCreate() Log call 1");
Log.d("SMS", "onCreate() Log call 2");
Log.d("TEST", "onCreate() Log call 3");
finish();
}
#Override
protected void onDestroy() {
Log.d("TAG", "onDestroy() Log call 1");
Log.d("SMS", "onDestroy() Log call 2");
Log.d("TEST", "onDestroy() Log call 3");
super.onDestroy();
}
}
I would expect this to generate 6 log messages (3 from onCreate(), 3 from onDestroy()). Here is the logcat:
04-14 17:31:58.363: D/TAG(18084): onCreate() Log call 1
04-14 17:31:58.363: D/TEST(18084): onCreate() Log call 3
04-14 17:31:59.905: D/TAG(18084): onDestroy() Log call 1
04-14 17:31:59.905: D/TEST(18084): onDestroy() Log call 3
As can be seen, the lines with the tag "SMS" don't get through. This is not, as far as I can tell a documented thing. The question is, why?
EDIT: More details on the answer.
A rather good answer is given below by Matthew Burke. In short, on the basis of the source code for logd_write.c, it seems that:
Log requests with the following tags are automatically redirected to the radio log:
HTC_RIL
tags starting with RIL
AT
GSM
STK
CDMA
PHONE
SMS
No Log requests are redirected to the events log (or the system log, see also http://elinux.org/Android_Logging_System)
All other Log requests go to the main log, the one that is usually monitored.
I should have read the documentation for logcat before I started hunting through source. According to logcat's documentation:
The Android logging system keeps multiple circular buffers for log messages, and not all of the log messages are sent to the default circular buffer.
Messages with a tag of SMS are sent to the radio buffer, not the main buffer. Hence you won't see them unless you go out of your way to do so. If you run the command:
adb logcat -b radio
you should see your missing log messages. The above information can be found in https://developer.android.com/tools/debugging/debugging-log.html.
Now, for those of you interested in code spelunking, below is my original answer:
The methods in the Log class are all wrappers around println_native which is a JNI method.
println_native performs some validation of its parameters and then calls __android_log_buf_write.
Now this latter method compares the tag parameter (from the original Log.d call) against several hard-coded strings (with the tag SMS being one of this list) and if it finds a match, winds up writing the log message to a different file!
By the way, other tags that get rerouted are GSM, STK, PHONE, CDMA, and a few others.
Relevant source can be read in
http://www.java2s.com/Open-Source/Android/android-core/platform-frameworks-base/android/util/Log.java.htm
https://pdroid.googlecode.com/svn/android-2.3.4_r1/trunk/frameworks/base/core/jni/android_util_Log.cpp
https://in-the-box.googlecode.com/svn-history/r4/trunk/InTheBoxSim/liblog/logd_write.c
http://www.takatan.net/lxr/source/drivers/staging/android/logger.h#L33
These aren't the official links and may disappear at some point. I'll try and track down the official links and edit this later this evening.
EDIT Ignore this, I'm apparently quite off base according to this.
So I thought this was interesting, and after digging through the source, I ended up finding out about Log.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. '
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.=' and place that in /data/local.prop.
Parameters
tag
The tag to check. level The level to check. Returns
Whether or not that this is allowed to be logged.
Apparently some tags are not allowed at certain log levels, seemingly defined in /data/local.prop, but there must be some system level properties file I haven't found yet. You can check against it using something like this, though:
boolean isLoggableV = Log.isLoggable("SMS", Log.VERBOSE);
boolean isLoggableD = Log.isLoggable("SMS", Log.DEBUG);
boolean isLoggableI = Log.isLoggable("SMS", Log.INFO);
boolean isLoggableW = Log.isLoggable("SMS", Log.WARN);
boolean isLoggableE = Log.isLoggable("SMS", Log.ERROR);
boolean isLoggableA = Log.isLoggable("SMS", Log.ASSERT);
Log.v("LogTest", String.format("Verbose: %b Debug: %b Info: %b Warn: %b Error: %b Assert: %b", isLoggableV, isLoggableD, isLoggableI, isLoggableW, isLoggableE, isLoggableA));
Which for me returned the following:
Verbose: false Debug: false Info: true Warn: true Error: true Assert: true
So you can log the tag SMS at a log level of INFO and above, but not VERBOSE or DEBUG.
I have to assume this is to prevent applications from accidentally logging personal information, but it seems like a fairly crude way of doing so.

Filtering Logcat Logs on commandline

public static final TAG = "Legendry Eagle";
Issue: I want to see logs of "Legendry Eagle" from the commandline.
I tried:
adb logcat -s "Legendry Eagle"
adb logcat -s <Legendry Eagle>
But Still it is not working.
If you only want to show logcat for a specific TAG, do it like this:
adb logcat YourTAGHere:Priority *:S
The *:S is important, as it sets all other tags to silent. If I want to track only my MainActivity tag at Verbose level, the syntax would look like this.
adb logcat MainActivity:V *:S
Edit:
I found no good way of filtering out tags with spaces. LegendryEagle works fine, but I was not able to filter out Legendry Eagle
If the standard adb logcat -s tagname doesn't work, you can always pipe the output of adb to find to filter what you need, something like
adb logcat | find "Legendry Eagle"
This passes the entire logcat to DOS find command, which in turn filters out rows containing Legendry Eagle string.
adb logcat | grep "your tag"
will only display logs with "your tag"
Answer is very simple . Please remove space between two words and try again.
public static final TAG = "LegendryEagle";
adb logcat -s "LegendryEagle"
and see the logcat . You got your answer.
use this command adb logcat *:W and read this. http://developer.android.com/tools/debugging/debugging-log.html
Assuming you are using Eagle as the logging tag, use this:
adb logcat Eagle:* *:s
as I understand the Eagle:* means to turn on all logs for the Eagle tag, and the *:s means to make all other tags silent
I personally find the eclipse logcat view much easier to use than the command line, it has different colors for different levels of logs, and you can create a filter and save it, it'll stay there forever until you delete that filter

Categories

Resources