# ffsky-app-logger **Repository Path**: hljdrl/ffsky-app-logger ## Basic Information - **Project Name**: ffsky-app-logger - **Description**: 客户端日志 - **Primary Language**: Android - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-10-08 - **Last Updated**: 2026-04-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: logger组件, android日志组件, 抽象日志, logger文件 ## README # ffsky-app-logger ## 介绍 **ffsky-app-logger** 是一个轻量级 Android 日志框架,为 Android 应用提供统一的日志输出 API。 核心思想:**接口与实现分离**。业务代码只依赖核心接口层,日志的实际输出方式(控制台、文件、远程等)通过可插拔的实现层组件来决定,无需修改业务代码即可灵活切换日志后端。 ### 功能特性 - 统一的日志 API,支持 `info`、`debug`、`error`、`warn` 四个日志级别 - 支持多种参数形式:单字符串、多字符串、多对象、异常堆栈 - 内置 Android Logcat 输出实现,开箱即用 - 提供 tinylog 1.x / tinylog 2.x 文件日志实现,Logcat 输出与文件写入同时进行 - 运行时动态切换日志实现,一行代码完成 - 线程安全设计,支持多线程环境 - 提供 `L`、`Logger`、`AppLogger` 三个类名别名,适应不同编码习惯 - 已发布至 Maven Central(Sonatype),支持远程依赖 ### 模块结构 ``` ffsky-app-logger/ ├── lib_logger # 核心接口层(必选) ├── lib_tiny_logger # 实现层 - tinylog 1.x(可选) ├── lib_tiny_logger2 # 实现层 - tinylog 2.x(可选) └── app # 示例应用 ``` | 模块 | 类型 | Maven 坐标 | 最新版本 | 说明 | |------|------|-----------|-------|------| | `lib_logger` | 核心层 | `com.gitee.hljdrl:logger` | 3.0.0 | 日志接口定义 + 默认 Logcat 实现 | | `lib_tiny_logger` | 实现层 | `com.gitee.hljdrl:tinylog` | 3.0.0 | 基于 tinylog 1.x,支持文件日志写入 | | `lib_tiny_logger2` | 实现层 | `com.gitee.hljdrl:tinylog2` | 3.0.0 | 基于 tinylog 2.x,支持文件日志写入 | --- ## 设计理念 ### 1. 门面模式(Facade Pattern) `L` 类作为全局静态门面,屏蔽底层日志实现细节。业务代码只需调用 `L.i()`、`L.d()`、`L.e()` 等静态方法,无需关心日志写到了哪里。 ``` 业务代码 ──> L(门面) ──> LogOut 实例(实际输出) ``` ### 2. 策略模式(Strategy Pattern) 通过 `LogEvent` 接口和 `LogOut` 抽象类,定义日志输出的统一行为契约。不同的实现类代表不同的输出策略: ``` LogEvent(接口) └── LogOut(抽象基类) ├── AndroidLogout → 控制台输出(默认) ├── TinyLogFileLogout → tinylog 1.x 文件输出 └── TinyLog2FileLogout → tinylog 2.x 文件输出 ``` 运行时通过 `L.setLogOut(...)` 一行代码即可切换策略,零侵入业务代码。 ### 3. 接口与实现分离 - **核心层**(`lib_logger`)只定义接口和默认 Logcat 实现,零外部依赖 - **实现层**(`lib_tiny_logger` / `lib_tiny_logger2`)各自引入第三方日志库,独立存在 - 业务方按需选择实现层组件,不需要文件日志的场景甚至可以只依赖核心层 ### 4. 线程安全 - `L` 类的 `FACTORY_LOG` 和 `enable` 字段使用 `volatile` 修饰,保证多线程可见性 - `setLogOut()` 使用 `synchronized` 保证原子性 - 实现层的 `mStarted` 标志也使用 `volatile` ### 5. 向后兼容 旧包名 `com.ffsky.logger` 和 `com.ffsky.tinylog` 的类保留为废弃桥接类,继承自新包名对应的类,使旧代码无需修改即可编译通过,逐步迁移到新包名 `com.gitee.hljdrl.logger`。 --- ## 使用说明 ### 添加依赖 **v3.0.0**(最新版本,AGP 8.x + Gradle 8.x,新增中文 Javadoc) ```groovy // 核心日志库(必选) api 'com.gitee.hljdrl:logger:3.0.0' // 实现层 - 二选一(可选,按需引入) api 'com.gitee.hljdrl:tinylog:3.0.0' // tinylog 1.x 文件日志 api 'com.gitee.hljdrl:tinylog2:3.0.0' // tinylog 2.x 文件日志 ```
历史版本 **v2.0.1**(新增 warn 日志级别) ```groovy api 'com.gitee.hljdrl:logger:2.0.1' api 'com.gitee.hljdrl:tinylog:2.0.0' // tinylog 1.x 文件日志 ``` **v2.0.0** ```groovy api 'com.gitee.hljdrl:logger:2.0.0' api 'com.gitee.hljdrl:tinylog:2.0.0' // tinylog 1.x 文件日志 ```
### 初始化 ```java import com.gitee.hljdrl.logger.L; import com.gitee.hljdrl.logger.AndroidLogout; import com.gitee.hljdrl.tinylog.TinyLogFileLogout; // tinylog 1.x import com.gitee.hljdrl.tinylog2.TinyLog2FileLogout; // tinylog 2.x // 方式一:默认 Logcat 输出(开箱即用,无需手动设置) L.setLogOut(new AndroidLogout()); // 方式二:tinylog 1.x 文件日志(Logcat + 文件同时输出) String logDir = getExternalFilesDir("logs").toString(); L.setLogOut(new TinyLogFileLogout(logDir)); // 方式三:tinylog 2.x 文件日志(Logcat + 文件同时输出) L.setLogOut(new TinyLog2FileLogout(logDir)); // 方式四:关闭所有日志 L.setLogOut(null); ``` ### 输出日志 ```java String TAG = "MyActivity"; // INFO 级别 L.i(TAG, "应用启动完成"); L.i(TAG, "用户ID:", userId, " 名称:", userName); // DEBUG 级别 L.d(TAG, "请求参数:", requestBody); // ERROR 级别 L.e(TAG, "网络请求失败"); L.e(TAG, exception); L.e(TAG, "加载数据异常", exception); // WARN 级别(默认仅输出到 Logcat,不写入文件) L.w(TAG, "磁盘空间不足"); ``` ### 日志控制 ```java // 获取当前日志文件路径 String logFile = L.getFile(); // 关闭日志(停止写入) L.close(); // 重新开启日志 L.open(); // 获取当前日志实现实例 LogOut logout = L.getLogout(); ``` --- ## 接口层 API ### LogEvent 接口 `com.gitee.hljdrl.logger.LogEvent` — 定义所有日志操作的统一 API。 #### 常量 | 常量 | 值 | 说明 | |------|---|------| | `OPTION_DIR` | `_option_dir` | 日志文件写入目录的选项 key | | `OPTION_SWITCH` | `_option_switch` | 日志开关的选项 key | #### 生命周期方法 | 方法 | 说明 | |------|------| | `void close()` | 关闭日志 | | `void open()` | 开启日志 | | `void open(String fileName)` | 开启日志并指定日志文件名(default 方法) | | `void setOption(String key, Object option)` | 设置日志选项 | | `String getLoggerFile()` | 获取当前日志文件路径,无文件输出时返回 null | #### INFO 级别 | 方法 | 说明 | |------|------| | `void i(String tag, String msg)` | 输出 INFO 日志 | | `void i(String tag, String... msg)` | 输出 INFO 日志(多条字符串拼接) | | `void i(String tag, Object... msg)` | 输出 INFO 日志(多个对象拼接) | #### DEBUG 级别 | 方法 | 说明 | |------|------| | `void d(String tag, String msg)` | 输出 DEBUG 日志 | | `void d(String tag, String... msg)` | 输出 DEBUG 日志(多条字符串拼接) | | `void d(String tag, Object... msg)` | 输出 DEBUG 日志(多个对象拼接) | #### ERROR 级别 | 方法 | 说明 | |------|------| | `void e(String tag, String msg)` | 输出 ERROR 日志 | | `void e(String tag, Object... msg)` | 输出 ERROR 日志(多个对象拼接) | | `void e(String tag, Throwable throwable)` | 输出 ERROR 日志(异常堆栈) | | `void e(String tag, String msg, Throwable throwable)` | 输出 ERROR 日志(消息 + 异常堆栈) | #### WARN 级别 | 方法 | 说明 | |------|------| | `void w(String tag, String msg)` | 输出 WARN 日志(default 方法,仅 Logcat,不写入文件) | | `void w(String tag, String... msg)` | 输出 WARN 日志(多条字符串拼接,default 方法) | | `void w(String tag, Object... msg)` | 输出 WARN 日志(多个对象拼接,default 方法) | --- ## 类与方法总览 ### lib_logger — 核心接口层 包名:`com.gitee.hljdrl.logger` | 类/接口 | 类型 | 说明 | |---------|------|------| | `LogEvent` | 接口 | 日志事件接口,定义所有日志操作的统一 API | | `LogOut` | 抽象类 | 日志输出抽象基类,实现 LogEvent 接口,提供字符串拼接工具方法 | | `L` | 类 | 日志门面类,提供全局静态日志 API | | `AndroidLogout` | 类 | Android Logcat 日志输出实现(默认) | | `Logger` | 类 | L 的别名(继承 L),完整类名风格 | | `AppLogger` | 类 | L 的别名(继承 L),App 语义风格 | #### LogEvent 接口方法 | 方法签名 | 返回值 | 说明 | |----------|--------|------| | `close()` | void | 关闭日志 | | `open()` | void | 开启日志 | | `open(String fileName)` | void | 开启日志并指定文件名(default) | | `setOption(String key, Object option)` | void | 设置日志选项 | | `getLoggerFile()` | String | 获取日志文件路径 | | `i(String tag, String msg)` | void | INFO 日志 | | `i(String tag, String... msg)` | void | INFO 日志(字符串数组) | | `i(String tag, Object... msg)` | void | INFO 日志(对象数组) | | `d(String tag, String msg)` | void | DEBUG 日志 | | `d(String tag, String... msg)` | void | DEBUG 日志(字符串数组) | | `d(String tag, Object... msg)` | void | DEBUG 日志(对象数组) | | `e(String tag, String msg)` | void | ERROR 日志 | | `e(String tag, Object... msg)` | void | ERROR 日志(对象数组) | | `e(String tag, Throwable throwable)` | void | ERROR 日志(异常) | | `e(String tag, String msg, Throwable throwable)` | void | ERROR 日志(消息 + 异常) | | `w(String tag, String msg)` | void | WARN 日志(default,仅 Logcat) | | `w(String tag, String... msg)` | void | WARN 日志(default,仅 Logcat) | | `w(String tag, Object... msg)` | void | WARN 日志(default,仅 Logcat) | #### LogOut 抽象类方法 | 方法签名 | 修饰符 | 返回值 | 说明 | |----------|--------|--------|------| | `toString(String... list)` | protected static | String | 将多个字符串拼接为一个字符串 | | `toString(Object... list)` | protected static | String | 将多个对象拼接为字符串(null 输出 " NULL ") | #### L 类方法 | 方法签名 | 修饰符 | 返回值 | 说明 | |----------|--------|--------|------| | `setLogOut(LogOut logOut)` | public static | void | 设置日志输出实现,传 null 禁用日志 | | `getLogout()` | public static | LogOut | 获取当前日志输出实例 | | `getFile()` | public static | String | 获取当前日志文件路径 | | `open()` | public static | void | 开启日志 | | `close()` | public static | void | 关闭日志 | | `i(String tag, String msg)` | public static | void | INFO 日志 | | `i(String tag, String... msg)` | public static | void | INFO 日志(字符串数组) | | `i(String tag, Object... msg)` | public static | void | INFO 日志(对象数组) | | `d(String tag, String msg)` | public static | void | DEBUG 日志 | | `d(String tag, String... msg)` | public static | void | DEBUG 日志(字符串数组) | | `d(String tag, Object... msg)` | public static | void | DEBUG 日志(对象数组) | | `e(String tag, String msg)` | public static | void | ERROR 日志 | | `e(String tag, Object... msg)` | public static | void | ERROR 日志(对象数组) | | `e(String tag, Throwable throwable)` | public static | void | ERROR 日志(异常) | | `e(String tag, String msg, Throwable throwable)` | public static | void | ERROR 日志(消息 + 异常) | | `w(String tag, String msg)` | public static | void | WARN 日志 | | `w(String tag, String... msg)` | public static | void | WARN 日志(字符串数组) | | `w(String tag, Object... msg)` | public static | void | WARN 日志(对象数组) | #### AndroidLogout 类 继承 `LogOut`,实现所有 `LogEvent` 接口方法。所有日志直接输出到 Android Logcat 控制台,不写入文件。`close()`、`open()`、`setOption()` 为空实现,`getLoggerFile()` 始终返回 null。 --- ### lib_tiny_logger — tinylog 1.x 实现层 包名:`com.gitee.hljdrl.tinylog` | 类 | 说明 | |----|------| | `TinyLogFileLogout` | 基于 tinylog 1.x 的日志输出实现,Logcat + 文件同时写入 | #### TinyLogFileLogout 方法 | 方法签名 | 说明 | |----------|------| | `TinyLogFileLogout(String dir)` | 构造函数,自动生成日志文件名 | | `TinyLogFileLogout(String dir, String fileName)` | 构造函数,指定日志文件名 | | `TinyLogFileLogout(String dir, String fileFormatPattern, String logcatFormatPattern)` | 构造函数,自定义日志格式 | | `close()` | 关闭日志,停止 tinylog 写入线程 | | `open()` | 重新开启日志,生成新的日志文件 | | `open(String fileName)` | 重新开启日志并指定文件名 | | `setOption(String key, Object option)` | 设置选项,支持 `OPTION_SWITCH` | | `getLoggerFile()` | 获取当前日志文件路径 | | `i(tag, msg)` / `d(tag, msg)` / `e(tag, msg)` | 各级别日志输出(多个重载) | --- ### lib_tiny_logger2 — tinylog 2.x 实现层 包名:`com.gitee.hljdrl.tinylog2` | 类 | 说明 | |----|------| | `TinyLog2FileLogout` | 基于 tinylog 2.x 的日志输出实现,Logcat + 文件同时写入 | #### TinyLog2FileLogout 方法 | 方法签名 | 说明 | |----------|------| | `TinyLog2FileLogout(String dir)` | 构造函数,自动生成日志文件名 | | `TinyLog2FileLogout(String dir, String fileName)` | 构造函数,指定日志文件名 | | `TinyLog2FileLogout(String dir, String fileFormatPattern, String logcatFormatPattern)` | 构造函数,自定义日志格式 | | `close()` | 停止日志发送(tinylog 写入线程保持空闲) | | `open()` | 恢复日志发送,继续写入已有文件 | | `open(String fileName)` | 恢复日志发送并指定文件名 | | `setOption(String key, Object option)` | 设置选项,支持 `OPTION_SWITCH` | | `getLoggerFile()` | 获取当前日志文件路径 | | `i(tag, msg)` / `d(tag, msg)` / `e(tag, msg)` | 各级别日志输出(多个重载) | > **注意**:tinylog 2.x 的配置在首次日志调用时冻结,之后无法修改。如需切换到新日志文件,请创建新实例:`L.setLogOut(new TinyLog2FileLogout(dir, newFileName))` --- ### tinylog 1.x vs tinylog 2.x 对比 | 特性 | lib_tiny_logger (1.x) | lib_tiny_logger2 (2.x) | |------|----------------------|------------------------| | tinylog 版本 | 1.3.6 | 2.7.0 | | close() 行为 | 停止写入线程 | 仅停止发送日志,线程保持空闲 | | open() 行为 | 重新配置并生成新文件 | 恢复发送,继续写入已有文件 | | 配置可变性 | 每次 open/close 可重新配置 | 首次调用后配置冻结 | | 文件切换 | 支持 close → open(newFile) | 需要创建新实例 | --- ## 废弃说明 以下旧包名已废弃,保留为向后兼容桥接类。请迁移到新包名: | 废弃包名 | 迁移到 | |----------|--------| | `com.ffsky.logger.L` | `com.gitee.hljdrl.logger.L` | | `com.ffsky.logger.LogEvent` | `com.gitee.hljdrl.logger.LogEvent` | | `com.ffsky.logger.LogOut` | `com.gitee.hljdrl.logger.LogOut` | | `com.ffsky.logger.AndroidLogout` | `com.gitee.hljdrl.logger.AndroidLogout` | | `com.ffsky.tinylog.TinyLogFileLogout` | `com.gitee.hljdrl.tinylog.TinyLogFileLogout` | --- ## 项目信息 - **仓库地址**:https://gitee.com/hljdrl/ffsky-app-logger - **GroupId**:`com.gitee.hljdrl` - **License**:Apache 2.0