博客
关于我
Timber 配合 logback-android (slf4j) Log输出
阅读量:500 次
发布时间:2019-03-07

本文共 4898 字,大约阅读时间需要 16 分钟。

Timber 配合 Logback-Android

Logback-Android 是一个强大的日志框架,可以将日志记录到文件、数据库、邮件或网络中。本文将介绍如何配置并实际使用 Logback-Android 与 Timber 结合进行日志记录。

一、存储权限

在 Android 11 及及以上版本中,存储权限被改为强制分区存储。因此,需要将存储路径更改为内部存储路径,以确保日志能够顺利写入。

二、配置文件

Logback-Android 的配置文件结构如下:

%-5relative [%thread] - %msg%n
true
true
${LOG_DIR}/base.log
%date [%thread] %-5level - %msg%n
${LOG_DIR}/app.${today}.log
true
%date %-5relative [%thread] %-5level - %msg%n
${LOG_DIR}/app.%d{yyyy-MM-dd}.log
7
10MB

三、日志记录配置

3.1 据功能描述

  • 初始化日志输出:

    Timber.tag("Custom_TAG").d("This is a debug log.");
  • 异步日志记录:

    Timber.logPreferredCrash Alley{    ...}
  • 多线程安全性:

    // 确保在多线程环境下避免日志重sandboxfinal android.os.Handler mainHandler = new android.os.Handler(getMainLooper());final PriorityQueue
    runnableQueue = new PriorityQueue<>();public void log(final int priority, final String tag, final String message) { final Runnable runnable = new Runnable() { @Override public void run() { // Actual logging logic if (!TextUtils.isEmpty(message)) { String logMessage = tag + ": " + message; switch (priority) { case Log.DEBUG: case Log.INFO: case Log.WARN: case Log.ERROR: } } ... } }; if (runnableQueue.size() < MAX_LOG_THREADS) { runnableQueue.put(runnable); mainHandler.post(runnable); } else { // 处理队列已满的情况 }}
  • 四、JAVA实现

    4.1 核心日志处理逻辑

    public class FileLoggingTree extends Timber.DebugTree {    private static final Logger sLogger = LoggerFactory.getLogger(FileLoggingTree.class);    @Override    protected void log(int priority, String tag, String message, Throwable t) {        if (priority == Log.VERBOSE) {            return;        }        if (!TextUtils.isEmpty(message)) {            String logMessage = tag + ": " + message;            switch (priority) {                case Log.DEBUG:                    sLogger.debug(logMessage);                    break;                case Log.INFO:                    sLogger.info(logMessage);                    break;                case Log.WARN:                    sLogger.warn(logMessage);                    break;                case Log.ERROR:                    sLogger.error(logMessage);                    break;            }        } else {            if (t != null) {                switch (priority) {                    case Log.DEBUG:                        sLogger.debug(tag, t);                        break;                    case Log.INFO:                        sLogger.info(tag, t);                        break;                    case Log.WARN:                        sLogger.warn(tag, t);                        break;                    case Log.ERROR:                        sLogger.error(tag, t);                        break;                }            }        }    }}

    4.2 简化日志工具类设计

    public class AppLogUtils {    private static final String sTag = "AppLogUtils ===";    private static boolean sEnablingLog = true;    private AppLogUtils() {        throw new IllegalStateException("不能实例化Me!");    }    public static boolean isLog() {        return sEnablingLog;    }    public static void setLog(boolean enable) {        sEnablingLog = enable;    }    public static void setTag(String tag) {        sTag = tag;    }    public static void input(String msg) {        if (!sEnablingLog) {            return;        }        Timber.tag(sTag).i(msg);    }    public static void input(String tag, String msg) {        if (!sEnablingLog || TextUtils.isEmpty(msg)) {            return;        }        Timber.tag(sTag + tag).i(msg);    }    public static void warn(String tag, String msg) {        if (!sEnablingLog || TextUtils.isEmpty(msg)) {            return;        }        Timber.tag(sTag + tag).w(msg);    }    public static void error(String tag, String msg) {        if (!sEnablingLog || TextUtils.isEmpty(msg)) {            return;        }        Timber.tag(sTag + tag).e(msg);    }    public static void error(String tag, Exception e) {        if (!sEnablingLog || e == null) {            return;        }        Timber.tag(sTag + tag).e(e);    }    public static void debugInfo(String tag, String msg) {        if (!sEnablingLog || TextUtils.isEmpty(msg)) {            return;        }        Timber.tag(sTag + tag).d(msg);    }}

    五、参考资料

    • Android 文件系统结构
    • Logback-Android 权限配置
    • RollingFileAppender 面板配置
    • FileLoggingTree 日志处理逻辑

    转载地址:http://bovcz.baihongyu.com/

    你可能感兴趣的文章
    Python3-selenium自动化测试框架,结合HTMLTestRunner测试报告!
    查看>>
    Python3-如何自我更新作为服务运行的应用程序
    查看>>
    Python3.1-网格模拟概念性问题
    查看>>
    Python3.12 解决conda环境libstdc++版本过低问题
    查看>>
    python3.2批量查询IP地址区域
    查看>>
    Python3.5中协程和未来/任务之间的区别?
    查看>>
    python3.5实现socket通讯(TCP)
    查看>>
    python3.6 ubuntu部署nginx、 uwsgi、 django
    查看>>
    Python3.6.3中,functools似乎不能用
    查看>>
    python3.6.5+cuda9+cudnn7.1+win10+tensorflow-gpu1.9.0下载配置
    查看>>
    python3.6使用pickle序列化class
    查看>>
    python3.6入门到高阶(全栈) day027 网络通信协议 osi七层模型
    查看>>
    Python3.6属性错误:模块‘;异步没有属性‘;运行‘;
    查看>>
    python3.6版本中的python-weka-wrapper安装失败,错误代码为%1
    查看>>
    Python3.7安装cv2踩过的坑
    查看>>
    python写txt文件
    查看>>
    python关于sorted排序函数详细解析 附实战代码(全)
    查看>>
    python3.8调用m文件,调用matlab
    查看>>
    python3.9新特性_Python 3.9 新特性速览
    查看>>
    Python3.x:遍历select下拉框获取value值
    查看>>