I have a program to read logs and based on certain filters save logs to database.
private static final String LOGCAT_EVENTS_CMD = "logcat -b events -v time";
try {
EventProcess = Runtime.getRuntime().exec(LOGCAT_EVENTS_CMD);
BufferedReader eventBufferedReader = new BufferedReader(new InputStreamReader(
EventProcess.getInputStream()));
String line = "";
while ((line = eventBufferedReader.readLine()) != null) {
onLogFetched(line);
}
} catch (Exception e) {
e.printStackTrace();
}
But sometimes android kills my application and my application restarts automatically START_STICKY. In this case already read logs are read again and again saved to database.
I want a piece of code which will restrict/identify already read logs.
For clearing the log buffer in android we have command as:-
adb logcat -c
And also I can't clear log buffer before start of process as it will clear logs which was not recorded.(logs generated between kill of App and start of App/Monitoring log Process)
Related
I am trying to start internal logs within my android devices without having to go directly into the adb shell. I have to script this process so I can run it from a program.
I am aware that you can take the following steps to start internal logs on an android device:
Open a cmd prompt
enter 'adb shell'
enter 'logcat -v time -f /sdcard/LogFile.txt&'
The above will start a logcat process within the actual device. I can now unplug my phone from the computer and move around then come back and collect the logs once my test is complete. It's crucial that I am able to start this process and be able to unplug my device with the logs still running.
To my knowledge running 'adb shell' in front of any command would run as if it were in the shell. Therefore by this logic I tried running:
Method 1:
'adb shell logcat -v time -f /sdcard/LogFile.txt&'
This command did properly start the log on the device which is great. However, once I unplug from my computer the logcat process stops.
Method 2:
'adb shell "logcat -v time -f /sdcard/LogFile.txt&" '
This didn't seem to do anything at all on the phone and I don't know why.
Method 3
I have tried the scripting method as well where I run a Batch file that contains only:
'adb shell < Commands.txt'
Where commands has the single line:
'logcat -v time -f /sdcard/LogFile.txt&'
This doesn't appear to do anything. It appears to send the command once the window comes up but doesn't actually perform the action.
Any help on this topic would be greatly appreciated. Thanks.
you can use this code in application class. so when app will launch this code will start executing. and it will create new log file according to current time.
Thread t = new Thread(new Runnable() {
public void run() {
while (collectLog == true) {
try {
Thread.sleep(1000 * 60 * 6);
StringBuilder log = null;
Date now = new Date();
String fileName = formatter.format(now);
File file = new File(dir, fileName + "_logcat2.txt");
try {
Process process = Runtime.getRuntime().exec("logcat -d");// d will dump logs
//Process process = Runtime.getRuntime().exec("logcat -c"); c will clear logs
// process = Runtime.getRuntime().exec("logcat -f " + file);
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
log = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
log.append(line);
log.append("\n");
}
} catch (IOException e) {
}
try {
//to write logcat in text file
FileOutputStream fOut = new FileOutputStream(file);
OutputStreamWriter osw = new OutputStreamWriter(fOut)
// Write the string to the file
osw.append(log.toString());
osw.flush();
osw.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t.start();
I have an application and I'd like to collect the LogCat messages of a specified level and tag.
Can I somehow get the accumulated messages at some point? I don't want to collect the messages one by one, it should be the sum of them like when I use adb to read the actual log. Is this possible?
Try this: Note that in Android 4 you will only see the log messages that were written by your own app unless you have root access.
public static String getLog(Context c) {
try {
Process process = Runtime.getRuntime().exec("logcat -d");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
StringBuilder log = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
log.append(line);
log.append("\n");
}
return log.toString();
} catch (IOException e) {
return null;
}
}
Why not just write them to a file instead? LogCat is really for real-time logs. There are lots of good quality logging packages that can log to a file if that's what you want to do.
Just as an example:
How to write logs in text file when using java.util.logging.Logger
I want get complete system log. Currently, I'm using below code to get system log
try {
final Process process = Runtime.getRuntime().exec("logcat -d -v threadtime *:I");
final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(
process.getInputStream()));
String line;
while ((line = bufferedReader.readLine()) != null) {
lineList.add(line);
}
} catch (final IOException e) {
Log.e(e.toString());
}
I'm able to get system log successfully using above code. It gives only last 30 min log. But, I want complete system log from my application launch. Is it possible to write system log to our private file?
To write continuously to a file, try this:
... exec( "logcat -f cachedirectory/logfile.txt -v threadtime" );
See the -f option in http://developer.android.com/tools/help/logcat.html.
I am trying to read from the logcat output in my app. I am able to read in correctly, but it goes on reading it in endless loop. Somehow there seems no way to detect the end of stream.
Not sure what I am doing wrong.
Here is my code:
String baseCommand = "logcat -v time MyTag:D *:S";
Process process = null;
try {
process = Runtime.getRuntime().exec(baseCommand);
InputStreamReader reader = new InputStreamReader(process.getInputStream());
BufferedReader bufferedReader = new BufferedReader(reader);
String line;
while ((line = bufferedReader.readLine()) != null) {
Log.d("SomeOtherTag", line); //This line executes endlessly
}
} catch (IOException e) {
Log.e(DEBUG_TAG, "error in logging");
e.printStackTrace();
}
Logcat doesn't exit so the buffer is blocked.
Use 'logcat -d' in order to dump the log and then exit.
Hope this still helps, Yaron
Not positive but I believe you need to pass the logcat call if it has args in a String[] so it would be something like
String[] baseCommand = {"logcat", "-v", "time", "MyTag:D", "*:S"};
then the rest of your code.
The single string call is just the program name, not the args.
For the purposes of monitoring Battery usage etc. I have code that executes a few dumpsys calls, reads and parses the output to extract data that I am interested in.
dumpsys battery, dumpsys statusbar, and dumpsys power all give me an error message for output like "Permission Denial: can't dump Battery service from pid..."
Also, when the application is launched there is an item in the log tagged with "PackageManager" statingNot granting permission android.permissionDUMP to package.... (protectionLevel = 3 ...)"
However, dumpsys cpuinfo and dumpsys netstat work and give me the correct output, which seems to be inconsistent.
I am able to generate dumpsys battery and the like from the adb shell, but when I try to call it programmatically it does not work.
I have tried running this on a HTC Nexus One phone as well as the emulator and get the same results for each. The weird thing is that this code worked on my Nexus One a day ago (before I upgraded from 2.2 to 2.3), and now it does not. Is this because of the upgrade?
An example of the code I am trying to run is as follows:
String command = "dumpsys battery";
try {
String s = null;
Process process = Runtime.getRuntime().exec(command);
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(process.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(process.getErrorStream()));
// read the output from the command
System.out.println("Here is the standard output of the command:\n");
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
// read any errors from the attempted command
System.out.println("Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
How do I get the dumpsys to give me the correct output programmatically and how to I get the dump permission to be granted?
*The Nexus One is not rooted and I would like to get this working without having to root it for the purposes of my project
Thank you for your help
Regular applications cannot get the DUMP permission. It is reserved to system applications.
android.permission.Dump is protected by system, signature, and development permission protection levels. Line 1993 of the source shows you this. If your APK is signed with the framework cert, is in the priv-app directory, or debuggable (see below) you can use the pm service to grant the permission, but otherwise the code specifically prevents what you're asking for (line 2624 of source).
Debuggable APKs can be created through setting the debuggable attribute on a buildType via build.gradle. Sample Android DSL:
android {
...
buildTypes {
debug {
debuggable true
...
}
quality_assurance {
debuggable true
}
...
}
If your handset had been rooted, 'dumpsys activity' will work on Android2.3:
private static void dumpIT0(String sCmd) {
try {
String s = null;
String command = "su -c " + sCmd;
Process process = Runtime.getRuntime().exec(command);
BufferedReader stdInput = new BufferedReader(new InputStreamReader(
process.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(
process.getErrorStream()));
// read the output from the command
System.out.println("Here is the standard output of the command:\n");
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
// read any errors from the attempted command
System.out.println("Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
} catch (IOException e) {
Log.e(TAG, "IOException: " + e);
}
}
sCmd = "dumpsys activity";