3、日志标签与领域:创建自定义日志标签、领域标识符(Domain)的作用与配置、多模块日志隔离
日志这东西,说白了就是给系统装个「黑匣子」。但黑匣子里的数据如果乱七八糟,那还不如不记。我刚开始做鸿蒙开发时,就吃过这个亏——日志打了一堆,真要查问题时,满屏都是杂音,根本找不到关键信息。
后来我慢慢摸索出套路:日志标签和领域标识符,就是给每条日志贴上的「身份证」和「户口本」。今天咱们就聊聊这两个东西怎么用,以及怎么实现多模块日志隔离。
3.1 日志标签:给每条日志贴个标签
日志标签(Tag)是啥?就是一条日志的「名字」。比如你写了个网络模块,所有网络相关的日志都打上 NetModule 这个标签。这样过滤时,一眼就能看到网络模块在干什么。
在鸿蒙系统里,创建自定义日志标签很简单。我一般这么写:
import { hilog } from '@kit.PerformanceAnalysisKit';
// 定义标签常量
const TAG = 'MyApp_Network';
// 打印日志
hilog.info(0x0001, TAG, '网络连接成功,耗时 %d ms', 120);
嗯,这里要注意:标签长度最好控制在 32 个字符以内。太长了会被截断,反而看不全。我个人习惯用「模块名_子模块」的格式,比如 Payment_Checkout、User_Login,这样层次清晰。
3.2 领域标识符(Domain):给日志上个「户口」
标签是「名字」,那领域标识符(Domain)就是「户口所在地」。鸿蒙系统里,Domain 是一个 32 位的整数,用来标识日志属于哪个子系统或功能领域。
为什么要搞个 Domain?你想想看,一个大型 App 可能有几十个模块,光靠标签过滤,还是会有重名风险。Domain 就像给每个模块划了块「自留地」,互不干扰。
配置 Domain 的规则是这样的:
| Domain 范围 | 用途 | 示例 |
|---|---|---|
| 0x0000 - 0x00FF | 系统保留 | 系统服务、内核日志 |
| 0x0100 - 0xFFFF | 应用自定义 | 业务模块日志 |
| 0x10000 以上 | 扩展预留 | 第三方库、插件 |
我在项目中遇到过一个问题:两个团队用了相同的 Domain 值,结果日志混在一起,排查了整整两天。后来我们统一在项目文档里登记了每个模块的 Domain 范围,才彻底解决。
配置代码示例:
// 定义领域标识符
const DOMAIN_NETWORK = 0x0101; // 网络模块
const DOMAIN_PAYMENT = 0x0102; // 支付模块
const DOMAIN_USER = 0x0103; // 用户模块
// 使用领域标识符打印日志
hilog.info(DOMAIN_NETWORK, 'NetModule', 'DNS解析完成');
hilog.info(DOMAIN_PAYMENT, 'PayModule', '订单创建成功');
3.3 多模块日志隔离:让每个模块「自扫门前雪」
多模块日志隔离,说白了就是让 A 模块的日志不要跑到 B 模块的日志里去。鸿蒙系统提供了几种方式来实现:
3.3.1 基于 Domain 的隔离
这是最基础的方式。每个模块分配唯一的 Domain,日志自然就分开了。过滤时用 hilog -d 0x0101 就能只看网络模块的日志。
3.3.2 基于标签前缀的隔离
如果 Domain 不够用,可以用标签前缀做二次过滤。比如:
// 网络模块
hilog.info(DOMAIN_NETWORK, 'Net_HTTP', '请求发送');
hilog.info(DOMAIN_NETWORK, 'Net_DNS', '域名解析');
// 支付模块
hilog.info(DOMAIN_PAYMENT, 'Pay_Order', '订单创建');
hilog.info(DOMAIN_PAYMENT, 'Pay_Refund', '退款处理');
这样即使 Domain 相同,也能通过标签前缀快速定位子模块。
3.3.3 日志级别隔离
不同模块可以设置不同的日志级别。比如网络模块调试时用 DEBUG,上线后改成 INFO;支付模块因为涉及资金,始终保留 WARN 以上级别。
// 网络模块:调试时打开
if (isDebug) {
hilog.debug(DOMAIN_NETWORK, 'NetModule', '当前网络状态: %s', status);
}
// 支付模块:始终记录错误
hilog.error(DOMAIN_PAYMENT, 'PayModule', '支付失败,错误码: %d', errCode);
3.4 实战:一个多模块日志配置示例
说了这么多,咱们来个完整的例子。假设你有个电商 App,分网络、支付、用户三个模块。我会这样组织日志:
// 日志配置中心
const LogConfig = {
network: { domain: 0x0101, tag: 'Net', level: 'DEBUG' },
payment: { domain: 0x0102, tag: 'Pay', level: 'INFO' },
user: { domain: 0x0103, tag: 'User', level: 'WARN' },
};
// 封装日志工具
function log(module, level, message, ...args) {
const config = LogConfig[module];
if (!config) return;
// 级别过滤
const levels = ['DEBUG', 'INFO', 'WARN', 'ERROR'];
if (levels.indexOf(level) < levels.indexOf(config.level)) {
return;
}
hilog[level.toLowerCase()](config.domain, config.tag, message, ...args);
}
// 使用
log('network', 'DEBUG', '连接耗时 %d ms', 50); // 调试时输出
log('payment', 'ERROR', '扣款失败'); // 始终输出
这样做的好处是:改日志级别只需改一处配置,不用满世界找 hilog.info 去改。我曾经在一个大项目里用这种方式,上线前把网络模块从 DEBUG 切到 INFO,一行代码搞定。
3.5 知识体系总览
下面这张图,是我梳理的本章核心逻辑。你看一眼就能明白标签、Domain、隔离之间的关系:
说白了,日志标签和领域就是给系统装上一套「户籍管理系统」。标签是名字,Domain 是地址,隔离就是分小区管理。搞清楚了这三者的关系,你的日志就不再是噪音,而是真正的「黑匣子」——关键时刻能救命那种。
公众号:蓝海资料掘金营,微信deep3321