鸿蒙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;
      }
    }
  }
}
相关推荐
浩浩乎@4 分钟前
【openGLES】安卓端EGL的使用
android
YungFan34 分钟前
iOS26适配指南之UINavigationController
ios·swift
Kotlin上海用户组1 小时前
Koin vs. Hilt——最流行的 Android DI 框架全方位对比
android·架构·kotlin
请叫我小蜜蜂同学1 小时前
【鸿蒙】鸿蒙操作系统发展综述
华为·harmonyos
zzq19962 小时前
Android framework 开发者模式下,如何修改动画过度模式
android
木叶丸2 小时前
Flutter 生命周期完全指南
android·flutter·ios
阿幸软件杂货间2 小时前
阿幸课堂随机点名
android·开发语言·javascript
没有了遇见2 小时前
Android 渐变色整理之功能实现<二>文字,背景,边框,进度条等
android
HMS Core2 小时前
借助HarmonyOS SDK,《NBA巅峰对决》实现“分钟级启动”到“秒级进场”
华为·harmonyos
二二孚日3 小时前
自用华为ICT云赛道AI第一章知识点-机器学习概览
人工智能·华为