Is it possible to read the Slog in android monitor? - android

In the android source code i see often line like Slog.v(WindowManagerService.TAG, "First window added to " + this + ", creating SurfaceSession"); How can i see those Slog under android monitor ? And what the difference between Slog and Log?

Short answer
You get logs logged with Slog by default, but they are "hidden" between other log messages. In order to get just the ones logged with Slog use this command:
adb logcat -b system
Long answer
I looked at source of Slog.java:
public static int v(String tag, String msg) {
return Log.println_native(Log.LOG_ID_SYSTEM, Log.VERBOSE, tag, msg);
}
Compared to Log.java:
public static int v(String tag, String msg) {
return println_native(LOG_ID_MAIN, VERBOSE, tag, msg);
}
As you can see, the difference is solely in LOG_ID parameter.
Then I looked at adb logcat -help:
...
-b <buffer> Request alternate ring buffer, 'main', 'system', 'radio',
'events', 'crash' or 'all'. Multiple -b parameters are
allowed and results are interleaved. The default is
-b main -b system -b crash.
...
I did not check any further - it looks like a safe bet that -b option corresponds to different LOG_ID params.

Related

android: How to create an hyperlink to a code line using Log.d

I am learning logging in android code using android studio and emulator
I found that the following command shows a traceback with hyperlink to the code location
Log.d("TAG", "Message with stack trace info", new Throwable());
the image of logcat with hyperlink is
How can i create only the hyperlink part in my log message, without any traceback output
Try this, for example:
import android.util.Log;
public class Logger {
public static void log(String tag, String message) {
String caller = getCallerInfo(new Throwable().getStackTrace());
Log.d(tag, message + caller);
}
private static String getCallerInfo(StackTraceElement[] stacks) {
if (stacks == null || stacks.length < 1) {
return "";
}
StackTraceElement stack = stacks[1];
return String.format(" (%s:%s)", stack.getFileName(), stack.getLineNumber());
}
}
And call it from any where in your code
Logger.log("Manowar", "Today is the good day to die");
As of now the answer by #Cao Mạnh Quang was not giving me the Hyperlink.
The specific String format required for it's generation is this:
return String.format(" %s(%s:%s)", traceE.getClassName(), traceE.getFileName(), traceE.getLineNumber());
which is just the same as:
return stackTraceElement.toString();
so you may as well just do that.
Nothing was working for me...
My guess is that...
This hyperlink is generated by a preconfigured String specification format.
this format follows the className + "(" + fileName + ":" + lineNumber + ")"
If any of those parameters are missing, the hyperlink will not be generated.
There are a couple questions that arise from this:
Is this specification hard coded as a consensus of each LogCat display (IDE side interacts directly with String)
OR
Is this specification hardcoded into the Java code itself? (Java side interprets String generates hyperlink signal + IDE side interprets hyperlink signal and generates it)
The difference between which of these options is the one, would imply whether hyperlink generation is possible simply by changing the required configuration for the Logcat to generate the link either at IDE config level... OR at Java level.
Maybe it is not possible, and this configuration format cannot be changed....
Btw I am sure there must be some super hacky way to achieve this, maybe a way not so intuitive... or maybe it just requires some digging on the IDE config options...

Android Logcat very strange behavior when getting empty string

So I came across something strange that made me loose some time. I have been trying to print the content of an ArrayList containing string elements, sometimes, an element might contain an empty string, which is fine and absolutely my intention.
So I have something like this:
List<String> l = new ArrayList<String>();
//adding strings in l, sometimes it's an empty string
for (int i=0; i < l.size(); i++) {
Log.w("element in l : ", l.get(i));
}
So here, when the loop is gonna hit the empty string, logcat is simply NOT going to print it out BUT (and here is the root of my confusion), if you have a message following the one that failed to display, suddenly the failed message is going to show up as if it contained the new logcat message. For example if you try logging an empty string like this
Log.w(TAG, <empty string here>);
Logcat is going to output nothing at first, then, when it has a NEW message to display this is what it prints out (in this case the new message is some warning about AudioTrack):
08-21 17:06:02.265 13047-13047/company.myapp W/TAG﹕ [ 08-21 17:06:05.411 766: 937 W/AudioTrack ]
AUDIO_OUTPUT_FLAG_FAST denied by client
I'm interested in knowing how this happens, maybe it can help someone else not getting super confused like I did. I suppose trying to log an empty string triggers some kind of buffer that sits there until it gets something to print, is this a bug?
That is an interesting question. I just tried this in LogRabbit and am able to see the same result.
I took a quick browse through the android source and see that Log.W(...) ends up in native code and getting handled in logd_write.c
This basically writes the data to /dev/log/main (or one of the other logs)
You can get those logs like this:
adb pull /dev/log/events .
adb pull /dev/log/main .
adb pull /dev/log/radio .
adb pull /dev/log/system .
You will need to press cntl-C otherwise the copy will happen forever.
Looking in the raw log in /dev/log/main I see the message does get logged:
<8b>F×U^_<8c>^Y^U^Emfl_MessageList^#Before Empty^#^R^#^#^#!z^#^#!z^#^#
<8b>F×U^_<8c>^Y^U^Emfl_MessageList^#^#^]^#^#^#!z^#^#!z^#^#
<8b>F×U^_ <8c>^Y^U^Emfl_MessageList^#After Empty^#7^#^#^#^#^E^#^#^Z^E^#^#
That gets decoded by struct found in logger.h So I think this is a problem in adb. pull the source code from here: (looks like quite a few of undocumented commands there)
This is the primary function
static int logcat(TransportType transport, const char* serial, int argc, const char** argv) {
char* log_tags = getenv("ANDROID_LOG_TAGS");
std::string quoted = escape_arg(log_tags == nullptr ? "" : log_tags);
std::string cmd = "shell:export ANDROID_LOG_TAGS=\"" + quoted + "\"; exec logcat";
if (!strcmp(argv[0], "longcat")) {
cmd += " -v long";
}
--argc;
++argv;
while (argc-- > 0) {
cmd += " " + escape_arg(*argv++);
}
return send_shell_command(transport, serial, cmd);
}
Looking in there I see that all logcat does is basically this:
adb shell
> exec logcat
So I think the root of the problem is in logcat itself. Logcat.cpp calls into log_read.c
Based on my quick read through things what I think is happening is the message is not terminated properly. The empty message does not show up until another message is appended and the first message overruns and shows the second message because it has the appropriate termination.

