Android上的日志

Android的日志机制和普通的Java项目有一些不一样, 这里记录一下

安卓内建的Log

安卓应用类型(在build.gradle里定义 android {...})的模块, 可以直接引用内建的android.util.Log, 这是最常用的日志机制, 和服务器端开发的区别在于, 内建的Log需要一个TAG, 这个TAG用于在控制台过滤日志, 一般使用类名. 日志级别从verbose开始, 分为 v, d, i, w, e. 其中, v不应该被编译进入发布版本, d会被编译但是会在运行时去掉. 长度大于23个字符的TAG在Logcat输出中会被截断. 如果需要对某个TAG设置单独的日志级别, 需要通过setprop设置

setprop log.tag.<YOUR_LOG_TAG> <LEVEL>
# 例如
adb shell setprop log.tag.MainActivity VERBOSE

 如果需要写入文件, 不能在android.util.Log的基础上实现, 需要自己实现一个Log类.

使用slf4j + Logback classic

对于非安卓应用模式的模块, 例如Java/Kotlin Library, 无法直接使用安卓内建Log, 可以使用slf4j. 网络上可以找到的android slf4j变体很多, 但是经典的org.slf4j:slf-api还是可用的, 需要在build.gradle添加dependency, 这里使用了和服务器环境一样的ch.qos.logback. logback-core会被logback-classic引用加入, 可以不写在dependencies里面. 

dependencies {
    ...
    implementation 'org.slf4j:slf4j-api:1.7.25'
    implementation 'ch.qos.logback:logback-classic:1.2.3'
    ...
}

 添加上门的dependency之后, 就可以在代码中输出日志, 这个输出对于logcat, 和命令行执行main()方法都是有效的.

private static final Logger Log = LoggerFactory.getLogger(NetworkUtil.class);
...
Log.error(e.getMessage(), e);
...

使用slf4j + tony19:logback-android

在Java/Kotlin Library的build.gradle中只添加slf4j, 在app module的build.gradle中添加tony19:logback-android

dependencies {
    ...
    implementation 'com.github.tony19:logback-android:2.0.0'
    ...

然后在app module中, 与main和res目录平级添加assets目录, 添加logback.xml, 写入

<configuration>
    <appender name="logcat" class="ch.qos.logback.classic.android.LogcatAppender">
        <tagEncoder>
            <pattern>%logger{12}</pattern>
        </tagEncoder>
        <encoder>
            <pattern>[%-20thread] %msg</pattern>
        </encoder>
    </appender>

    <root level="DEBUG">
        <appender-ref ref="logcat" />
    </root>
</configuration>

这样就可以在运行app时, 使用slf4j输出日志. 

注意: assets/logback.xml 这个文件是必须的, 如果没有找到配置文件, tony19:logback-android不会输出任何日志.

logback-classic 与 logback-android 并存

如果在lib中只添加slf4j, 在运行main()时会报错 SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
如果在lib中添加tony19:logback-android, 依然会报上面的错误
如果在lib中添加logback-classic, 运行main()会正常输出日志, 但是在编译app时, 会提示"Duplicate class ch.qos.logback.classic"

这是因为这两个logback实现类产生了冲突, 需要在app的build.gradle中配置排除lib引入的logback-classic, 添加

android {
    ...

    configurations {
        all {
            exclude group: 'ch.qos.logback', module: 'logback-classic'
        }
    }
    ...

之后就可以正常编译了

Logback-android日志写入文件

使用以下配置, 可以将日志写入文件, 注意这里的文件路径 ${DATA_DIR} 会指向应用在内部存储的目录, 这个不需要读写权限, 并且其他应用无权访问. 对应文件系统中的实际路径为 /storage/emulated/0/com.rockbb.app.pocketserver/files/logs/app.log 或 /data/user/0/com.rockbb.app.pocketserver/files/logs/app.log , 但是如果在<file>中直接指定这个路径, 就需要读写权限.

<configuration>
    <!-- Create a file appender for a log in the application's data directory -->
    <property name="LOG_HOME" value="${DATA_DIR}" />
    <appender name="file" class="ch.qos.logback.core.FileAppender">
        <file>${LOG_HOME}/logs/app.log</file>
        <encoder>
            <tagEncoder>
                <pattern>%35.35logger{70}#%4.4line</pattern>
            </tagEncoder>
            <encoder>
                <pattern>%8.8thread %msg%n</pattern>
            </encoder>
        </encoder>
    </appender>

    <appender name="logcat" class="ch.qos.logback.classic.android.LogcatAppender">
        <tagEncoder>
            <pattern>%25.25logger{50}#%3.3line</pattern>
        </tagEncoder>
        <encoder>
            <pattern>%8.8thread %msg%n</pattern>
        </encoder>
    </appender>

    <root level="DEBUG">
        <appender-ref ref="logcat" />
        <appender-ref ref="file" />
    </root>
</configuration>

需要写入其他公共路径, 需要在AndroidManifest.xml中申请权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

  

posted on 2020-09-02 14:44  Milton  阅读(1212)  评论(0编辑  收藏  举报

导航