Java android应用程序的文件记录器

Java android应用程序的文件记录器,java,android,logging,Java,Android,Logging,我希望最简单的记录器就是简单地将错误(主要是异常)记录到android文件系统中的日志文件中。例如,我过去在PC java上登录文件的最简单、最方便的方式(至少在我看来)是将所有异常打印到控制台,并将系统重定向到控制台和我的文件。据我所知,这在android上并不足够,我猜这是因为android操作系统的设计方式,那么在安卓系统中最简单的方法是什么呢 请注意,项目中已经有很多代码,我真的不想再看一遍,在catch块上添加日志调用或其他任何东西来记录我的异常,因为记录这些异常所需做的工作对我的用例

我希望最简单的记录器就是简单地将错误(主要是异常)记录到android文件系统中的日志文件中。例如,我过去在PC java上登录文件的最简单、最方便的方式(至少在我看来)是将所有异常打印到控制台,并将系统重定向到控制台和我的文件。据我所知,这在android上并不足够,我猜这是因为android操作系统的设计方式,那么在安卓系统中最简单的方法是什么呢

请注意,项目中已经有很多代码,我真的不想再看一遍,在catch块上添加日志调用或其他任何东西来记录我的异常,因为记录这些异常所需做的工作对我的用例来说是最好的


谢谢你

它还没有完成,但运行非常稳定。它使用异常名称、时间、堆栈跟踪和其他数据保存人类可读的json数组。您还可以保存logcat的日志

使用

ExceptionWriter ew = new ExceptionWriter(new File(Environment.getExternalStorageDirectory(), "debug.txt"));
ew.w(new IllegalArgumentException("some msg"), "additional message");
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * User: elevenetc
 * Date: 10/9/13
 * Time: 12:52 PM
 */
public class ExceptionWriter {

    private final StringBuilder sb;
    private final ExceptionWriter.WriteExceptionTask writeExceptionTask;
    private final SimpleDateFormat dataFormat;
    private int totalExceptions;
    private StringBuilder stackBuilder = new StringBuilder();

    public int getTotalExceptions(){return totalExceptions;}

    public ExceptionWriter(File file) throws IOException {
        if(file != null){
            writeExceptionTask = new WriteExceptionTask(file);
            sb = new StringBuilder();
            dataFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
            new Thread(writeExceptionTask).start();
        }else{
            sb = null;
            writeExceptionTask = null;
            dataFormat = null;
        }

    }

