Skip to content

Commit

Permalink
Merge pull request #426 from F43nd1r/collectorutil
Browse files Browse the repository at this point in the history
Extract read of streams into strings
  • Loading branch information
william-ferguson-au committed Apr 9, 2016
2 parents 2d25919 + 7c42eab commit 5932c05
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 83 deletions.
25 changes: 0 additions & 25 deletions src/main/java/org/acra/collector/CollectorUtil.java

This file was deleted.

18 changes: 2 additions & 16 deletions src/main/java/org/acra/collector/DumpSysCollector.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,9 @@
import android.support.annotation.NonNull;

import org.acra.ACRA;
import org.acra.ACRAConstants;
import org.acra.util.IOUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

Expand All @@ -47,31 +45,19 @@ private DumpSysCollector(){}
public static String collectMemInfo() {

final StringBuilder meminfo = new StringBuilder();
BufferedReader bufferedReader = null;
try {
final List<String> commandLine = new ArrayList<String>();
commandLine.add("dumpsys");
commandLine.add("meminfo");
commandLine.add(Integer.toString(android.os.Process.myPid()));

final Process process = Runtime.getRuntime().exec(commandLine.toArray(new String[commandLine.size()]));
bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()), ACRAConstants.DEFAULT_BUFFER_SIZE_IN_BYTES);

while (true) {
final String line = bufferedReader.readLine();
if (line == null) {
break;
}
meminfo.append(line);
meminfo.append("\n");
}
meminfo.append(IOUtils.streamToString(process.getInputStream()));

} catch (IOException e) {
ACRA.log.e(LOG_TAG, "DumpSysCollector.meminfo could not retrieve data", e);
}

CollectorUtil.safeClose(bufferedReader);

return meminfo.toString();
}
}
32 changes: 10 additions & 22 deletions src/main/java/org/acra/collector/LogCatCollector.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,15 @@
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import com.android.internal.util.Predicate;

import org.acra.ACRA;
import org.acra.ACRAConstants;
import org.acra.annotation.ReportsCrashes;
import org.acra.config.ACRAConfiguration;
import org.acra.util.BoundedLinkedList;
import org.acra.util.IOUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
Expand Down Expand Up @@ -97,43 +96,32 @@ public String collectLogCat(@NonNull ACRAConfiguration config, @Nullable String
final LinkedList<String> logcatBuf = new BoundedLinkedList<String>(tailCount > 0 ? tailCount
: DEFAULT_TAIL_COUNT);
commandLine.addAll(logcatArgumentsList);

BufferedReader bufferedReader = null;

try {
final Process process = Runtime.getRuntime().exec(commandLine.toArray(new String[commandLine.size()]));
bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()), ACRAConstants.DEFAULT_BUFFER_SIZE_IN_BYTES);

if (ACRA.DEV_LOGGING) ACRA.log.d(LOG_TAG, "Retrieving logcat output...");

// Dump stderr to null
new Thread(new Runnable() {
public void run() {
try {
InputStream stderr = process.getErrorStream();
byte[] dummy = new byte[ACRAConstants.DEFAULT_BUFFER_SIZE_IN_BYTES];
//noinspection StatementWithEmptyBody
while (stderr.read(dummy) >= 0)
;
IOUtils.streamToString(process.getErrorStream());
} catch (IOException ignored) {
}
}
}).start();

while (true) {
final String line = bufferedReader.readLine();
if (line == null) {
break;
}
if (myPidStr == null || line.contains(myPidStr)) {
logcatBuf.add(line + "\n");
final String finalMyPidStr = myPidStr;
logcatBuf.add(IOUtils.streamToString(process.getInputStream(), new Predicate<String>() {
@Override
public boolean apply(String s) {
return finalMyPidStr == null || s.contains(finalMyPidStr);
}
}
}));

} catch (IOException e) {
ACRA.log.e(LOG_TAG, "LogCatCollector.collectLogCat could not retrieve data.", e);
} finally {
CollectorUtil.safeClose(bufferedReader);
}

return logcatBuf.toString();
Expand Down
21 changes: 5 additions & 16 deletions src/main/java/org/acra/collector/LogFileCollector.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import android.support.annotation.NonNull;

import org.acra.ACRA;
import org.acra.util.BoundedLinkedList;
import org.acra.util.IOUtils;

import java.io.*;

