Android|Integrate slf4j + logback as a logging framework

Recently, when I was doing a log transformation for an Android APP, I wanted to meet the following needs:

  1. You can easily use variable parameters to output logs;

  2. Logs can be output to the console and files according to levels;

  3. It can cut log files according to date and file size, save logs for a specified number of days on a rolling basis, and automatically clean up old logs.

Based on this demand, I searched for “Android logging framework”. Most netizens recommended logger, timber, xLog, etc., which looked good. However, due to several years of back-end development experience and habits, I learned more and found that the familiar log4j and logback have also been adapted on Android, so I finally decided to use slf4j + logback to achieve consistent results in front-end and back-end development. experience.

Students who have done Java back-end development are generally familiar with the combination of slf4j + logback, while students who develop Android may not necessarily have heard of them. Therefore, this article will start from scratch and record how to integrate slf4j + logback as a logging framework in Android APP, and use Lombok annotations to generate log objects.

Integrate slf4j + logback

logback-android project address: https://github.com/tony19/logback-android

1. Add dependencies in the build.gradle file of the project/module:

dependencies {
  implementation 'org.slf4j:slf4j-api:2.0.7'
  implementation 'com.github.tony19:logback-android:3.0.0'
}

If it is a single-module project, you can add it directly in the app/build.gradle file. If it is a multi-module project, you can add it in the build.gradle file of a common module. Remember to add the implementation Change it to api before it can be referenced by other modules.

2. Create the log configuration file app/src/main/assets/logback.xml:

<configuration debug="false"
    xmlns="https://tony19.github.io/logback-android/xml"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="https://tony19.github.io/logback-android/xml https://cdn.jsdelivr.net/gh/tony19/logback-android/logback.xsd"
>

    <property name="LOG_DIR" value="${EXT_DIR:-${DATA_DIR}}/test/log"/>
    
    <appender name="logcat" class="ch.qos.logback.classic.android.LogcatAppender">
        <tagEncoder>
            <pattern>%logger{12}</pattern>
        </tagEncoder>
        <encoder>
            <pattern>[%-20thread] %msg</pattern>
        </encoder>
    </appender>

    <appender name="local_file" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_DIR}/test.log</file>
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_DIR}/test.%d.log</fileNamePattern>
            <maxHistory>15</maxHistory>
        </rollingPolicy>
    </appender>

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

    <root level="INFO">
        <appender-ref ref="local_file" />
    </root>
</configuration>

The above configuration means that DEBUG and above level logs are output to the console, and INFO and above level logs are output to files. The files are divided according to date, and a maximum of 15 days of logs are retained.

You can configure it as needed, for example, you can also limit the size of a single file, customize the format of log output, etc.

It is mentioned in the project’s Wiki that one thing that Android developers are more concerned about is that the log has a saving path, which can either specify an absolute path or use variables, such as:

  • ${DATA_DIR} means Context.getFilesDir();

  • ${EXT_DIR} means Context.getExternalFilesDir(null);

  • ${EXT_DIR:-${DATA_DIR}} means to use EXT_DIR when EXT_DIR is available, otherwise use DATA_DIR;

  • ${PACKAGE_NAME} represents the package name;

  • ${VERSION_NAME} represents the version name;

  • ${VERSION_CODE} represents the version number.

3. You can start using slf4j’s API for log printing:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

// declare logger
Logger log = LoggerFactory.getLogger(MainActivity.class);

// print log
log.info("hello world");
log.info("number {}, boolean {}, string {}, object {}", 1, true, "string", new Object());

Run the APP and you can see the log output to logcat and the file in the corresponding location.

When you have questions about the configuration and need to debug, you can change debug="false" in the above configuration file to debug="true", so that logback will output detailed information. information to help us locate the problem.

Use Lombok annotations to generate log objects

In step 3 of the previous part, in every class that needs to use logger, you need to declare logger manually, such as Logger log = LoggerFactory.getLogger(MainActivity.class);, which is not convenient.

Here we can use Lombok annotations to simplify this step and automatically generate logger objects.

Lombok officially provides integration instructions for the Android platform: https://projectlombok.org/setup/android

Based on the Android Studio environment, there are actually two steps to do.

1. Install the Lombok plug-in;

Settings -> Plugins -> Search Lombok -> Install

Note: For Android Studio versions 2020.3.1 – 2022.3.1, the JetBrains official plug-in market cannot search for a compatible version of the Lombok plug-in. You can refer to https://gitee.com/sgpublic/lombok-plugin-repository for solution.

2. Add the following content to the build.gradle file of the module you need to use:

dependencies {
compileOnly 'org.projectlombok:lombok:1.18.30'
annotationProcessor 'org.projectlombok:lombok:1.18.30'
}

Then, you can use the @Slf4j annotation to automatically generate a logger object. The current usage posture is simplified to this:

@Slf4j
public class Test {
    public void test() {
        log.info("hello world");
    }
}

Summary

Okay, the above is the record of integrating slf4j + logback in Android. At this point, I have “unified” the usage of Java backend and Android client to print logs, and I have taken a small step forward on the road to avoid “schizophrenia” caused by multi-project maintenance. .

The code examples listed in this article have been uploaded to GitHub at: https://github.com/mzlogin/AndroidPractices/tree/master/android-studio/LogbackDemo

The above steps are for reference by students with similar needs, and it is strongly recommended to focus on official documents. If you have a better solution, please leave a message for discussion and exchange.

Related links

  • https://github.com/tony19/logback-android

  • https://projectlombok.org/setup/android

  • https://gitee.com/sgpublic/lombok-plugin-repository

  • https://github.com/mzlogin/AndroidPractices/tree/master/android-studio/LogbackDemo

If you have gained something after reading the article, you can follow my WeChat public account “Mengsao Programmer” and set it as a star to read more content at any time.

Please help by clicking “Share” or “Watching”!