    public synchronized int wLogcat(){
        try {
            writeExceptionTask.addStreamToRead(Runtime.getRuntime().exec("logcat -d -v time").getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }

        return 0;
    }

    public int w(Exception debugException, String caughtMessage){
        return w(debugException, caughtMessage, null);
    }

    public synchronized int w(Exception debugException, String caughtMessage, String additionalData){

        if(writeExceptionTask == null) return -1;

        sb.setLength(0);

        StackTraceElement[] stackTrace = debugException == null ? null : debugException.getStackTrace();

        sb.append("{\"date\":\"");sb.append(getTime());
        sb.append("\",\"exceptionClassName\":\"");sb.append(debugException == null ? null : debugException.getClass());
        sb.append("\",\"exceptionMessage:\":\"");sb.append(debugException == null ? null : debugException.getMessage());
        sb.append("\",\"caughtMessage:\":\"");sb.append(caughtMessage);
        if(additionalData != null) {sb.append("\",\"data:\":\"");sb.append(additionalData);}
        sb.append("\",\"stack\":");sb.append(stackToString(stackTrace));
        sb.append("},");

        writeExceptionTask.stringQueue.add(sb.toString());

        totalExceptions++;

        return 0;
    }

    public void destroy() {
        if(writeExceptionTask != null) {
            writeExceptionTask.stop();
        }
    }

    private String getTime(){
        return dataFormat.format(System.currentTimeMillis());
    }

    private String stackToString(StackTraceElement[] stackTrace){

        if(stackTrace == null) return null;

        stackBuilder.setLength(0);

        stackBuilder.append("[");
        for (int i = 0; i < stackTrace.length; i++) {
            StackTraceElement e = stackTrace[i];

            stackBuilder.append("{\"");
            stackBuilder.append(e.getLineNumber());
            stackBuilder.append("\":\"");
            stackBuilder.append(e.getClassName());
            stackBuilder.append(".");
            stackBuilder.append(e.getMethodName());
            stackBuilder.append("\"}");

            if(i != stackTrace.length -1) stackBuilder.append(",");
        }
        stackBuilder.append("]");
        return stackBuilder.toString();
    }

    ///////////////////////////////////////////////
    /// Static classes
    ///////////////////////////////////////////////

    private class WriteExceptionTask implements Runnable {

        private final File file;
        private boolean running;
        private final ConcurrentLinkedQueue<String> stringQueue;
        private final ConcurrentLinkedQueue<InputStream> isQueue;
        private final FileWriter writer;

        private WriteExceptionTask(File file) throws IOException {
            this.file = file;
            writer = new FileWriter(this.file, true);
            stringQueue = new ConcurrentLinkedQueue<String>();
            isQueue = new ConcurrentLinkedQueue<InputStream>();
            running = true;
        }

        public void addStreamToRead(InputStream is){
            if(is != null){
                isQueue.add(is);
            }
        }

        @Override
        public void run() {
            while(running){
                if(!stringQueue.isEmpty()){

                    //TODO check file existence

                    try {
                        writer.append(stringQueue.poll());
                        writer.flush();
                    } catch (IOException e) {
                        e.printStackTrace();
                        running = false;
                    }
                }

                if(!isQueue.isEmpty()){
                    InputStream is = isQueue.poll();
                    BufferedReader reader = new BufferedReader(new InputStreamReader(is));

                    StringBuilder builder = new StringBuilder("{\"catLog\":\"");

                    String aux;

                    try {

                        while ((aux = reader.readLine()) != null) {
                            //TODO view like array or \n
                            builder.append(aux);
                        }

                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    builder.append("\"},");

                    stringQueue.add(builder.toString());
                }
            }

            try {
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        public void stop() {
            running = false;
        }
    }

}
来源

ExceptionWriter ew = new ExceptionWriter(new File(Environment.getExternalStorageDirectory(), "debug.txt"));
ew.w(new IllegalArgumentException("some msg"), "additional message");
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * User: elevenetc
 * Date: 10/9/13
 * Time: 12:52 PM
 */
public class ExceptionWriter {

    private final StringBuilder sb;
    private final ExceptionWriter.WriteExceptionTask writeExceptionTask;
    private final SimpleDateFormat dataFormat;
    private int totalExceptions;
    private StringBuilder stackBuilder = new StringBuilder();

    public int getTotalExceptions(){return totalExceptions;}

    public ExceptionWriter(File file) throws IOException {
        if(file != null){
            writeExceptionTask = new WriteExceptionTask(file);
            sb = new StringBuilder();
            dataFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
            new Thread(writeExceptionTask).start();
        }else{
            sb = null;
            writeExceptionTask = null;
            dataFormat = null;
        }

    }

    public synchronized int wLogcat(){
        try {
            writeExceptionTask.addStreamToRead(Runtime.getRuntime().exec("logcat -d -v time").getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }

        return 0;
    }

    public int w(Exception debugException, String caughtMessage){
        return w(debugException, caughtMessage, null);
    }

    public synchronized int w(Exception debugException, String caughtMessage, String additionalData){

        if(writeExceptionTask == null) return -1;

        sb.setLength(0);

        StackTraceElement[] stackTrace = debugException == null ? null : debugException.getStackTrace();

        sb.append("{\"date\":\"");sb.append(getTime());
        sb.append("\",\"exceptionClassName\":\"");sb.append(debugException == null ? null : debugException.getClass());
        sb.append("\",\"exceptionMessage:\":\"");sb.append(debugException == null ? null : debugException.getMessage());
        sb.append("\",\"caughtMessage:\":\"");sb.append(caughtMessage);
        if(additionalData != null) {sb.append("\",\"data:\":\"");sb.append(additionalData);}
        sb.append("\",\"stack\":");sb.append(stackToString(stackTrace));
        sb.append("},");

        writeExceptionTask.stringQueue.add(sb.toString());

        totalExceptions++;

        return 0;
    }

    public void destroy() {
        if(writeExceptionTask != null) {
            writeExceptionTask.stop();
        }
    }

    private String getTime(){
        return dataFormat.format(System.currentTimeMillis());
    }

    private String stackToString(StackTraceElement[] stackTrace){

        if(stackTrace == null) return null;

        stackBuilder.setLength(0);

        stackBuilder.append("[");
        for (int i = 0; i < stackTrace.length; i++) {
            StackTraceElement e = stackTrace[i];

            stackBuilder.append("{\"");
            stackBuilder.append(e.getLineNumber());
            stackBuilder.append("\":\"");
            stackBuilder.append(e.getClassName());
            stackBuilder.append(".");
            stackBuilder.append(e.getMethodName());
            stackBuilder.append("\"}");

            if(i != stackTrace.length -1) stackBuilder.append(",");
        }
        stackBuilder.append("]");
        return stackBuilder.toString();
    }

    ///////////////////////////////////////////////
    /// Static classes
    ///////////////////////////////////////////////

    private class WriteExceptionTask implements Runnable {

        private final File file;
        private boolean running;
        private final ConcurrentLinkedQueue<String> stringQueue;
        private final ConcurrentLinkedQueue<InputStream> isQueue;
        private final FileWriter writer;

        private WriteExceptionTask(File file) throws IOException {
            this.file = file;
            writer = new FileWriter(this.file, true);
            stringQueue = new ConcurrentLinkedQueue<String>();
            isQueue = new ConcurrentLinkedQueue<InputStream>();
            running = true;
        }

        public void addStreamToRead(InputStream is){
            if(is != null){
                isQueue.add(is);
            }
        }

        @Override
        public void run() {
            while(running){
                if(!stringQueue.isEmpty()){

                    //TODO check file existence

                    try {
                        writer.append(stringQueue.poll());
                        writer.flush();
                    } catch (IOException e) {
                        e.printStackTrace();
                        running = false;
                    }
                }

                if(!isQueue.isEmpty()){
                    InputStream is = isQueue.poll();
                    BufferedReader reader = new BufferedReader(new InputStreamReader(is));

                    StringBuilder builder = new StringBuilder("{\"catLog\":\"");

                    String aux;

                    try {

                        while ((aux = reader.readLine()) != null) {
                            //TODO view like array or \n
                            builder.append(aux);
                        }

                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    builder.append("\"},");

                    stringQueue.add(builder.toString());
                }
            }

            try {
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        public void stop() {
            running = false;
        }
    }

}
import java.io.*;
导入java.text.simpleDataFormat;
导入java.util.concurrent.ConcurrentLinkedQueue;
/**
*用户:elevenetc
*日期:10/9/13
*时间:下午12:52
*/
公共类例外编写器{
私人住宅;私人住宅;私人住宅;
private final ExceptionWriter.WriteExceptionTask WriteExceptionTask;
私有最终SimpleDataFormat数据格式;
私人例外;
私有StringBuilder stackBuilder=新StringBuilder();
public int getTotalExceptions(){return totalExceptions;}
公共异常编写器(文件)引发IOException{
如果(文件!=null){
writeExceptionTask=新的writeExceptionTask(文件);
sb=新的StringBuilder();
数据格式=新的简化格式(“yyyy.MM.dd HH:MM:ss”);
新线程(writeExceptionTask).start();
}否则{
sb=null;
writeExceptionTask=null;
dataFormat=null;
}
}
公共同步int-wLogcat(){
试一试{
writeExceptionTask.addStreamToRead(Runtime.getRuntime().exec(“logcat-d-v time”).getInputStream());
}捕获(IOE异常){
e、 printStackTrace();
}
返回0;
}
public int w(异常debugException,字符串caughtMessage){
返回w(debugException,caughtMessage,null);
}
public synchronized int w(异常debugException、字符串caughtMessage、字符串additionalData){
if(writeExceptionTask==null)返回-1;
sb.设定长度(0);
StackTraceElement[]stackTrace=debugException==null?null:debugException.getStackTrace();
sb.append(“{”日期\“:\”);sb.append(getTime());
sb.append(“\”,\“exceptionClassName\”:\”);sb.append(debugException==null?null:debugException.getClass());
sb.append(“\”,\”异常消息:\“:\”);sb.append(debugException==null?null:debugException.getMessage());
sb.append(“\”,\“caughtMessage:\”:\”);sb.append(caughtMessage);
如果(additionalData!=null){sb.append(\”,\“data:\”:\”);sb.append(additionalData);}
sb.append(“\”,“stack\”:”);sb.append(stackToString(stackTrace));
某人加上(“},”);
writeExceptionTask.stringQueue.add(sb.toString());
totalExceptions++;
返回0;
}
公共空间销毁(){
if(writeExceptionTask!=null){
writeExceptionTask.stop();
}
}
私有字符串getTime(){
返回dataFormat.format(System.currentTimeMillis());
}
私有字符串stackToString(StackTraceElement[]stackTrace){
if(stackTrace==null)返回null;
stackBuilder.setLength(0);
stackBuilder.append(“[”);
对于(int i=0;i