鸿蒙NEXT开发日志工具类(ArkTs)

复制代码
import hilog from '@ohos.hilog';
import { JSON } from '@kit.ArkTS';
import { BusinessError } from '@kit.BasicServicesKit';
import { StrUtil } from './StrUtil';

/**
 * 日志工具类
 * author: 鸿蒙布道师
 * since: 2024/03/31
 */
export class LogUtil {
  private static logSize: number = 2048;
  private static domain: number = 0x0000;
  private static tag: string = 'HarmonyUtilsLog'; // 日志Tag
  private static showLog: boolean = true; // 是否显示打印日志
  private static isHilog: boolean = true; // true-hilog、false-console

  /**
   * 初始化日志参数(该方法建议在Ability里调用)
   * @param domain - 领域标识
   * @param tag - 日志标签
   * @param showLog - 是否显示日志
   * @param isHilog - 是否使用hilog
   */
  static init(domain: number = LogUtil.domain, tag: string = LogUtil.tag, showLog: boolean = true,
    isHilog: boolean = true): void {
    LogUtil.domain = domain;
    LogUtil.tag = tag;
    LogUtil.showLog = showLog;
    LogUtil.isHilog = isHilog;
  }

  /**
   * 设置领域标识
   * @param domain - 领域标识
   */
  static setDomain(domain: number = LogUtil.domain): void {
    LogUtil.domain = domain;
  }

  /**
   * 设置日志标签
   * @param tag - 日志标签
   */
  static setTag(tag: string = LogUtil.tag): void {
    LogUtil.tag = tag;
  }

  /**
   * 设置是否显示日志
   * @param showLog - 是否显示日志
   */
  static setShowLog(showLog: boolean = true): void {
    LogUtil.showLog = showLog;
  }

  /**
   * 设置日志打印方式
   * @param isHilog - true-hilog、false-console
   */
  static setHilog(isHilog: boolean): void {
    LogUtil.isHilog = isHilog;
  }

  /**
   * 打印DEBUG级别日志
   * @param args - 日志内容
   */
  static debug(...args: (string | object)[]): void {
    LogUtil.uniLog(args, hilog.LogLevel.DEBUG);
  }

  /**
   * 打印INFO级别日志
   * @param args - 日志内容
   */
  static info(...args: (string | object)[]): void {
    LogUtil.uniLog(args, hilog.LogLevel.INFO);
  }

  /**
   * 打印WARN级别日志
   * @param args - 日志内容
   */
  static warn(...args: (string | object)[]): void {
    LogUtil.uniLog(args, hilog.LogLevel.WARN);
  }

  /**
   * 打印ERROR级别日志
   * @param args - 日志内容
   */
  static error(...args: (string | object)[]): void {
    LogUtil.uniLog(args, hilog.LogLevel.ERROR);
  }

  /**
   * 打印FATAL级别日志
   * @param args - 日志内容
   */
  static fatal(...args: (string | object)[]): void {
    LogUtil.uniLog(args, hilog.LogLevel.FATAL);
  }

  /**
   * 打印JSON对象或JSON字符串
   * @param msg - JSON对象或字符串
   */
  static print(msg: object | string): void {
    try {
      const content = LogUtil.formatMessage(msg);
      const len = Math.ceil(content.length / LogUtil.logSize);
      for (let i = 0; i < len; i++) {
        const end = Math.min((i + 1) * LogUtil.logSize, content.length);
        const logMsg = `\n${content.substring(i * LogUtil.logSize, end)}`;
        LogUtil.levelLog(logMsg, hilog.LogLevel.DEBUG);
      }
    } catch (err) {
      const error = err as BusinessError;
      console.error(`LogUtil-print-异常 ~ code: ${error.code} -·- message: ${error.message}`);
    }
  }

  /**
   * 统一日志输出
   * @param message - 日志内容
   * @param level - 日志级别
   */
  private static uniLog(message: (string | object)[], level: hilog.LogLevel): void {
    if (!LogUtil.showLog) return;

    const topLine = LogUtil.getLine(LogUtil.tag);
    LogUtil.levelLog(topLine, level);

    if (level === hilog.LogLevel.ERROR) {
      const locationLog = LogUtil.getLogLocation();
      LogUtil.levelLog(locationLog, level);
    }

    const content = LogUtil.formatMessage(message);
    const len = Math.ceil(content.length / LogUtil.logSize);
    for (let i = 0; i < len; i++) {
      const end = Math.min((i + 1) * LogUtil.logSize, content.length);
      const logMsg = `\n|  ${content.substring(i * LogUtil.logSize, end)}`;
      LogUtil.levelLog(logMsg, level);
    }

    const bottomLine = LogUtil.getLine('');
    LogUtil.levelLog(bottomLine, level);
  }

