
Logger 日志系统——从 console.log 到分级日志一、为什么需要日志系统在 HarmonyOS 应用开发中日志是排查问题、了解运行时状态的核心手段。新手开发者往往习惯使用console.log()输出调试信息这在简单场景下确实够用。但随着项目规模增长——多模块协作、多设备适配、线上问题排查——console.log 的局限性就会暴露无遗缺乏分级无法区分信息、警告、错误日志淹没在大量输出中缺少 TAG难以定位日志来自哪个模块或页面性能开销生产环境无法按需关闭影响应用性能格式不统一不同开发者的日志风格各异阅读困难本项目的 Logger 类正是为解决这些问题而设计的。它基于 HarmonyOS 的kit.PerformanceAnalysisKit中的hilogAPI 构建提供了简洁的分级日志能力。二、Logger 源码分析Logger 类的完整实现位于commons/commonLib/src/main/ets/utils/Logger.etsimport{hilog}fromkit.PerformanceAnalysisKit;exportclassLogger{privatestaticdomain:number0xff00;privatestaticprefix:stringHotelTemplate;privatestaticformat:string%{public}s, %{public}s;publicstaticdebug(...args:string[]):void{hilog.debug(Logger.domain,Logger.prefix,Logger.format,args);}publicstaticinfo(...args:string[]):void{hilog.info(Logger.domain,Logger.prefix,Logger.format,args);}publicstaticwarn(...args:string[]):void{hilog.warn(Logger.domain,Logger.prefix,Logger.format,args);}publicstaticerror(...args:string[]):void{hilog.error(Logger.domain,Logger.prefix,Logger.format,args);}}2.1 核心设计解析domain域0xff00是一个自定义的日志域标识。在 hilog 系统中domain 用于划分日志的所属子系统取值范围 0x0~0xFFFF。我们使用 0xff00 作为应用私有域避免与系统日志冲突。prefix前缀固定为HotelTemplate这是该应用的日志标识在抓取日志时可以快速过滤出属于本应用的日志行。format格式%{public}s, %{public}s定义了日志消息的格式化模板。%{public}s表示这是一个可公开的字符串参数。hilog 提供了%{public}s和%{private}s两种格式前者在日志中明文显示后者会被脱敏处理显示为private。在调试阶段使用 public 便于定位问题发布前应检查敏感信息是否使用了 private。2.2 分级体系Logger 提供了四个静态方法对应四种日志级别级别方法用途生产环境建议DEBUGLogger.debug()详细调试信息关闭INFOLogger.info()一般运行状态开启WARNLogger.warn()潜在问题警告开启ERRORLogger.error()错误和异常开启在 hilog 底层每个级别都有独立的缓冲区。ERROR 级别的日志会被优先保留不会被 INFO 日志覆盖。这确保了关键错误信息不会丢失。三、使用规范3.1 TAG 规范在本项目的所有文件中统一使用const TAG常量作为日志标签// 页面级别constTAG[HomePage];Logger.info(TAG,页面加载完成);// 管理器级别Logger.error(NewWordManager,添加生词失败:${JSON.stringify(e)});// 工具类级别constTAG[ContextUtils];Logger.error(TAG,showToast fail, error: JSON.stringify(error));TAG 命名的建议页面组件使用[页面名]如[HomePage]、[CourseHomePage]管理器使用类名如NewWordManager、StatisticsManager工具类使用[类名]如[ContextUtils]、[AudioPlayer]3.2 错误日志的 JSON 序列化在 catch 块中捕获异常时ArkTS 的错误对象无法直接进行字符串拼接。正确的做法是使用JSON.stringify(e)将错误转为可读的字符串try{// 可能出错的代码}catch(e){Logger.error(MyComponent,操作失败:${JSON.stringify(e)});}四、项目中各层的日志实践4.1 Manager 层日志Manager 层是业务逻辑的核心日志需要记录关键操作的入口和结果Logger.info(NewWordManager,添加生词成功:${topicItem.title});Logger.error(NewWordManager,添加生词失败:${JSON.stringify(e)});LearningPlanManager 中同样遵循此模式每个 public 方法都有对应的日志记录Logger.info(LearningPlanManager,保存学习计划成功);Logger.error(LearningPlanManager,更新连续学习天数失败:${JSON.stringify(e)});4.2 工具类日志工具类如 AudioPlayer 在生命周期方法中记录详细日志Logger.info(AudioPlayer,开始播放: url);Logger.warn(AudioPlayer,音频URL为空);Logger.error(AudioPlayer,播放失败:${JSON.stringify(e)});4.3 页面组件日志页面组件在 aboutToAppear 和关键交互处记录日志Logger.info(TAG,aboutToAppear);Logger.info(JSON.stringify(this.sourceRouterModel));五、与 console.log 的对比对比维度console.logLogger (hilog)分级能力无debug/info/warn/error标签过滤不支持domain prefix TAG生产可控不可控可按级别过滤隐私保护无%{private}s 脱敏缓冲区管理无分级独立缓冲区六、最佳实践总结始终使用 TAG每个文件定义唯一的 TAG便于 grep 过滤分层级输出避免把所有信息都用 Logger.info 输出合理使用 warn 和 errorJSON 序列化异常catch 块中始终使用JSON.stringify(e)记录错误避免敏感信息hilog 默认会脱敏 private 数据但 print 格式需手动指定统一前缀prefix 用于区分不同应用便于日志聚合系统过滤Logger 类的设计虽然简洁但它在项目中扮演着眼睛的角色。正是通过它开发者才能在无调试器的生产环境中快速定位问题的根源。从 console.log 到分级日志是每一个工程化项目必备的基础能力提升。