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应用的开发调试效率。根据项目实际需求,您可以进一步扩展或调整功能模块。

相关推荐
zhanshuo25 分钟前
在鸿蒙里优雅地处理网络错误:从 Demo 到实战案例
harmonyos
zhanshuo27 分钟前
在鸿蒙中实现深色/浅色模式切换:从原理到可运行 Demo
harmonyos
whysqwhw6 小时前
鸿蒙分布式投屏
harmonyos
whysqwhw7 小时前
鸿蒙AVSession Kit
harmonyos
whysqwhw9 小时前
鸿蒙各种生命周期
harmonyos
whysqwhw10 小时前
鸿蒙音频编码
harmonyos
whysqwhw10 小时前
鸿蒙音频解码
harmonyos
whysqwhw10 小时前
鸿蒙视频解码
harmonyos
whysqwhw10 小时前
鸿蒙视频编码
harmonyos
ajassi200010 小时前
开源 Arkts 鸿蒙应用 开发(十八)通讯--Ble低功耗蓝牙服务器
华为·开源·harmonyos