  /**
   * 格式化日志内容
   * @param message - 日志内容,可以是字符串、对象或数组
   */
  private static formatMessage(message: (string | object)[] | object | string): string {
    let logMessage = '';

    // Handle array input
    if (Array.isArray(message)) {
      message.forEach((msg: string | object) => {
        logMessage += typeof msg === 'object' ? LogUtil.getObjectToJson(msg) : String(msg);
      });
    }
    // Handle object input
    else if (typeof message === 'object') {
      logMessage = LogUtil.getObjectToJson(message);
    }
    // Handle string input
    else {
      logMessage = String(message);
    }

    return logMessage;
  }

  /**
   * 对象转JSON字符串
   * @param obj - 对象
   * @param line - 是否格式化换行
   */
  private static getObjectToJson(obj: object, line: boolean = true): string {
    try {
      let jsonStr = JSON.stringify(obj, null, 2);
      if (line) {
        jsonStr = jsonStr.replace(/\n/g, '\n|\t');
        jsonStr = jsonStr.replace(/..$/, '  ');
      }
      return jsonStr;
    } catch {
      return '';
    }
  }

  /**
   * 获取代码位置
   */
  private static getLogLocation(): string {
    const stackArray = new Error().stack?.split('\n').filter(item => item.trim() !== '').splice(-2) ?? [];
    const errorLocation = stackArray.join('\n').replace(/\s+/g, '');
    return `\n|  ${errorLocation}`;
  }

  /**
   * 获取生成的日志边框
   * @param tag - 日志标签
   * @param length - 边框长度
   */
  private static getLine(tag: string = '', length: number = 160): string {
    if (StrUtil.isNotEmpty(tag)) {
      return `┌${StrUtil.repeat('─', 10)} ${tag} ${StrUtil.repeat('─', length - tag.length - 2)}`;
    }
    return `└${StrUtil.repeat('─', 10)}${StrUtil.repeat('─', length)}`;
  }

  /**
   * 日志打印
   * @param msg - 日志内容
   * @param level - 日志级别
   */
  private static levelLog(msg: string, level: hilog.LogLevel): void {
    if (LogUtil.isHilog) {
      // Explicitly call the appropriate hilog method based on the log level
      switch (level) {
        case hilog.LogLevel.DEBUG:
          hilog.debug(LogUtil.domain, LogUtil.tag, msg);
          break;
        case hilog.LogLevel.INFO:
          hilog.info(LogUtil.domain, LogUtil.tag, msg);
          break;
        case hilog.LogLevel.WARN:
          hilog.warn(LogUtil.domain, LogUtil.tag, msg);
          break;
        case hilog.LogLevel.ERROR:
          hilog.error(LogUtil.domain, LogUtil.tag, msg);
          break;
        case hilog.LogLevel.FATAL:
          hilog.fatal(LogUtil.domain, LogUtil.tag, msg);
          break;
        default:
          console.error(`Unsupported log level: ${level}`);
          break;
      }
    } else {
      // Fallback to console logging if hilog is not enabled
      switch (level) {
        case hilog.LogLevel.DEBUG:
          console.debug(msg);
          break;
        case hilog.LogLevel.INFO:
          console.info(msg);
          break;
        case hilog.LogLevel.WARN:
          console.warn(msg);
          break;
        case hilog.LogLevel.ERROR:
          console.error(msg);
          break;
        case hilog.LogLevel.FATAL:
          console.log(msg);
          break;
        default:
          console.error(`Unsupported log level: ${level}`);
          break;
      }
    }
  }
}

代码如下:
TypeScript 复制代码
import hilog from '@ohos.hilog';
import { JSON } from '@kit.ArkTS';
import { BusinessError } from '@kit.BasicServicesKit';
import { StrUtil } from './StrUtil';

/**
 * 日志工具类
 * author: 鸿蒙布道师
 * since: 2024/03/31
 */
export class LogUtil {
  private static logSize: number = 2048;
  private static domain: number = 0x0000;
  private static tag: string = 'HarmonyUtilsLog'; // 日志Tag
  private static showLog: boolean = true; // 是否显示打印日志
  private static isHilog: boolean = true; // true-hilog、false-console

