鸿蒙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;
      }
    }
  }
}
相关推荐
I烟雨云渊T2 小时前
iOS 门店营收表格功能的实现
ios
Georgewu5 小时前
【 HarmonyOS 5 入门系列 】鸿蒙HarmonyOS示例项目讲解
harmonyos
androidwork6 小时前
Android LinearLayout、FrameLayout、RelativeLayout、ConstraintLayout大混战
android·java·kotlin·androidx
每次的天空6 小时前
Android第十三次面试总结基础
android·面试·职场和发展
wu_android6 小时前
Android 相对布局管理器(RelativeLayout)
android
libo_20257 小时前
HarmonyOS5 元宇宙3D原子化服务开发实践
harmonyos
半路下车7 小时前
【Harmony OS 5】DevEco Testing重塑教育质量
harmonyos·arkts
90后的晨仔7 小时前
解析鸿蒙 ArkTS 中的 Union 类型与 TypeAliases类型
前端·harmonyos
风浅月明7 小时前
[Harmony]颜色初始化
harmonyos·color
风浅月明8 小时前
[Harmony]网络状态监听
harmonyos·网络状态