专栏首页Android小菜鸡Android 拓展Logger细节分享

Android 拓展Logger细节分享

首先感谢orhanobut/logger库的作者提供了这么好用的日志管理工具。Github传送门 本文以orhanobut/logger为基础,通过阅读源码后进行的拓展,为达到以下目的:

  1. 将日志存在本地,并可以自由更改文件大小、存放路径等基本信息
  2. 实现log文件达到设置的最大文件大小后,自动生成新的文件,并且文件数量不超过5个,第一个文件永远是最新的log内容

实现:

logger的基本使用这里笔者就不再阐述了,原文写的非常清楚,首先我们先设置,让Logger将日志打印到本地文件中Logger.addLogAdapter(new DiskLogAdapter());这时笔者想要对文件大小,文件名字,存储路径等信息做设置,原作者的文档中没有这方面的内容,笔者阅读文档发现也并没有对外提供调用。那么我们只有自己集成LogAdapter实现一套了(DisAdapter也是继承了LogAdapter)。

public class MyDiskLogAdapter implements LogAdapter {

    @NonNull
    private final MyFormatStrateg formatStrategy;


    public MyDiskLogAdapter(){
        formatStrategy = MyFormatStrateg.newBuilder().build();
    }

    @Override
    public boolean isLoggable(int priority, @Nullable String tag) {
        return true;
    }

    @Override
    public void log(int priority, @Nullable String tag, @NonNull String message) {
        formatStrategy.log(priority, tag, message);
    }
}

DiskLogAdapter的构造方法实例了FormatStrateg,而看FormatStrateg的源码,我们看到我们需要更改的文件大小等内容都在里面,显然,我们得自己写一个FormatStrateg替换。

 @NonNull
        public MyFormatStrateg build() {
            if (date == null) {
                date = new Date();
            }
            if (dateFormat == null) {
                dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss.SSS", Locale.UK);
            }
            if (logStrategy == null) {
                String diskPath = Environment.getExternalStorageDirectory().getAbsolutePath();
                String folder = diskPath + File.separatorChar + "logger";
                HandlerThread ht = new HandlerThread("AndroidFileLogger." + folder);
                ht.start();
                Handler handler = new MyLogStrategy.WriteHandler(ht.getLooper(), folder, MAX_BYTES);
                logStrategy = new MyLogStrategy(handler);
            }
            return new MyFormatStrateg(this);
        }

FormatStrateg类中,我们主要看Builder下的这个build()方法。这里是对本地log文件的所有文件信息做了一个配置,现在我们就可以任意的修改满足我们自己的需要了。

第一个需求我们满足了,现在我们需要更改Logger写入文件的逻辑,通过阅读源码笔者发现,Logger本身会写入500K的文件log0,当日志装满文件时,会创建一个新的文件log1继续装,最多只会创建两个,并且只要有多个文件,最新的日志会在log1中。这里就和笔者的需求有冲突,日常开发中,笔者希望log0永远是最新的日志,这样笔者上传文件至服务器时只需要考虑上传log0即可,并且最大文件数需求是5个,超过时删除最后一个,创建一个新的log0,另外4个log文件index自动+1。

为实现这个需求,我们需要找到Logger的输出流。在FormatStrateg中实例了一个叫做LogStrategyHandler就是我们的目标。显然我们既然要更改他,就要自己实现一个。

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


            File folder = new File(folderName);
            if (!folder.exists()) {
                //TODO: What if folder is not created, what happens then?
                folder.mkdirs();
            }

            String[] files=folder.list();
            int filecount=files.length;
            File newFile= null;
            File existingFile = null;

            newFile = new File(folder, String.format("%s_%s.log", fileName, 0));
            while (newFile.exists()) {
                existingFile = newFile;
                newFile = new File(folder, String.format("%s_%s.log", fileName, filecount));
            }

            if (existingFile != null) {
                if (existingFile.length() >= maxFileSize) {
                    if(filecount>=5){
                        for(int i=0;i<filecount;i++){
                            File localfile= new File(folder.getPath()+ File.separator+files[i]);
                            if(localfile.exists()){
                                localfile.delete();
                            }
                        }
                    }else{
                        existingFile.renameTo(newFile);
                    }
                    newFile=new File(folder, String.format("%s_%s.log", fileName, 0));
                    return newFile;
                }
                return existingFile;
            }

            return newFile;
        }
    }

我们直接看核心方法,其实就是一个文件操作,首先判断现有的文件数是否大于我们设置的最大文件数,如果超过,则删除全部文件,新建一个新的文件log0,没有超过就直接创建一个新文件,下标为index+1。同是,我们需要保证最新的log文件时log0,则固定了新文件的名字。主要逻辑跟原作者差别并不大,只是在文件处理这里做了少许改动。

使用:

直接将项目中loggerExpand包引入项目,调用'Logger.addLogAdapter(MyDiskLogAdapter())'取代原作者的Logger.addLogAdapter(DiskLogAdapter())即可,配置文件信息,可以直接在MyFormatStrateg类中修改。 记得android.permission.WRITE_EXTERNAL_STORAGE权限很关键!!6.0以上的手机需要动态设置权限。

项目地址:

LoggerProject传送门

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 接口文档模板MarkDown版

    饮水思源为名
  • Kotlin日常编程(一)——拒绝使用"!!"

    这个时候,编译会无法通过,系统会给你改成list.add(str!!)以通过编译。会出现这样的原因是Kotlin有着自己的判空机制。"str!!"表示str一定...

    饮水思源为名
  • Andriod RX+Retrofit基础学习并简单封装

    最近加入了新的工作,Android产品用了RX+retrofit作为网络交互框架,以前完全没用过,只有自己补一补。这里与大家分享一下学习成果,也便于自己日后复习...

    饮水思源为名
  • 函数式接口小结

    如果说一个接口内有且只有一个方法,而且该方法是一个缺省属性为public abstract方法,该接口可以称之为是一个函数式接口。

  • 夯实Java基础系列3:一文搞懂String常见面试题,从基础到实战

    本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看

    黄小斜
  • 面经手册 · 第11篇《StringBuilder 比 String 快?空嘴白牙的,证据呢!》

    面我的题开发都用不到,你为什么要问?可能这是大部分程序员求职时的经历,甚至也是大家讨厌和烦躁的点。明明给的是拧螺丝的钱、明明做的是写CRUD的事、明明担的是成工...

    小傅哥
  • String类12个常用的方法

    挨踢小子部落阁
  • LeetCode 804 Unique Morse Code Words

    首先为每个单词的每个字符进行转码, 将转码后的数据放到 Set 集合中, 最后返回 Set 的长度。

    一份执着✘
  • Flink从入门到放弃-Flink分布式缓存

    在用户函数中访问缓存文件或者目录(这里是一个map函数)。这个函数必须继承RichFunction,因为它需要使用RuntimeContext读取数据:

    大数据技术与架构
  • 7-Flink的分布式缓存

    Flink提供了一个分布式缓存,类似于hadoop,可以使用户在并行函数中很方便的读取本地文件,并把它放在taskmanager节点中,防止task重复拉取。

    大数据技术与架构

扫码关注云+社区

领取腾讯云代金券