  /**
   * 初始化日志参数(该方法建议在Ability里调用)
   * @param domain - 领域标识
   * @param tag - 日志标签
   * @param showLog - 是否显示日志
   * @param isHilog - 是否使用hilog
   */
  static init(domain: number = LogUtil.domain, tag: string = LogUtil.tag, showLog: boolean = true,
    isHilog: boolean = true): void {
    LogUtil.domain = domain;
    LogUtil.tag = tag;
    LogUtil.showLog = showLog;
    LogUtil.isHilog = isHilog;
  }

  /**
   * 设置领域标识
   * @param domain - 领域标识
   */
  static setDomain(domain: number = LogUtil.domain): void {
    LogUtil.domain = domain;
  }

  /**
   * 设置日志标签
   * @param tag - 日志标签
   */
  static setTag(tag: string = LogUtil.tag): void {
    LogUtil.tag = tag;
  }

  /**
   * 设置是否显示日志
   * @param showLog - 是否显示日志
   */
  static setShowLog(showLog: boolean = true): void {
    LogUtil.showLog = showLog;
  }

  /**
   * 设置日志打印方式
   * @param isHilog - true-hilog、false-console
   */
  static setHilog(isHilog: boolean): void {
    LogUtil.isHilog = isHilog;
  }

  /**
   * 打印DEBUG级别日志
   * @param args - 日志内容
   */
  static debug(...args: (string | object)[]): void {
    LogUtil.uniLog(args, hilog.LogLevel.DEBUG);
  }

  /**
   * 打印INFO级别日志
   * @param args - 日志内容
   */
  static info(...args: (string | object)[]): void {
    LogUtil.uniLog(args, hilog.LogLevel.INFO);
  }

  /**
   * 打印WARN级别日志
   * @param args - 日志内容
   */
  static warn(...args: (string | object)[]): void {
    LogUtil.uniLog(args, hilog.LogLevel.WARN);
  }

  /**
   * 打印ERROR级别日志
   * @param args - 日志内容
   */
  static error(...args: (string | object)[]): void {
    LogUtil.uniLog(args, hilog.LogLevel.ERROR);
  }

  /**
   * 打印FATAL级别日志
   * @param args - 日志内容
   */
  static fatal(...args: (string | object)[]): void {
    LogUtil.uniLog(args, hilog.LogLevel.FATAL);
  }

  /**
   * 打印JSON对象或JSON字符串
   * @param msg - JSON对象或字符串
   */
  static print(msg: object | string): void {
    try {
      const content = LogUtil.formatMessage(msg);
      const len = Math.ceil(content.length / LogUtil.logSize);
      for (let i = 0; i < len; i++) {
        const end = Math.min((i + 1) * LogUtil.logSize, content.length);
        const logMsg = `\n${content.substring(i * LogUtil.logSize, end)}`;
        LogUtil.levelLog(logMsg, hilog.LogLevel.DEBUG);
      }
    } catch (err) {
      const error = err as BusinessError;
      console.error(`LogUtil-print-异常 ~ code: ${error.code} -·- message: ${error.message}`);
    }
  }

  /**
   * 统一日志输出
   * @param message - 日志内容
   * @param level - 日志级别
   */
  private static uniLog(message: (string | object)[], level: hilog.LogLevel): void {
    if (!LogUtil.showLog) return;

    const topLine = LogUtil.getLine(LogUtil.tag);
    LogUtil.levelLog(topLine, level);

    if (level === hilog.LogLevel.ERROR) {
      const locationLog = LogUtil.getLogLocation();
      LogUtil.levelLog(locationLog, level);
    }

    const content = LogUtil.formatMessage(message);
    const len = Math.ceil(content.length / LogUtil.logSize);
    for (let i = 0; i < len; i++) {
      const end = Math.min((i + 1) * LogUtil.logSize, content.length);
      const logMsg = `\n|  ${content.substring(i * LogUtil.logSize, end)}`;
      LogUtil.levelLog(logMsg, level);
    }

    const bottomLine = LogUtil.getLine('');
    LogUtil.levelLog(bottomLine, level);
  }

  /**
   * 格式化日志内容
   * @param message - 日志内容,可以是字符串、对象或数组
   */
  private static formatMessage(message: (string | object)[] | object | string): string {
    let logMessage = '';

    // Handle array input
    if (Array.isArray(message)) {
      message.forEach((msg: string | object) => {
        logMessage += typeof msg === 'object' ? LogUtil.getObjectToJson(msg) : String(msg);
      });
    }
    // Handle object input
    else if (typeof message === 'object') {
      logMessage = LogUtil.getObjectToJson(message);
    }
    // Handle string input
    else {
      logMessage = String(message);
    }

    return logMessage;
  }

