文章目录
- 前言
- 一、直接用 hilog vs 封装 Logger
- 1.1 直接用 hilog(不封装)
- 1.2 封装后(Logger)
- 二、Logger.ets 完整解析
- 三、hilog 参数详解
- 3.1 domain 业务域
- 3.2 %{public}s 是什么?
- 四、日志级别对比
- 五、项目中的使用示例
- 5.1 记录正常流程
- 5.2 记录错误
- 5.3 记录用户操作
- 六、可扩展版本的 Logger
- 七、在 DevEco Studio 查看日志
- 总结
前言
写代码调试时,很多人习惯用console.log('打印一下')来输出信息。HarmonyOS 当然也支持console.log,但官方推荐用hilog。
为什么?hilog有分级(info/warn/error)、有 domain 过滤、日志格式更规范,更适合在设备上调试复杂问题。
项目里的Logger.ets把hilog封装了一下,这篇文章把封装思路讲清楚,顺带教你怎么用 DevEco Studio 的日志面板调试。
项目预览
一、直接用 hilog vs 封装 Logger
1.1 直接用 hilog(不封装)
import{hilog}from'@kit.PerformanceAnalysisKit';// 每次都要写这三个参数hilog.info(0x0000,'NearByGasStationDemo','%{public}s, %{public}s',['初始化','成功']);hilog.error(0x0000,'NearByGasStationDemo','%{public}s, %{public}s',['出错',err.message]);问题:
0x0000是什么?每次都要记'NearByGasStationDemo'是前缀,每次都要写一遍- 格式字符串
'%{public}s, %{public}s'固定,但每次都要复制
1.2 封装后(Logger)
Logger.info('testTag','初始化成功');Logger.error('testTag',`出错了:${err.message}`);封装后只需要传关键信息(tag + 消息),其他的都在 Logger 类里统一处理。
二、Logger.ets 完整解析
// entry/src/main/ets/utils/Logger.etsimport{hilog}from'@kit.PerformanceAnalysisKit';exportclassLogger{// 私有静态属性:这些是 hilog 的固定参数privatestaticdomain:number=0x0000;// 业务域(用于过滤日志)privatestaticprefix:string='NearByGasStationDemo';// 日志前缀(标识来源)privatestaticformat:string='%{public}s, %{public}s';// 格式字符串// DEBUG 级别:只在开发时有用,发布版本会被过滤staticdebug(...args:string[]):void{hilog.debug(Logger.domain,Logger.prefix,Logger.format,args);}// INFO 级别:正常运行信息staticinfo(...args:string[]):void{hilog.info(Logger.domain,Logger.prefix,Logger.format,args);}// WARN 级别:警告(不影响运行,但需要关注)staticwarn(...args:string[]):void{hilog.warn(Logger.domain,Logger.prefix,Logger.format,args);}// ERROR 级别:错误(影响功能)staticerror(...args:string[]):void{hilog.error(Logger.domain,Logger.prefix,Logger.format,args);}}三、hilog 参数详解
hilog.info(domain,tag,format,...args)| 参数 | 类型 | 说明 |
|---|---|---|
domain | number | 业务域,0x0000-0xFFFF,用于在日志面板过滤 |
tag | string | 日志标签,标识日志来源(类似 Android 的 Tag) |
format | string | 格式字符串,%{public}s是公开字符串占位符 |
args | any[] | 填充格式字符串的参数 |
3.1 domain 业务域
domain是一个 16 进制数字,用于按业务模块分组日志。比如:
// 不同模块使用不同 domain,方便过滤constMAP_DOMAIN=0x0001;// 地图模块constPERMISSION_DOMAIN=0x0002;// 权限模块constNETWORK_DOMAIN=0x0003;// 网络模块项目里统一用0x0000,简化处理。
3.2 %{public}s 是什么?
%{public}s是 hilog 的格式占位符,{public}表示这是公开日志(会显示实际内容)。如果用%{private}s,敏感信息会被替换为<private>保护隐私。
// public:日志里显示实际值hilog.info(0x0000,'tag','%{public}s',['用户名: 张三']);// 输出: 用户名: 张三// private:日志里显示 <private>hilog.info(0x0000,'tag','%{private}s',['密码: 123456']);// 输出: <private>四、日志级别对比
| 级别 | 方法 | 颜色(DevEco日志面板) | 用途 |
|---|---|---|---|
| DEBUG | Logger.debug | 蓝色 | 开发时的详细调试信息 |
| INFO | Logger.info | 绿色/白色 | 正常运行流程记录 |
| WARN | Logger.warn | 黄色 | 警告,可能影响体验 |
| ERROR | Logger.error | 红色 | 错误,功能受影响 |
发布到应用市场时,debug级别的日志会被系统过滤,不会显示,避免性能损耗和信息泄露。
五、项目中的使用示例
5.1 记录正常流程
// EntryAbility.etsonCreate(want:Want,launchParam:AbilityConstant.LaunchParam):void{hilog.info(DOMAIN,'testTag','%{public}s','Ability onCreate');}onWindowStageCreate(windowStage:window.WindowStage):void{hilog.info(DOMAIN,'testTag','%{public}s','Ability onWindowStageCreate');// ...windowStage.loadContent('pages/MainPage',(err)=>{if(err.code){hilog.error(DOMAIN,'testTag','Failed to load the content. Cause: %{public}s',JSON.stringify(err));return;}hilog.info(DOMAIN,'testTag','Succeeded in loading the content.');});}5.2 记录错误
// PermissionsUtil.ets}catch(error){Logger.error(`Failed to get bundle info for self. Code is${error.code}, message is${error.message}`);}// MapUtil.ets(用 hilog 直接调用)if(err){Logger.error('testTag',`init fail, code:${err.code}, message:${err.message}`);return;}5.3 记录用户操作
// GasStationPage.etsthis.mapController.on('myLocationButtonClick',()=>{Logger.info('testTag','Jump to my location');// ...});六、可扩展版本的 Logger
项目里的 Logger 比较基础,生产级别的 Logger 可以加更多功能:
exportclassLogger{privatestaticdomain:number=0x0000;privatestaticprefix:string='NearByGasStationDemo';privatestaticformat:string='%{public}s, %{public}s';privatestaticisDebugMode:boolean=true;// 可通过配置关闭 debug 日志staticdebug(...args:string[]):void{if(Logger.isDebugMode){hilog.debug(Logger.domain,Logger.prefix,Logger.format,args);}}// 带时间戳的错误日志staticerrorWithTime(tag:string,message:string):void{lettimestamp=newDate().toISOString();hilog.error(Logger.domain,Logger.prefix,Logger.format,[`[${timestamp}]`,`${tag}:${message}`]);}// 格式化对象输出(调试用)staticlogObject(tag:string,obj:object):void{try{Logger.debug(tag,JSON.stringify(obj,null,2));}catch{Logger.debug(tag,String(obj));}}}七、在 DevEco Studio 查看日志
- 运行应用后,点击底部Log标签页
- 选择设备和进程(你的应用包名)
- 在搜索框里输入
NearByGasStationDemo(我们定义的 prefix)过滤日志 - 可以按级别过滤(Debug / Info / Warn / Error)
常用日志过滤技巧:
- 按tag过滤:搜索
testTag - 按错误级别过滤:点击顶部的 Error 按钮
- 按关键字过滤:直接输入关键字
总结
Logger 封装的核心价值:
- 统一配置:
domain、prefix、format只在一处配置 - 简化调用:调用方只传 tag 和消息,不关心 hilog 的具体参数
- 方便控制:想在生产环境关闭 debug 日志,只改一处
- 类型安全:
static方法直接调用,不需要实例化
console.log不是不能用,但hilog在 HarmonyOS 上更规范、更好过滤、更安全(可以保护私密信息)。封装成 Logger,以后维护起来也更方便。
下一篇讲CalculateUtil 距离计算——怎么用经纬度算出两点之间的距离(公里数)。