If I want to log a message that Android Studio will show in its console, I can do this:
import 'dart:developer';
void main() {
log('Hello world!');
runApp(const MyApp());
}
But if I package the app, run it and then look for it with logcat, it's not there.
flutter build apk
adb install build/app/outputs/flutter-apk/app-release.apk
adb shell am start -a android.intent.action.MAIN -n com.example.myapp/.MainActivity
adb logcat -t '12-08 00:00:00.000' | grep Hello
This results in empty output. So how do I log a system message, not just an IDE debug message?
Use print() or debugPrint().
You have two options for logging for your application. The first is to use stdout and stderr. Generally, this is done using print() statements, or by importing dart:io and invoking methods on stderr and stdout.
If you output too much at once, then Android sometimes discards some log lines. To avoid this, use debugPrint(), from Flutter’s foundation library.
Check Debugging Flutter apps programmatically for more info.
Also, if you want to get the log messages inside your flutter application check the plugin called logcat_monitor on pub.dev.
Its biggest advantage over the other logcat plugin is that it allows continuous monitoring of logcat messages.
Follows a screenshot example:
how to use
Add the dependencies:
dependencies:
logcat_monitor: ^0.0.4
Create a function to consume the logcat messages
void _mylistenStream(dynamic value) {
if (value is String) {
_logBuffer.writeln(value);
}
}
Register your function as a listener to get logs then use it in anyway within your app.
LogcatMonitor.addListen(_mylistenStream);
Start the logcat monitor passing the filter parameters as defined in logcat tool.
await LogcatMonitor.startMonitor("*.*");
my environment:
cpu:rk3288
os:android7.1
transfer method:sftp
I wrote android code to do these things below:
get the logcat with code "adb logcat -d -v time -f /mnt/sdcard/logcat.txt"
pull the file logcat.tx to the server with sftp
in 1st step I coding some java language with android studio like below, if anyone can help me, thanks!
Process p = Runtime.getRuntime().exec("adb logcat -d -v time -f /mnt/sdcard/logcat.txt");
error massage:
java.io.IOException: Cannot run program "adb": error=13, Permission denied
You can't use adb commands from inside the device, even if you somehow have it in the device you would need root permissions. The adb is the bridge between the PC and the device. Take a look here: https://developer.android.com/studio/command-line/adb
Although you probably can just remove the adb and use logcat directly, like:
Process p = Runtime.getRuntime().exec("logcat -d -v time -f /mnt/sdcard/logcat.txt");
Here you can see some more options about using the logcat command: Read logcat programmatically within application, including Reetpreet Brar's answer, that I think will be better for you:
Process pq=Runtime.getRuntime().exec("logcat v main"); //adapt the command for yourself
BufferedReader brq = new BufferedReader(new InputStreamReader(pq.getInputStream()));
String sq="";
while ((sq = brq.readLine()) != null)
{
//here you can do what you want with the log, like writing in a file to
//send to the server later.
}
Here you can choose methods to write your file: How to Read/Write String from a File in Android
Then, just send the file to the server.
I have an Android application utilizing RootTools v4.2 (the latest I know of) and I have followed their documentation on how to execute shell commands as root. Sometimes the commands execute just fine, other times the app crashes with the following exception.
java.lang.IllegalStateException: Unable to add commands to a closed shell
Here is the actual code the exception is being throw on:
RootTools.getShell(true).add(cmd);
So I'm wondering since the docs make no mention of this sort of problem if there is something else I'm doing wrong? Looking through the docs I see nothing on how to ensure I get an open shell before I start adding commands.
This code is working with me . Try to install the Library again may be its not vaild .
if(RootTools.isAccessGiven()){
try {
Shell shell = RootTools.getShell(true);
JavaCommand cmd = new JavaCommand(0,this,"input keyevent 26");
shell.add(cmd);
}
catch (Exception e){
Log.d("ERRORS : ",e.getMessage());
}
}
This question already has answers here:
Filter LogCat to get only the messages from My Application in Android?
(37 answers)
Closed 5 years ago.
How can I filter Android logcat output by application? I need this because when I attach a device, I can't find the output I want due to spam from other processes.
Edit: The original is below. When one Android Studio didn't exist. But if you want to filter on your entire application I would use pidcat for terminal viewing or Android Studio. Using pidcat instead of logcat then the tags don't need to be the application. You can just call it with pidcat com.your.application
You should use your own tag, look at: http://developer.android.com/reference/android/util/Log.html
Like.
Log.d("AlexeysActivity","what you want to log");
And then when you want to read the log use>
adb logcat -s AlexeysActivity
That filters out everything that doesn't use the same tag.
According to http://developer.android.com/tools/debugging/debugging-log.html:
Here's an example of a filter expression that suppresses all log messages except those with the tag "ActivityManager", at priority "Info" or above, and all log messages with tag "MyApp", with priority "Debug" or above:
adb logcat ActivityManager:I MyApp:D *:S
The final element in the above expression, *:S, sets the priority level for all tags to "silent", thus ensuring only log messages with "View" and "MyApp" are displayed.
V — Verbose (lowest priority)
D — Debug
I — Info
W — Warning
E — Error
F — Fatal
S — Silent (highest priority, on which nothing is ever printed)
Hi I got the solution by using this :
You have to execute this command from terminal. I got the result,
adb logcat | grep `adb shell ps | grep com.package | cut -c10-15`
I am working on Android Studio, there is a nice option to get the message using package name.
On the "Edit Filter Configuration" you can create a new filter by adding your package name on the "by package name".
If you could live with the fact that you log are coming from an extra terminal window, I could recommend pidcat (Take only the package name and tracks PID changes.)
Suppose your application named MyApp contains the following components.
MyActivity1
MyActivity2
MyActivity3
MyService
In order to filter the logging output from your application MyApp using logcat you would type the following.
adb logcat MyActivity1:v MyActivity2:v MyActivity3:v MyService:v *:s
However this requires you to know the TAG names for all of the components in your application rather than filtering using the application name MyApp. See logcat for specifics.
One solution to allow filtering at the application level would be to add a prefix to each of your unique TAG's.
MyAppActivity1
MyAppActivity2
MyAppActivity3
MyAppService
Now a wild card filter on the logcat output can be performed using the TAG prefix.
adb logcat | grep MyApp
The result will be the output from the entire application.
put this to applog.sh
#!/bin/sh
PACKAGE=$1
APPPID=`adb -d shell ps | grep "${PACKAGE}" | cut -c10-15 | sed -e 's/ //g'`
adb -d logcat -v long \
| tr -d '\r' | sed -e '/^\[.*\]/ {N; s/\n/ /}' | grep -v '^$' \
| grep " ${APPPID}:"
then:
applog.sh com.example.my.package
When we get some error from our application, Logcat will show session filter automatically. We can create session filter by self. Just add a new logcat filter, fill the filter name form. Then fill the by application name with your application package. (for example : my application is "Adukan" and the package is "com.adukan", so I fill by application name with application package "com.adukan")
If you use Eclipse you are able to filter by application just like it is possible with Android Studio as presented by shadmazumder.
Just go to logcat, click on Display Saved Filters view, then add new logcat filter. It will appear the following:
Then you add a name to the filter and, at by application name you specify the package of your application.
On my Windows 7 laptop, I use 'adb logcat | find "com.example.name"' to filter the system program related logcat output from the rest. The output from the logcat program is piped into the find command. Every line that contains 'com.example.name' is output to the window. The double quotes are part of the find command.
To include the output from my Log commands, I use the package name, here "com.example.name", as part of the first parameter in my Log commands like this:
Log.d("com.example.name activity1", "message");
Note: My Samsung Galaxy phone puts out a lot less program related output
than the Level 17 emulator.
I use to store it in a file:
int pid = android.os.Process.myPid();
File outputFile = new File(Environment.getExternalStorageDirectory() + "/logs/logcat.txt");
try {
String command = "logcat | grep " + pid + " > " + outputFile.getAbsolutePath();
Process p = Runtime.getRuntime().exec("su");
OutputStream os = p.getOutputStream();
os.write((command + "\n").getBytes("ASCII"));
} catch (IOException e) {
e.printStackTrace();
}
This is probably the simplest solution.
On top of a solution from Tom Mulcahy, you can further simplify it like below:
alias logcat="adb logcat | grep `adb shell ps | egrep '\bcom.your.package.name\b' | cut -c10-15`"
Usage is easy as normal alias. Just type the command in your shell:
logcat
The alias setup makes it handy. And the regex makes it robust for multi-process apps, assuming you care about the main process only.
Of coz you can set more aliases for each process as you please. Or use hegazy's solution. :)
In addition, if you want to set logging levels, it is
alias logcat-w="adb logcat *:W | grep `adb shell ps | egrep '\bcom.your.package.name\b' | cut -c10-15`"
Yes now you will get it automatically....
Update to AVD 14, where the logcat will automatic session filter
where it filter log in you specific app (package)
On the left in the logcat view you have the "Saved Filters" windows. Here you can add a new logcat filter by Application Name (for example, com.your.package)
What I usually do is have a separate filter by PID which would be the equivalent of the current session. But of course it changes every time you run the application. Not good, but it's the only way the have all the info about the app regardless of the log tag.
Generally, I do this command "adb shell ps" in prompt (allows to see processes running) and it's possible to discover aplication's pid. With this pid in hands, go to Eclipse and write pid:XXXX (XXXX is the application pid) then logs output is filtered by this application.
Or, in a easier way... in logcat view on Eclipse, search for any word related with your desired application, discover the pid, and then do a filter by pid "pid:XXXX".
you can achieve this in Eclipse logcat by entering the following to the search field.
app:com.example.myapp
com.example.myapp is the application package name.
my .bash_profile function, it may be of any use
logcat() {
if [ -z "$1" ]
then
echo "Process Id argument missing."; return
fi
pidFilter="\b$1\b"
pid=$(adb shell ps | egrep $pidFilter | cut -c10-15)
if [ -z "$pid" ]
then
echo "Process $1 is not running."; return
fi
adb logcat | grep $pid
}
alias logcat-myapp="logcat com.sample.myapp"
Usage:
$ logcat-myapp
$ logcat com.android.something.app
In Android Studio in the Android Monitor window:
1. Select the application you want to filter
2. Select "Show only selected application"
Use fully qualified class names for your log tags:
public class MyActivity extends Activity {
private static final String TAG = MyActivity.class.getName();
}
Then
Log.i(TAG, "hi");
Then use grep
adb logcat | grep com.myapp
The Android Device Monitor application available under sdk/tools/monitor has a logcat option to filter 'by Application Name' where you enter the application package name.
On Linux/Un*X/Cygwin you can get list of all tags in project (with appended :V after each) with this command (split because readability):
$ git grep 'String\s\+TAG\s*=\s*' | \
perl -ne 's/.*String\s+TAG\s*=\s*"?([^".]+).*;.*/$1:V/g && print ' | \
sort | xargs
AccelerometerListener:V ADNList:V Ashared:V AudioDialog:V BitmapUtils:V # ...
It covers tags defined both ways of defining tags:
private static final String TAG = "AudioDialog";
private static final String TAG = SipProfileDb.class.getSimpleName();
And then just use it for adb logcat.
I have found an app on the store which can show the name / process of a log.
Since Android Studio just puts a (?) on the logs being generated by the other processes, I found it useful to know which process is generating this log. But still this app is missing the filter by the process name. You can find it here.
use first parameter as your application name.
Log.d("your_Application_Name","message");
and in LogCat : create Filter ---> Filter Name & by Log Tag: is equal to 'your_Application_Name'
it will create new tab for your application.
Add your application's package in "Filter Name" by clicking on "+" button on left top corner in logcat.
to filter the logs on command line use the below script
adb logcat com.yourpackage:v
The log cat output can be filtered to only display messages from your package by using these arguments.
adb com.your.package:I *:s
Edit - I spoke to soon.
adb com.your.package:v
I would like to pull the log file from a device to my PC. How can I do that?
Logcollector is a good option but you need to install it first.
When I want to get the logfile to send by mail, I usually do the following:
connect the device to the pc.
Check that I already setup my os for that particular device.
Open a terminal
Run adb shell logcat > log.txt
I hope this code will help someone. It took me 2 days to figure out how to log from device, and then filter it:
public File extractLogToFileAndWeb(){
//set a file
Date datum = new Date();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd", Locale.ITALY);
String fullName = df.format(datum)+"appLog.log";
File file = new File (Environment.getExternalStorageDirectory(), fullName);
//clears a file
if(file.exists()){
file.delete();
}
//write log to file
int pid = android.os.Process.myPid();
try {
String command = String.format("logcat -d -v threadtime *:*");
Process process = Runtime.getRuntime().exec(command);
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
StringBuilder result = new StringBuilder();
String currentLine = null;
while ((currentLine = reader.readLine()) != null) {
if (currentLine != null && currentLine.contains(String.valueOf(pid))) {
result.append(currentLine);
result.append("\n");
}
}
FileWriter out = new FileWriter(file);
out.write(result.toString());
out.close();
//Runtime.getRuntime().exec("logcat -d -v time -f "+file.getAbsolutePath());
} catch (IOException e) {
Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show();
}
//clear the log
try {
Runtime.getRuntime().exec("logcat -c");
} catch (IOException e) {
Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show();
}
return file;
}
as pointed by #mehdok
add the permission to the manifest for reading logs
<uses-permission android:name="android.permission.READ_LOGS" />
I would use something of this sort :
$adb logcat -d > logcat.txt
The -d option dumps the entire circular buffer into the text file and if you are looking for a particular action/intent try
$adb logcat -d | grep 'com.whatever.you.are.looking.for' -B 100 -A 100 > shorterlog.txt
Hope this helps :)
For those not interested in USB debugging or using adb there is an easier solution. In Android 6 (Not sure about prior version) there is an option under developer tools: Take Bug Report
Clicking this option will prepare a bug report and prompt you to save it to drive or have it sent in email.
I found this to be the easiest way to get logs. I don't like to turn on USB debugging.
EDIT:
The internal log is a circular buffer in memory. There are actually a few such circular buffers for each of: radio, events, main. The default is main.
To obtain a copy of a buffer, one technique involves executing a command on the device and obtaining the output as a string variable.
SendLog is an open source App which does just this: http://www.l6n.org/android/sendlog.shtml
The key is to run logcat on the device in the embedded OS. It's not as hard as it sounds, just check out the open source app in the link.
Often I get the error "logcat read: Invalid argument". I had to clear the log, before reading from the log.
I do like this:
prompt> cd ~/Desktop
prompt> adb logcat -c
prompt> adb logcat | tee log.txt
I know it's an old question, but I believe still valid even in 2018.
There is an option to Take a bug report hidden in Developer options in every android device.
NOTE: This would dump whole system log
How to enable developer options? see: https://developer.android.com/studio/debug/dev-options
What works for me:
Restart your device (in order to create minimum garbage logs for developer to analyze)
Reproduce your bug
Go to Settings -> Developer options -> Take a bug report
Wait for Android system to collect the logs (watch the progressbar in notification)
Once it completes, tap the notification to share it (you can use gmail or whetever else)
how to read this?
open bugreport-1960-01-01-hh-mm-ss.txt
you probably want to look for something like this:
------ SYSTEM LOG (logcat -v threadtime -v printable -d *:v) ------
--------- beginning of crash
06-13 14:37:36.542 19294 19294 E AndroidRuntime: FATAL EXCEPTION: main
or:
------ SYSTEM LOG (logcat -v threadtime -v printable -d *:v) ------
--------- beginning of main
A simple way is to make your own log collector methods or even just an existing log collector app from the market.
For my apps I made a report functionality which sends the logs to my email (or even to another place - once you get the log you can do whether you want with it).
Here is a simple example about how to get the log file from a device:
http://code.google.com/p/android-log-collector/
Simple just run the following command to get the output to your terminal:
adb shell logcat
Two steps:
Generate the log
Load Gmail to send the log
.
Generate the log
File generateLog() {
File logFolder = new File(Environment.getExternalStorageDirectory(), "MyFolder");
if (!logFolder.exists()) {
logFolder.mkdir();
}
String filename = "myapp_log_" + new Date().getTime() + ".log";
File logFile = new File(logFolder, filename);
try {
String[] cmd = new String[] { "logcat", "-f", logFile.getAbsolutePath(), "-v", "time", "ActivityManager:W", "myapp:D" };
Runtime.getRuntime().exec(cmd);
Toaster.shortDebug("Log generated to: " + filename);
return logFile;
}
catch (IOException ioEx) {
ioEx.printStackTrace();
}
return null;
}
Load Gmail to send the log
File logFile = generateLog();
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(logFile));
intent.setType("multipart/");
startActivity(intent);
References for #1
https://stackoverflow.com/a/34883741/2162226
https://stackoverflow.com/a/3359857/2162226
~~
For #2 - there are many different answers out there for how to load the log file to view and send. Finally, the solution here actually worked to both:
load Gmail as an option
attaches the file successfully
Big thanks to https://stackoverflow.com/a/22367055/2162226 for the correctly working answer
Thanks to user1354692 I could made it more easy, with only one line! the one he has commented:
try {
File file = new File(Environment.getExternalStorageDirectory(), String.valueOf(System.currentTimeMillis()));
Runtime.getRuntime().exec("logcat -d -v time -f " + file.getAbsolutePath());}catch (IOException e){}
I have created a small library (.aar) to retrieve the logs by email. You can use it with Gmail accounts. It is pretty simple but works. You can get a copy from here
The site is in Spanish, but there is a PDF with an english version of the product description.
I hope it can help.
First make sure adb command is executable by setting PATH to android sdk platform-tools:
export PATH=/Users/espireinfolabs/Desktop/soft/android-sdk-mac_x86/platform-tools:$PATH
then run:
adb shell logcat > log.txt
OR first move to adb platform-tools:
cd /Users/user/Android/Tools/android-sdk-macosx/platform-tools
then run
./adb shell logcat > log.txt
I would use something like:
$ adb logcat --pid=$(adb shell pidof com.example.yourpackage)
which you can then redirect to a file
$ adb logcat --pid=$(adb shell pidof com.example.yourpackage) > log.txt
or if you also want to see it at stdout as well:
$ adb logcat --pid=$(adb shell pidof com.example.yourpackage) | tee log.txt