Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Logger组件之日志序列化 #57

Open
soapgu opened this issue Jun 21, 2021 · 0 comments
Open

Logger组件之日志序列化 #57

soapgu opened this issue Jun 21, 2021 · 0 comments
Labels
安卓 安卓

Comments

@soapgu
Copy link
Owner

soapgu commented Jun 21, 2021

  • 引言

一直一来Logger组件我们都是使用默认的AndroidLogAdapter,就是之间打Logcat日志。比较好用。所以一直一来也没有进一步深入的需求,直到现在为了测试安卓的稳定性,使用长期监控的程序运行情况。光使用Logcat感觉有点不太保险,第一主要Logcat本身会定时清理,一些久远的日志难以持久,第二Logcat本身其他日志量也很大,虽然有命令可以过滤,但是也不是特别方便。不过保存到本机来的安心

  • 持有化日志的使用

废话不多说了。先直接看官挡说明

Save logs to the file

//TODO: More information will be added later

Logger.addLogAdapter(new DiskLogAdapter());

Add custom tag to Csv format strategy

FormatStrategy formatStrategy = CsvFormatStrategy.newBuilder()
  .tag("custom")
  .build();
  
Logger.addLogAdapter(new DiskLogAdapter(formatStrategy));

这文档写的真是拉垮,聊了几句,连起码日志存哪里都不说清楚,无力吐槽。

无奈,只能翻代码
发现所有的日志都会输出到/sdcard/logger/logs_{n}.csv里面。
虽然勉强能用,但是显然不能满足要求。感觉这个SDK就是一个半成品。

  • 自定义LogStrategy

本来想要直接重写WriteHandler,无奈相关代码是内部类。只能另起炉灶。

public class MyDiskLogStrategy extends DiskLogStrategy {
    public MyDiskLogStrategy(@NonNull Handler handler) {
        super(handler);
    }

    @SuppressLint("SimpleDateFormat")
    static class WriteHandler extends Handler {

        @NonNull private final String folder;
        private final int maxFileSize;
        private final DateFormat format = new SimpleDateFormat("yyyy-MM-dd");

        WriteHandler(@NonNull Looper looper, @NonNull String folder, int maxFileSize  ) {
            super(looper);
            this.folder = folder;
            this.maxFileSize = maxFileSize;
        }

        @SuppressWarnings("checkstyle:emptyblock")
        @Override public void handleMessage(@NonNull Message msg) {
            String content = (String) msg.obj;

            FileWriter fileWriter = null;
            String fileName = format.format(new Date());
            File logFile = getLogFile(folder, fileName);

            try {
                fileWriter = new FileWriter(logFile, true);

                writeLog(fileWriter, content);

                fileWriter.flush();
                fileWriter.close();
            } catch (IOException e) {
                if (fileWriter != null) {
                    try {
                        fileWriter.flush();
                        fileWriter.close();
                    } catch (IOException e1) { /* fail silently */ }
                }
            }
        }

        /**
         * This is always called on a single background thread.
         * Implementing classes must ONLY write to the fileWriter and nothing more.
         * The abstract class takes care of everything else including close the stream and catching IOException
         *
         * @param fileWriter an instance of FileWriter already initialised to the correct file
         */
        private void writeLog(@NonNull FileWriter fileWriter, @NonNull String content) throws IOException {

            fileWriter.append(content);
        }

        private File getLogFile(@NonNull String folderName, @NonNull String fileName) {

            File folder = new File(folderName);
            if (!folder.exists()) {
                folder.mkdirs();
            }

            int newFileCount = 0;
            File newFile;
            File existingFile = null;

            newFile = new File(folder, String.format("%s_%s.csv", fileName, newFileCount));
            while (newFile.exists()) {
                existingFile = newFile;
                newFileCount++;
                newFile = new File(folder, String.format("%s_%s.csv", fileName, newFileCount));
            }

            if (existingFile != null) {
                if (existingFile.length() >= maxFileSize) {
                    return newFile;
                }
                return existingFile;
            }

            return newFile;
        }
    }
}

把DiskLogStrategy 的主要源码搬过来,把文件名改为按天记录日志
String fileName = format.format(new Date());
接下来是调用部分

 String diskPath = Environment.getExternalStorageDirectory().getAbsolutePath();
        String folder = diskPath + File.separatorChar + "logger" + File.separatorChar + this.getPackageName();

        HandlerThread ht = new HandlerThread("AndroidFileLogger." + folder);
        ht.start();
        Handler handler = new MyDiskLogStrategy.WriteHandler(ht.getLooper(), folder, MAX_BYTES);
        LogStrategy logStrategy = new DiskLogStrategy(handler);
        FormatStrategy cvsFormatStrategy = CsvFormatStrategy.newBuilder()
                .tag(this.provideTagName())
                .logStrategy( logStrategy )
                .build();
        Logger.addLogAdapter( new DiskLogAdapter(cvsFormatStrategy) );

把日志目录设为/sdcard/logger/{package}/,这样通用过,还不会冲突。

  • 总结

最终效果
图片
这才是我想要的。

相关链接

@soapgu soapgu added the 安卓 安卓 label Jun 21, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
安卓 安卓
Projects
None yet
Development

No branches or pull requests

1 participant