Android 5 - Redirect stdout to logcat

I am trying to run some GMock/GTest tests on Android. These all run fine, but there's no output, as GMock logs to stdout.
I've tried the following with no luck (likely because it's for the Dalvik VM, and they've done away with that in Android 5):
$ adb shell stop
$ adb shell setprop log.redirect-stdio true
$ adb shell start
When log.redirect-stdio is set to true, there is still no output from stdio to logcat.
I've also tried custom several streambuf implementations with std::cout.rdbuf to try to direct stdout to logcat with __android_log_print, but none of these have printed anything to logcat.
Has anyone successfully managed to redirect stdout to logcat in Android 5?
I can add more details (such as streambuf implementations I've tried) if needed.
This isn't really a solution to the problem of redirecting stdout to logcat, but I'm suggesting it as a workaround in case it helps someone.
You can redirect stdout to a file instead:
freopen("/data/data/com.your.package/files/out.txt", "w", stdout);
... // Call GMock which prints to the file instead
fclose(stdout)
We can then cat the file to see the logged test results. Sadly Android doesn't have tail so the logging isn't nicely available in real time. (Unless you're good at spamming cat)
Do it with the old Java way: (but I am using kotlin, can anyone suggest a cleaner version?)
documentation: System.setOut()
import java.io.OutputStream
import java.io.PrintStream
private const val TAG = "MyActivity"
class LogcatOutputStream: OutputStream(){
private var line_buffer: StringBuilder = StringBuilder()
override fun write(b: Int){
when(b){
'\n'.toInt() -> {
Log.i(TAG, line_buffer.toString())
line_buffer.setLength(0)
}
else -> line_buffer.append(b.toChar())
}
}
}
// put this somewhere in the code, like onCreate() as shown
class MainActivity: Activity(){
override fun onCreate(savedInstanceState: Bundle?){
// some other code
PrintStream(LoggerOutputStream()).let{
System.setOut(it)
System.setErr(it)
}
// some other code
}
}
// result:
println("Hello World") // which is effectively System.out.println in Java
// with have the below output in logcat
I/MyActivity(<pid>): Hello World
// as a reminder, you can filter logcat by tags
adb logcat MyActivity:D
// to only show logs tagged with 'MyActivity' (same value as 'TAG' above)

How to debug in .rs file with RenderScript?

I want to add some log in fall.rs (in:packages\wallpapers\Basic\src\com\android\wallpaper\fall). And the code is like this:
int root(void) {
rsDebug("===========root==================",0);
rsgClearColor(0.f, 0.f, 0.f, 1.f);
...
}
But my device can't print any log when I set live wallpaper. Although there are many examples about "rsDebug", but I can't find what's wrong when I use "rsDebug".
What kind of device is this (and what version of Android is it running)? Also, rsDebug logs at the "D" (Debug) level, so if you are filtering logcat, you might just not be seeing it. Do you see any messages tagged as "D"?
To see all renderscript debug messages from logcat, use:
adb logcat -s RenderScript:D
To filter for your specific application, add a prefix in the rsDebug message:
rsDebug("==MyApplication== my debug message", 0);
and filter in logcat:
adb logcat -s RenderScript:D | grep ==MyApplication==

How do i output a log in Android?

I have seen like a million different log functions , like log.i , log.v , log.d .
I just want to output a simple string on the log some times in my code to see if everything is working ok for debugging.
What is the clean way to do that?
You can use Log to track the logs in your application code.
Log API is for sending log output.
Generally, use the Log.v() Log.d() Log.i() Log.w() and Log.e() methods.
The order in terms of verbosity(wordiness), from least to most is ERROR, WARN, INFO, DEBUG, VERBOSE. Otherwise more or less they are same.
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.
example
String TAG = "value of i = ";
for(int i = 0; i<=10 i++)
{
Log.i(TAG, i+"");
}
this will print the 10 numbers in your log.i (info).
log.d
is for debug
log.e
is for error
and so on. here is a link to study more about log
Log.d("tag","the string youd like");
log.d is for the debug list of LogCat
When you change the letters after log. you are basically setting the severity of this log record:
I => Info
V => Verbose
D => Debug
E => Error
Take a look at this picture for all the different kinds of log records:
So use .d for simple debugging records like this:
Log.d (TAG, "the message you want to out put");
While I always set the TAG at the begging of the class like this:
static final String TAG = YouCurrentActivity.class.getSimpleName();
#donparalias great question
The Most easiest way:
public static final String LOG_TAG = "Facebook";
public void onFacebookError(FacebookError error)
{
Log.i(Facebook.LOG_TAG, "LoginListener onFacebookError " + error);
}
You can use one or all of these:
Log.d("tag","string"); :: Debug
Log.v("tag","string"); :: Verbose
Log.e("tag","string"); :: Error
Log.i("tag","string"); :: Info
there are different type of log.
I = Info
V = Verbose
D = Debug
E = Error
Example:
Log.d("tag","the string youd like");
Log.v("tag","the string youd like");
Log.e("tag","the string youd like");
Log.i("tag","the string youd like");

Categories

Resources