HarmonyOS5---封装 日志 工具

在HarmonyOS应用开发中,封装一个高效的日志工具是提升开发效率和调试能力的关键。下面我将详细介绍在DevEco Studio中封装日志工具的完整过程。

一、封装准备

1. 创建日志工具文件

在项目 utils 目录下新建 Logger.ets 文件:

css 复制代码
src/main/ets
├── Application
├── pages
└── utils
    └── Logger.ets  <-- 日志工具类

2. 导入必要模块

打开终端下载

javascript 复制代码
// Logger.ets
import hilog from '@ohos.hilog';

二、基础封装实现

1. 定义日志级别枚举

ini 复制代码
export enum LogLevel {
  DEBUG = 3,  // 调试信息
  INFO = 4,   // 常规信息
  WARN = 5,   // 警告信息
  ERROR = 6   // 错误信息
}

2. 实现日志工具类

typescript 复制代码
export default class Logger {
  // 应用唯一标识 (16进制)
  private static readonly DOMAIN: number = 0x6688;
  
  // 全局应用标签
  private static readonly GLOBAL_TAG: string = '[MyApp]';
  
  // 当前日志级别
  private static logLevel: LogLevel = LogLevel.DEBUG;
  
  /**
   * 设置日志级别
   * @param level 日志级别
   */
  static setLevel(level: LogLevel): void {
    this.logLevel = level;
    this.debug('Logger', `日志级别设置为: ${LogLevel[level]}`);
  }
  
  /**
   * 检查是否可打印日志
   * @param level 日志级别
   */
  private static isLoggable(level: LogLevel): boolean {
    return level >= this.logLevel;
  }
  
  /**
   * 获取调用位置信息
   */
  private static getCallerInfo(): string {
    try {
      const stack = new Error().stack?.split('\n') || [];
      // 查找调用日志方法的位置(通常是栈的第3个元素)
      if (stack.length > 3) {
        const callerLine = stack[3].trim();
        const match = callerLine.match(/((.+):(\d+):(\d+))$/);
        if (match) {
          const fileName = match[1].split('/').pop()?.split('.')[0];
          return `[${fileName}:${match[2]}]`;
        }
      }
      return '';
    } catch (e) {
      return '';
    }
  }
  
  /**
   * 基础日志方法
   * @param level 日志级别
   * @param tag 模块标签
   * @param message 日志消息
   * @param args 附加参数
   */
  private static log(level: LogLevel, tag: string, message: string, ...args: any[]): void {
    if (!this.isLoggable(level)) return;
    
    const callerInfo = this.getCallerInfo();
    const formattedMsg = `${callerInfo} ${this.GLOBAL_TAG} [${tag}]: ${message}`;
    
    // 输出到系统日志
    switch (level) {
      case LogLevel.DEBUG:
        hilog.debug(this.DOMAIN, tag, `%{public}s`, formattedMsg, ...args);
        break;
      case LogLevel.INFO:
        hilog.info(this.DOMAIN, tag, `%{public}s`, formattedMsg, ...args);
        break;
      case LogLevel.WARN:
        hilog.warn(this.DOMAIN, tag, `%{public}s`, formattedMsg, ...args);
        break;
      case LogLevel.ERROR:
        hilog.error(this.DOMAIN, tag, `%{public}s`, formattedMsg, ...args);
        break;
    }
  }
  
  // 公共日志方法
  static debug(tag: string, message: string, ...args: any[]): void {
    this.log(LogLevel.DEBUG, tag, message, ...args);
  }
  
  static info(tag: string, message: string, ...args: any[]): void {
    this.log(LogLevel.INFO, tag, message, ...args);
  }
  
  static warn(tag: string, message: string, ...args: any[]): void {
    this.log(LogLevel.WARN, tag, message, ...args);
  }
  
  static error(tag: string, message: string, ...args: any[]): void {
    this.log(LogLevel.ERROR, tag, message, ...args);
  }
  
  /**
   * 记录网络请求
   * @param tag 模块标签
   * @param url 请求URL
   * @param method 请求方法
   * @param status 响应状态码
   * @param duration 请求耗时(ms)
   */
  static network(tag: string, url: string, method: string, status: number, duration: number): void {
    const color = status >= 400 ? 31 : status >= 300 ? 33 : 32; // 红/黄/绿
    const msg = `\x1b[${color}m${method} ${url} → ${status} (${duration}ms)\x1b[0m`;
    this.info(tag, msg);
  }
  