Expand Down Expand Up @@ -50,22 +50,11 @@ class LogFileCollector {
*/
@NonNull
public String collectLogFile(@NonNull Context context, @NonNull String fileName, int numberOfLines) throws IOException {
final BoundedLinkedList<String> resultBuffer = new BoundedLinkedList<String>(numberOfLines);
final BufferedReader reader = getReader(context, fileName);
try {
String line = reader.readLine();
while (line != null) {
resultBuffer.add(line + "\n");
line = reader.readLine();
}
} finally {
CollectorUtil.safeClose(reader);
}
return resultBuffer.toString();
return IOUtils.streamToString(getStream(context, fileName), numberOfLines);
}

@NonNull
private static BufferedReader getReader(@NonNull Context context, @NonNull String fileName) {
private static InputStream getStream(@NonNull Context context, @NonNull String fileName) {
try {
final FileInputStream inputStream;
if (fileName.startsWith("/")) {
Expand All @@ -78,10 +67,10 @@ private static BufferedReader getReader(@NonNull Context context, @NonNull Strin
// A file directly contained within the application files folder.
inputStream = context.openFileInput(fileName);
}
return new BufferedReader(new InputStreamReader(inputStream), 1024); //TODO: 1024 should be a constant. Use ACRAConstants.DEFAULT_BUFFER_SIZE_IN_BYTES ?
return inputStream;
} catch (FileNotFoundException e) {
ACRA.log.e(LOG_TAG, "Cannot find application log file : '" + fileName + "'");
return new BufferedReader(new InputStreamReader(new ByteArrayInputStream(new byte[0])));
return new ByteArrayInputStream(new byte[0]);
}
}
}
4 changes: 2 additions & 2 deletions src/main/java/org/acra/file/CrashReportPersister.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

import org.acra.ACRAConstants;
import org.acra.ReportField;
import org.acra.collector.CollectorUtil;
import org.acra.util.IOUtils;
import org.acra.collector.CrashReportData;

import java.io.*;
Expand Down Expand Up @@ -286,7 +286,7 @@ private synchronized CrashReportData load(@NonNull Reader reader) throws IOExcep
crashData.put(key, value);
}

CollectorUtil.safeClose(reader);
IOUtils.safeClose(reader);

return crashData;
}
Expand Down
132 changes: 132 additions & 0 deletions src/main/java/org/acra/util/IOUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/*
* Copyright 2016
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.acra.util;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;

import com.android.internal.util.Predicate;

import org.acra.ACRAConstants;
import org.acra.util.BoundedLinkedList;

import java.io.BufferedReader;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.List;

/**
* @author William Ferguson, F43nd1r
* @since 4.6.0
*/
public final class IOUtils {

private static final Predicate<String> DEFAULT_FILTER = new Predicate<String>() {
@Override
public boolean apply(String s) {
return true;
}
};
private static final int NO_LIMIT = -1;

private IOUtils() {
}


/**
* Closes a Closeable.
*
* @param closeable Closeable to close. If closeable is null then method just returns.
*/
public static void safeClose(@Nullable Closeable closeable) {
if (closeable == null) return;

try {
closeable.close();
} catch (IOException ignored) {
// We made out best effort to release this resource. Nothing more we can do.
}
}

/**
* Reads an InputStream into a string
*
* @param input the stream
* @return the read string
* @throws IOException
*/
@NonNull
public static String streamToString(@NonNull InputStream input) throws IOException {
return streamToString(input, DEFAULT_FILTER, NO_LIMIT);
}

/**
* Reads an InputStream into a string
*
* @param input the stream
* @param filter should return false for lines which should be excluded
* @return the read string
* @throws IOException
*/
@NonNull
public static String streamToString(@NonNull InputStream input, Predicate<String> filter) throws IOException {
return streamToString(input, filter, NO_LIMIT);
}

/**
* Reads an InputStream into a string
*
* @param input the stream
* @param limit the maximum number of lines to read (the last x lines are kept)
* @return the read string
* @throws IOException
*/
@NonNull
public static String streamToString(@NonNull InputStream input, int limit) throws IOException {
return streamToString(input, DEFAULT_FILTER, limit);
}

/**
* Reads an InputStream into a string
*
* @param input the stream
* @param filter should return false for lines which should be excluded
* @param limit the maximum number of lines to read (the last x lines are kept)
* @return the read string
* @throws IOException
*/
@NonNull
public static String streamToString(@NonNull InputStream input, Predicate<String> filter, int limit) throws IOException {
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(input), ACRAConstants.DEFAULT_BUFFER_SIZE_IN_BYTES);
String line;
List<String> buffer = limit == NO_LIMIT ? new LinkedList<String>() : new BoundedLinkedList<String>(limit);
while ((line = reader.readLine()) != null) {
if (filter.apply(line)) {
buffer.add(line);
}
}
return TextUtils.join("\n", buffer);
} finally {
safeClose(reader);
}
}
}
3 changes: 1 addition & 2 deletions src/main/java/org/acra/util/JSONReportBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import org.acra.ACRA;
import org.acra.ReportField;
import org.acra.collector.CollectorUtil;
import org.acra.collector.CrashReportData;
import org.json.JSONArray;
import org.json.JSONException;
Expand Down Expand Up @@ -96,7 +95,7 @@ public static JSONObject buildJSONReport(@NonNull CrashReportData errorContent)
} catch (JSONException e) {
throw new JSONReportException("Could not create JSON object for key " + key, e);
} finally {
CollectorUtil.safeClose(reader);
IOUtils.safeClose(reader);
}
}
return jsonReport;
Expand Down

0 comments on commit 5932c05

Please sign in to comment.