  /**
   * 对象转JSON字符串
   * @param obj - 对象
   * @param line - 是否格式化换行
   */
  private static getObjectToJson(obj: object, line: boolean = true): string {
    try {
      let jsonStr = JSON.stringify(obj, null, 2);
      if (line) {
        jsonStr = jsonStr.replace(/\n/g, '\n|\t');
        jsonStr = jsonStr.replace(/..$/, '  ');
      }
      return jsonStr;
    } catch {
      return '';
    }
  }

  /**
   * 获取代码位置
   */
  private static getLogLocation(): string {
    const stackArray = new Error().stack?.split('\n').filter(item => item.trim() !== '').splice(-2) ?? [];
    const errorLocation = stackArray.join('\n').replace(/\s+/g, '');
    return `\n|  ${errorLocation}`;
  }

  /**
   * 获取生成的日志边框
   * @param tag - 日志标签
   * @param length - 边框长度
   */
  private static getLine(tag: string = '', length: number = 160): string {
    if (StrUtil.isNotEmpty(tag)) {
      return `┌${StrUtil.repeat('─', 10)} ${tag} ${StrUtil.repeat('─', length - tag.length - 2)}`;
    }
    return `└${StrUtil.repeat('─', 10)}${StrUtil.repeat('─', length)}`;
  }

  /**
   * 日志打印
   * @param msg - 日志内容
   * @param level - 日志级别
   */
  private static levelLog(msg: string, level: hilog.LogLevel): void {
    if (LogUtil.isHilog) {
      // Explicitly call the appropriate hilog method based on the log level
      switch (level) {
        case hilog.LogLevel.DEBUG:
          hilog.debug(LogUtil.domain, LogUtil.tag, msg);
          break;
        case hilog.LogLevel.INFO:
          hilog.info(LogUtil.domain, LogUtil.tag, msg);
          break;
        case hilog.LogLevel.WARN:
          hilog.warn(LogUtil.domain, LogUtil.tag, msg);
          break;
        case hilog.LogLevel.ERROR:
          hilog.error(LogUtil.domain, LogUtil.tag, msg);
          break;
        case hilog.LogLevel.FATAL:
          hilog.fatal(LogUtil.domain, LogUtil.tag, msg);
          break;
        default:
          console.error(`Unsupported log level: ${level}`);
          break;
      }
    } else {
      // Fallback to console logging if hilog is not enabled
      switch (level) {
        case hilog.LogLevel.DEBUG:
          console.debug(msg);
          break;
        case hilog.LogLevel.INFO:
          console.info(msg);
          break;
        case hilog.LogLevel.WARN:
          console.warn(msg);
          break;
        case hilog.LogLevel.ERROR:
          console.error(msg);
          break;
        case hilog.LogLevel.FATAL:
          console.log(msg);
          break;
        default:
          console.error(`Unsupported log level: ${level}`);
          break;
      }
    }
  }
}
相关推荐
笑鸿的学习笔记10 分钟前
ROS2笔记之服务通信和基于参数的服务通信区别
android·笔记·microsoft
8931519601 小时前
Android开发融云获取多个会话的总未读数
android·android开发·android教程·融云获取多个会话的总未读数·融云未读数
zjw_swun2 小时前
实现了一个uiautomator玩玩
android
pengyu2 小时前
系统化掌握Dart网络编程之Dio(二):责任链模式篇
android·flutter·dart
水w2 小时前
【Android Studio】如何卸载干净(详细步骤)
android·开发语言·android studio·activity
别说我什么都不会2 小时前
OpenHarmony 5.0(API 12)关系型数据库relationalStore 新增本地数据变化监听接口介绍
api·harmonyos
亦是远方2 小时前
2025华为软件精英挑战赛2600w思路分享
android·java·华为
jiet_h2 小时前
深入解析KSP(Kotlin Symbol Processing):现代Android开发的新利器
android·开发语言·kotlin
清晨細雨2 小时前
UniApp集成极光推送详细教程
android·ios·uni-app·极光推送
Li_na_na012 小时前
解决安卓手机WebView无法直接预览PDF的问题(使用PDF.js方案)
android·pdf·uni-app·html5