  /**
   * 记录性能指标
   * @param tag 模块标签
   * @param metricName 指标名称
   * @param value 指标值
   * @param unit 单位 (默认为ms)
   */
  static performance(tag: string, metricName: string, value: number, unit: string = 'ms'): void {
    this.info(tag, `⏱️ ${metricName}: ${value}${unit}`);
  }
}

三、使用封装后的日志工具

1. 在页面中调用

typescript 复制代码
// HomePage.ets
import { Logger, LogLevel } from '../utils/Logger';

const PAGE_TAG = "HomePage";

@Entry
@Component
struct HomePage {
  @State count: number = 0;

  aboutToAppear() {
    // 设置日志级别
    Logger.setLevel(LogLevel.DEBUG);
    
    // 记录初始化信息
    Logger.debug(PAGE_TAG, "页面初始化完成");
    Logger.performance(PAGE_TAG, "页面渲染", 85);
  }

  build() {
    Column() {
      Button('点击计数: ' + this.count)
        .onClick(() => {
          this.count++;
          Logger.info(PAGE_TAG, "按钮点击", { count: this.count });
        })
        
      Button('模拟网络请求')
        .onClick(() => {
          // 模拟网络请求
          Logger.network(PAGE_TAG, "/api/user", "GET", 200, 150);
          
          // 模拟错误请求
          setTimeout(() => {
            try {
              // 模拟错误
              throw new Error("连接超时");
            } catch (e) {
              Logger.error(PAGE_TAG, "网络请求失败", e);
            }
          }, 1000);
        })
    }
    .padding(20)
    .width('100%')
  }
}

2. 查看日志输出

在DevEco Studio中查看日志:

  1. 打开底部 Log 面板

  2. 选择 OpenLog 标签页

  3. 使用过滤器:

    bash 复制代码
    tag:HomePage level:D  # 查看HomePage的DEBUG日志
    domain:0x6688        # 查看本应用的所有日志

四、常见问题解决

1. 日志不显示

  • 检查设备是否连接到DevEco Studio
  • 确认 hilog.isLoggable 返回 true
  • 检查日志级别设置是否过高
  • 尝试重启ADB服务:hdc shell killall hilogd

2. 日志格式混乱

  • 确保格式化字符串与参数匹配
  • 避免在日志消息中使用特殊字符 {}%
  • 使用JSON序列化复杂对象

3. 性能问题

  • 生产环境禁用DEBUG日志
  • 避免在循环中记录大对象
  • 使用条件日志减少不必要的字符串拼接

总结

通过封装日志工具,您可以:

  1. 统一日志格式和输出方式
  2. 实现日志级别动态控制
  3. 自动捕获代码位置信息
  4. 增强敏感信息保护
  5. 添加网络请求和性能监控等高级功能
  6. 优化生产环境日志输出

这个封装方案提供了灵活、高效的日志管理能力,能显著提升HarmonyOS应用的开发调试效率。根据项目实际需求,您可以进一步扩展或调整功能模块。

相关推荐
lqj_本人10 小时前
鸿蒙OS&UniApp结合机器学习打造智能图像分类应用:HarmonyOS实践指南#三方框架 #Uniapp
机器学习·uni-app·harmonyos
哼唧唧_10 小时前
使用 React Native 开发鸿蒙运动健康类应用的高频易错点总结
react native·react.js·harmonyos·harmony os5·运动健康
二流小码农12 小时前
鸿蒙开发:loading动画的几种实现方式
android·ios·harmonyos
大胖子10113 小时前
HarmonyOS5ArkTS常见数据类型认识
harmonyos
大胖子10113 小时前
HarmonyOS5鸿蒙开发常用装饰器
harmonyos
大胖子10113 小时前
HarmonyOS5鸿蒙开发常用组件介绍
harmonyos
小镇梦想家14 小时前
鸿蒙NEXT-Flutter(1)
harmonyos
zhanshuo16 小时前
安卓→鸿蒙迁移实战:3步重构消息提示,解锁跨设备协同黑科技!
harmonyos
不爱吃糖的程序媛16 小时前
鸿蒙版Taro 搭建开发环境
华为·harmonyos·taro
zhanshuo17 小时前
鸿蒙实战:智能灯泡状态监控,低功耗预警方案揭秘!
harmonyos