Setting Android Log Levels - android

Is it possible to set the log levels on a device that is not rooted?
so I want to change the device log level somehow to "debug". is this something that can be done?
since its not rooted i dont think setprop will work.
i can also not change the local.prop file since i do not have permissions to do so.
other than maybe getting lucky and finding a hidden menu that has the log levels in it.
is there a way for me to enhance the log level some other way?
thanks for the help.

setprop:
is temporary until you reboot your device, even on rooted phones.
you can persist properties through reboots if you write them into local.prop which is only possible on rooted phones.
some properties are read-only and can only be changed if you change some init files. That might be even impossible on rooted phones.
each device (or firmware) can have a different set of properties. A rooted phone wouldn't have automatically more.
Loglevels:
If the code that prints the log says Log.d() then it will be on "debug" level and you can't change that unless you change the code and recompile it. There is nothing that hides log messages if you execute a Log.? regardless of level.
the Android framework hides some log messages if you have a release build of your firmware. To show those you need to recompile your firmware as debug build. No chance to get those to show on a rooted phone either.
some messages are controlled by a local variable in the code like if (LOCAL_LOGV) Log.v(... - you need to change the code here to see those too.
some messages are controlled by Config.LOGV (= always false) see Config. No way to change the broken behaviour here either. You need to recompile.
some other logmessages are hidden until you enable a property:
example
public static final boolean DEBUG_SQL_CACHE =
Log.isLoggable("SQLiteCompiledSql", Log.VERBOSE);
// somewhere in code
if (SQLiteDebug.DEBUG_SQL_CACHE) {
Log.d(TAG, "secret message!");
}
if you do adb shell setprop log.tag.SQLiteCompiledSql VERBOSE you should see those messages popping up. Log#isLoggable()
There is no global loglevel I know of.

Let me suggest a tiny replacement for the standard log class (I'm the author)
https://github.com/zserge/log
It's backwards compatible, so you only need to modify your imports. Then you can set the minimal log level for your app via Log.level(Log.D) or Log.level(Log.W) etc, or you can disable logs using Log.useLog(false). No need to modify your existing logging code.
Despite of its small size this logger works with both, JVM and Android, allows you to skip the "tag" parameter, simplifies logging of multiple values separated by commas or using a format string. So it's really convenient, easy to migrate to, and only adds ~4 kilobytes to your APK size.

Related

How to debug low-level Android?

I need to debug some low-level stuff on an Android device. Specifically the Bluetooth Stack. So far I tried to figure out what's going on by just reading the source code and I saw that there are a lot of logging there which can be very helpful.
My problem is with how to enable them, the Bluetooth Stack has a file called bt_stack.conf which is located at /etc/bluetooth/, I saw that this is used by the code to determine which log subsystems to enable. The problem is that I can't edit this file because of permissions, so I can't enable the logs.
One option would be to Root the device and edit the file, and I don't mind doing so on my development phone, but I will soon have to debug it on other phones as well. There must be better way to debug low level Android stuff other then rooting the phone using third-party tools.
How is it done usually by system level Android developers?

Connect to RS232 from Android - No permission dialog or shell command

Objective
I'm developing a custom app for internal use on a rooted android mini-pc.
The goal (between others... so...many...others...) is to be able to turn on and off a tv using the serial port embeeded on the tv.
I'm using an FTDI UART RS232 serial usb cable for it.
Status
The application is working right now, using an android library (serial-driver) i can communicate with the tv, but the problem is that the device asks for permissions every install (and sometimes, weirdly, again on the same device), so it needs to be improved.
Issue
Since the device doesn't have mouse or keyboard by default, when this happens someone has to click the buttons, and since the device is normally hidden behind the screen, it can be really annoying.
My two bits
This problem, i feel, can be solved by two methods, but i still haven't been able to make them work.
Since the device is rooted, i might be able to modify an unknown (to me) parameter that allows me to bypass the permission request. For this i have tried to make an intent filter for the usb device, and to rewrite the interface that controlls this behaviour, both without success. Is there a way to make this android version more lenient about permissions?
I use for other reasons SuperSU inside the app, so i can use the full width of the might shell power. Using this i've been trying to send commands manually to the device (/dev/bus/usb/00X/00Y), but this haven't worked. My theory is that it's beacuse of the permissions of the device path, but even doing an unhealthy chmod 777 i cannot have them working.
So, that's my problem right now. I hope someone here can help me.
Additional data
Running: Custom Android 4.4.2 (Cannot be changed)
Needs to be doable solely from within the apk (but it can use shell commands)
We don't have the manufacturer signature to install it as a system app
We can use only one app, so i cannot have another one to move this one to /sys/apps, and i don't know if an app can do that to itself.
using Busybox stty -F /dev/.../ returns "Operation not permitted"

Access old/past logs from logcat or Android

Is it possible to get old logs (such as logs of one hour or one day before) of an Android device?
I am asking this because sometimes testers encounter some errors. The Android developer says that the error is related to the device's hardware. To prove his claim, he has to show the error inside the logs. But he says that when attaching an Android device to his computer, he cannot see past logs.
I'm not sure how it was back then, but with current Android versions you can use adb logcat to get at older logs. On my device this is limited to the current boot, but I understand that on some devices older logs may be accessible.
adb logcat --help will have all the details (note that your device must be connected even for the help functionality), here's an example usage:
To get all the logs from today at 4PM:
adb logcat -d -T "2022-01-27 16:00:00.000"
Or:
adb logcat -d -T "01-27 16:00:00.000"
As Year may not be valid in some ADB versions, with message:
-T "2022-01-27 16:00:00.000" not in "%m-%d %H:%M:%S.%q" time format
You can't, but there are libraries like ACRA which will automatically send you detailed crash reports including the user LogCat if you want (disabled by default).
If you don't want to use a library, when an error occurs you can also write the content of the Logcat to a file that your testers can easily find (like in a log folder of the SD card). It shouldn't be very hard to implement.
I think there is no way you can access the past logs, unless you save them.
Ask your testers to save the Log the moment they see the issue.
With the logger buffer size option on the developer option, one could choose the logger size for each buffer. There are quite a several logger sizes available and they include 64k, 256k, 1M, 4M, and 16M. I recommend only increasing the buffer size for debugging purposes, as the logging area is a ring buffer, this helps to capture old logs to some extent once we encounter the glitch that we're looking out for.

Prevent Android device rebooting when app is re/uninstalled

I'm debugging an Android app on an HTC tablet and every time I uninstall the app, the device reboots. Uninstallation also happens as part of trying a new build, so any changes to the app require a reboot before testing. This is predictably aggravating for development.
The problem sounds similar to that described here except that there's no mystery about it in my case. Uninstall => reboot. Change app and debug through Eclipse & adb => reboot. Wiping all the data on the device as suggested in the only answer to the similar problem is not desirable, especially as there's not much indication that even that poster saw it as anything other than the tech equivalent of sacrificing a chicken.
Can anyone tell me why this is happening and how to prevent it?
I'm not offering this as an answer (at least not yet) but need more space than a comment provides to brainstorm about how to investigate this
I'd be tempted to take a safe "hello world" type app and merge it into the project as its own activity. Then comment out all the real functionality from the manifest and java files. That should leave only the hello world and the resources. See if the device survives uninstalling that after a run - if not, guess you might have to suspect the resources.
This should do the commenting - or you could just remove files wholesale from the tree
find . -name "*.java" | xargs -I f sed -i 's/^/\/\//' f
(Some editors will do block comment/uncomment, emacs will do arbitrary operations on a column of a file.)
Then I'd either uncomment the skeleton of the real activity - ie, all the onCreate, onStart, etc methods with no operations in them, and restore that activity to the manifest. Or else I'd restore functional java code, but leave the activity out of the manifest. You could then incrementally add more and more functionality until you get a crash.
If you have any ndk libs or even java libs you could play a similar game with those.
You can also try to run logcat during the uninstall and see if any messages make it out before the device hangs up on you.
Oh - and a major question, is this a kernel reboot, or an android runtime restart? In the later case, adb & logcat should probably survive, and /proc/uptime will not be reset to a small number.
If you get it down to a suspect operation, it would be great if you could post a description of that - I have a similar device in my test collection and would be curious to see if it has the same apparent bug. Also HTC has a number of "Developer Evangelists" who might be a point of contact.

Android logging levels

I'm having a little difficulty configuring Android logging. Here's what my code looks like:
if (Log.isLoggable("MY_TAG", Log.VERBOSE)) {
Log.v("MY_TAG", "Here's a log message");
}
Pretty simple, right?
However, I'm having quite a bit of difficulty getting the Log.isLoggable("MY_TAG", Log.VERBOSE) to return true.
Per http://developer.android.com/reference/android/util/Log.html, I tried adding a local.prop file to the /data/ directory which looks like this:
log.tag.MY_TAG=VERBOSE
but no luck. I also tried:
System.setProperty("log.tag.MY_TAG", String.valueOf(Log.VERBOSE));
but that doesn't work either.
Any ideas on what I'm doing wrong here? I'm running Android 2.1-update1 on a Nexus 1 if that makes any difference.
Try
adb shell setprop log.tag.MyAppTag VERBOSE
It seems that later versions of Android want /data/local.prop to be writable by root only. The adb push command appears to initially create files with granting everyone read/write access (because default file mask is 777). Android, wisely, ignores /data/local.prop since this can be a security risk.
I have only experimented with Android 2.3.3, and 4.1.2. The former has no issues with reading a local.prop that is world writable, while the latter appears to silently ignore the file's contents.
Creating a local.prop file as described in the original question:
log.tag.MY_TAG=VERBOSE
And then pushing it onto the device as follows seems to do the trick:
adb push local.prop /data/local.prop
adb shell chmod 644 /data/local.prop
adb shell chown root.root /data/local.prop
adb reboot
You can double check to make sure that the values in local.prop were read by executing:
adb shell getprop | grep log.tag
So in summary:
/data/local.prop is only read during boot.
Later versions of Android appear to require that the permissions on the /data/local.prop file must be properly set, or it will not be read. The file must be writable by root only.
Using adb shell setprop log.tag.MyAppTag VERBOSE also work. The issue is that the property values are lost after a reboot.
An important goal is to not ship a production app with a ton of log calls left in it, increasing its size, and even possibly even impacting its performance.
To do this, my recommendation is to put these constants at the top of each class that is going to have log calls:
static final boolean DEBUG = false;
static final String TAG = "<MyClass>"
Now where you log, do this:
if (DEBUG) Log.v(TAG, "Something");
Turn on your logs by changing the DEBUG constant to true. (If you want, you could have one class with these statics for all of your app's code to use... That makes sense for a small app, but as things get large it is nice to decide which parts to turn logging on.)
By doing this, when you build your app with DEBUG = false, all of your logging code not only isn't executed, but is completely stripped out of your app. This is nice because it allows you to leave fairly extensive logging in your code to be turned on when you need it, without worrying about how that will impact the size of your shipping app. Basically just throw logs in wherever you need them and don't worry about leaving them in.
This is the approach that a lot of the Android framework takes. For example, the Activity ManagerService.
This has those constants at the top, and various log lines sprinkled throughout based on them. (And a bunch of other sub-debug constants for various aspects of it, since this file is ridiculously stupidly large.)

Categories

Resources