鸿蒙开发:console日志输出

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 针对初学者而言,大家只需要掌握住日志打印即可,等到了鸿蒙应用开发的时候,还有一个鸿蒙原生的打印工具HiLog,到时,我们也会详细的去讲述,也会针对HiLog,封装一个通用的工具类。

前言

本文代码案例基于Api13。

可以说,任何一种语言,都少不了日志,正因为有了日志,让开发者开发功能,排查问题,才显得游刃有余,一段代码执行的是否正确,某个结果是否匹配一致,等等,简简单单,一个日志打印,便可轻松知晓。

有过前端开发经验的同学,对于console,想必是非常的熟悉,它的使用方式和前端可以说是一模一样的,毕竟ArkTs是基于TypeScript而来的。

简单举例


我们随便打印一个内容,比如hello world,直接使用console.log()即可。


console.log("hello world")


以上的代码,我们还是放在点击事件中执行,这一段代码是鸿蒙应用的主页面,在上一章节中,我们有过概述,大家一定要注意,特别是刚入门的开发者,因为再接下来的所有代码执行,我们都是在这个点击事件中进行执行,并且进行逻辑的验证。


@Entry
@Component
struct Index {
  @State message: string = '测试代码';
  build() {
    RelativeContainer() {
      Text(this.message)
        .fontSize(50)
        .fontWeight(FontWeight.Bold)
        .alignRules({
          center: { anchor: '__container__', align: VerticalAlign.Center },
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })
        .onClick(() => {
          //点击事件,用于测试代码
          console.log("hello world")
        })
    }
    .height('100%')
    .width('100%')
  }
}


点击模拟器或者真机右边的第一个绿色按钮,进行运行。



页面很是简单,和之前的一样。



点击“测试代码”文字,在控制台中,我们可以发现内容已经输出:



console方法概述


console是一个全局对象,可以直接访问,虽然说可以直接访问,但并不意味着它可以在任何的地方都能调用,使用它必须得有承载的逻辑,比如在方法中,在一个点击事件中,如果你直接写到一个类中,或者UI页面中,这个是完全禁止的,这一点,初学者需要注意。


常用方法汇总


方法

描述

debug

以格式化输出方式打印调试信息。

log

以格式化输出方式打印日志信息。

info

以格式化输出方式打印日志信息。(console.log()的别名)

warn

以格式化输出方式打印警告信息。

error

以格式化输出方式打印错误信息。


方法参数:


参数名

类型

必填

说明

message

string

表示要打印的文本信息。

arguments

any[]

表示其余要打印的信息或message的替换值。


常用方法举例

使用方式,和前言中的案例一样,大家选择具体的场景调用即可,比如你想打印警告信息,你就可以使用warn方法,错误信息,就可以使用error方法,每个方法对应的级别是不一样的,而且在颜色上也有所区分。

我们还是在点击事件中进行代码编写:

console.debug("===打印调试信息")
  console.log("===打印日志信息")
  console.info("===打印日志信息")
  console.warn("===打印警告信息")
  console.error("===打印错误信息")

点击“测试代码”后,控制台输出如下,可以发现警告是黄色的,而错误信息则是红色的。


设置Tag标签


一个日志,如果没有指定的tag标签,在茫茫的控制台中,寻找起来是非常费劲的,所以,在日常的开发中,聪明的程序员都会设置一些指定的tag标签,便于在控制台中快速的寻找。


比如在上面的日志输出中,我加了三个等号“===”,其作用就是用于标记,可以让控制台中以此作为检索。



tag可以直接和内容进行拼接,在前中后都无所谓,一般习惯而言,会放在前边,tag一般作为唯一性,特殊性,这样方便我们针对日志进行检索:


console.debug("===打印调试信息")


除了上边的设置tag之外,也可以多个参数进行设置,毕竟console是支持可变参数设置的。


console.debug("Tag标识:", "打印调试信息")


控制台输出如下:



日志等级概念


所谓的等级,只是覆盖度的问题,比如在上面的案例中,我们打印了所有类型的日志输出,代码如下:


console.debug("===打印调试信息")
console.log("===打印日志信息")
console.info("===打印日志信息")
console.warn("===打印警告信息")
console.error("===打印错误信息")


当我们在控制台选择日志等级的时候,如下所示:



它们的覆盖度是debug>info>warn>error,也就是选择debug,所有类型的日志都会输出,如果你选择了error,那么它只会输出error这一种类型。


其它方法概述


日常的开发中,常见的方法已经完全满足,毕竟只是一个日志打印,但是,在console中还有着其它的方法,同样有着实际的用处,我们简单做一个介绍。


assert断言


言的作用用于调试和测试,用于验证表达式是否为真,如果不为真则抛出异常‌。


参数:

参数名

类型

必填

说明

value

Object

语句结果值。若value为假(false)或者省略,则输出以"Assertion failed"开头。如果 value 为真值(true),则无打印。

arguments

Object

value为假(false)的后续错误消息打印。省略则不打印。


如果表达式为真,则后面不会输出日志,像下面的案例,在控制台中是没有任何日志输出的。


console.assert(true, "表达式结果值为true, 无打印")


如果表达式为假,后面的日志则会输出,并且以"Assertion failed"开头。


console.assert(false, "表达式结果值为false, 进行控制台打印")



断言一般用于验证前边的逻辑是否为真,比如判断一个求和函数是否为等于10。


console.assert(this.add(6, 5) == 10, "求和函数 add(6, 5) 不为10,我就打印日志")


求和函数,关于函数,后面会重点讲述。


add(a: number, b: number): number {
    return a + b
  }


由于传递的是6和5,相加不为10,则表达式为假,就会在控制台中进行打印。



count计数


维护一个内部计数器,调用时,打印此标签名以及对应的计数次数。

参数:

参数名

类型

必填

说明

label

string

计数器标签名。默认值为'default'。


由于默认值是default,所以,加与不加都是一样的。

console.count()
console.count('default')
console.count()


我们看下控制台打印:


当然了,你可以定义任意的标签名,比如我定义了一个test标签名:


console.count("test")
console.count("test")
console.count("test")

控制台打印:


countReset清除计数


此方法主要用于清除指定标签名的计数,比如,还是上面的案例,我们调用一下清除。

console.count("test")
console.count("test")
console.countReset("test")
console.count("test")

控制台打印如下,可以清楚的看到,执行了清除了之后,计数已经发生了变化。

dir对象

此方法主要用于对象内容打印。

参数:

参数名

类型

必填

说明

dir

Object

需要打印内容的对象。省略则无任何打印。

对象可以直接以大括号的形式:

console.dir({ "name": "AbnerMing" })


控制台效果:



直接打印一个创建的对象:


console.dir(new Test())
class Test {
  name: string = "AbnerMing"
}


控制台效果:



两者的区别,大家可能看到了,自己创建的对象,打印会显示对象的名字,如果直接大括号形式打印,则会显示Object。


除了使用dir进行对象打印之外,其实我们也可以通过JSON.stringify()方式进行对象打印,用常见的打印方式即可。


console.log(JSON.stringify(Object({ "name": "AbnerMing" })))


控制台效果:


group缩进

默认将后续行的缩进增加两个空格。如果提供需要打印的信息,则首先打印信息,没有额外的缩进。

参数:


参数名

类型

必填

说明

arguments

Object

要打印的信息。

举例打印:

console.log("我是打印的第一条信息")
console.group()
console.log("我是打印的第二条信息")
console.group()
console.log("我是打印的第三条信息")

控制台效果,可以发现只要使用了group,后续的日志就会有缩进的效果。


groupCollapsed缩进


使用与功能同console.group()一致。

参数:

参数名

类型

必填

说明

arguments

Object

要打印的信息。

console.log("我是打印的第一条信息")
console.groupCollapsed()
console.log("我是打印的第二条信息")
console.groupCollapsed()
console.log("我是打印的第三条信息")


控制台效果:


groupEnd


将后续行的缩进减少两个空格。

console.log("我是打印的第一条信息")
console.groupCollapsed()
console.log("我是打印的第二条信息")
console.groupEnd()
console.log("我是打印的第三条信息")

控制台打印效果:


table表格


以表格形式打印数据。

参数:

参数名

类型

必填

说明

tableData

Object

要打印为表格形式的对象。省略则无任何打印。

打印举例:

console.table([1, 2, 3])


控制台打印效果:

打印举例2:

console.table({ a: [1, 2, 3], b: 4, c: { e: 5 } });


控制台打印效果:


time


启动可用于计算操作持续时间的计时器。可使用console.timeEnd()关闭计时器并打印经过的时间(单位:ms)。

参数:

参数名

类型

必填

说明

label

string

计时器标识。默认值为'default'。


示例:

console.time("AbnerMing")


timeEnd

停止之前通过调用 console.time() 启动的计时器并将打印经过的时间(单位:ms)。

参数:

参数名

类型

必填

说明

label

string

计时器标识。默认值为'default'


示例:

console.time("AbnerMing")
console.timeEnd("AbnerMing")


控制台打印效果:

timeLog

对于先前通过调用 console.time() 启动的计时器,打印经过时间和其他data参数。

参数:

参数名

类型

必填

说明

label

string

计时器标识。默认值为'default'

arguments

Object

需要打印的其他日志。


示例:

console.time('AbnerMing')
console.timeLog('AbnerMing', 88)
console.timeEnd('AbnerMing')


控制台打印效果:


trace


打印当前堆栈。

参数:

参数名

类型

必填

说明

arguments

Object

需要打印的其他日志。省略则仅打印堆栈信息。

示例:

console.trace("显示堆栈信息")


控制台打印效果:


日志工具类封装


平常的开发中,我们可以直接使用console进行打印,这是完全没问题的,但是在项目开发中,一般会兼顾着正式包和测试包,比如测试包下日志正常输出,当正式包时为了性能,就需要关闭日志打印,那么就需要针对日志做一个开关处理;除此之外,针对输出的日志进行格式化处理,美观处理等等,就不得不需要针对现有的日志工具进行再次的封装,已满足我们日后的开发。

工具类全部源码,大家可以复制直接使用:

/**
 * AUTHOR:AbnerMing
 * DATE:2025/1/17
 * INTRODUCE:日志打印工具类
 * */
export class Console {
  private logTag: string = "AbnerMing" //日志tag
  private logClose: boolean = false //日志是否关闭
  /*
* Author:AbnerMing
* Describe:私有化构造器
*/
  private constructor() {
  }
  /*
* Author:AbnerMing
* Describe:提供一个外部可访问的的静态方法
*/
  public static getInstance() {
    if (!Console.mConsole) {
      Console.mConsole = new Console()
    }
    return Console.mConsole
  }
  private static mConsole: Console
  /**
   * 初始化
   * @param logTag { string } 日志tag
   * @param logClose { boolean } 是否关闭打印日志
   */
  init(logClose?: boolean, logTag?: string) {
    if (logTag != undefined) {
      this.logTag = logTag
    }
    if (logClose != undefined) {
      this.logClose = logClose
    }
  }
  static log(message: string, tag?: string) {
    Console.getInstance().print(message, tag, LogType.LOG)
  }
  static info(message: string, tag?: string) {
    Console.getInstance().print(message, tag, LogType.INFO)
  }
  static debug(message: string, tag?: string) {
    Console.getInstance().print(message, tag, LogType.DEBUG)
  }
  static warn(message: string, tag?: string) {
    Console.getInstance().print(message, tag, LogType.WARN)
  }
  static error(message: string, tag?: string) {
    Console.getInstance().print(message, tag, LogType.ERROR)
  }
  /**
   * 日志打印
   * @param tag { string } 日志tag
   * @param message { Object } 日志内容
   */
  private print(message: Object, tag?: string, logType?: LogType) {
    if (this.logClose) {
      return
    }
    let lTag = this.logTag
    if (tag != undefined) {
      lTag = tag
    }
    switch (logType) {
      case LogType.DEBUG:
        console.debug(this.getMessage(lTag, message))
        break
      case LogType.LOG:
      case LogType.INFO:
        console.log(this.getMessage(lTag, message))
        break
      case LogType.WARN:
        console.warn(this.getMessage(lTag, message))
        break
      case LogType.ERROR:
        console.error(this.getMessage(lTag, message))
        break
    }
  }
  /**
   * 获取输出位置
   * */
  getMessage(tag: string, message: Object): string {
    let log = "┌───────" + tag + "────────────────────────────────────────────────────────────────────────────────"
    log = log.substring(0, log.length - tag.length) + "\n"
    try {
      const stackTrace = new Error().stack
      const traceArray = stackTrace!.split('\n')
      const trace = traceArray[traceArray.length-2]
      log = log + "|" + trace + "\n"
      let type = typeof message
      if (type == "object") {
        //是对象
        message = this.getObjectToJson(message)
      } else if (type == "string") {
        //判断是否包含大括号
        const content = message + ""
        if (content.startsWith("{") && content.endsWith("}")) {
          //对象
          const obj: string = JSON.parse(String(message))
          message = this.getObjectToJson(obj)
        } else {
          message = content
        }
      }
      log = log + "\n|    " + message
    } catch (e) {
    }
    log = log + "\n└───────────────────────────────────────────────────────────────────────────────────────"
    return log
  }
  /**
   * 对象转json
   * @param message
   * @returns
   */
  private getObjectToJson(message: Object): String {
    const json = JSON.stringify(message, null, 2)
    const endMessage = json.replace(/\n/g, "\n|    ")
    return endMessage
  }
}
enum LogType {
  DEBUG, LOG, INFO, WARN, ERROR
}


初始化,有两个参数看一个是日志打印开关,一个是日志的Tag,都可以进行全局设置,大家可以在AbilityStage里进行初始化。


Console.getInstance().init(false,"AbnerMing")


普通打印


Console.error("我是一个普通打印")


控制台效果,经过美化之后的日志输出,可以看到还是很直观的,还有打印的日志位置,可以点击直接的定位,可以说非常的方便。



对象打印:


Console.error(Object({ "name": "AbnerMing", "age": 18 }))


控制台效果,对象也进行了格式化处理。


小结


针对初学者而言,大家只需要掌握住日志打印即可,等到了鸿蒙应用开发的时候,还有一个鸿蒙原生的打印工具HiLog,到时,我们也会详细的去讲述,也会针对HiLog,封装一个通用的工具类。


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
22天前
鸿蒙开发:如何实现文本跑马灯效果
如果只是一个普通的跑马灯效果,而且Text文本组件中的TextOverflow.MARQUEE可以满足需求,以Text为主,如果你想控制文本的速度,暂停等功能,可以使用Marquee,如果你想实现复杂的场景滚动,比如图片,各种组件嵌套滚动,这种只能自己定义了。
鸿蒙开发:如何实现文本跑马灯效果
|
18天前
|
前端开发
鸿蒙开发:使用Rect绘制矩形
几何矩形,在实际的开发中,有多种的实现方式,并非一定需要Rect组件,但是,如果有需要用到矩形的场景,建议还是使用Rect组件,因为Rect组件自身携带了很多样式属性,可以满足我们日常的不同的需求。
鸿蒙开发:使用Rect绘制矩形
|
21天前
|
Android开发 容器
鸿蒙开发:动态添加节点
流程就是,通过typeNode来创建自己的组件,然后使用追加到FrameNode节点中,然后将自定义节点挂载到NodeContainer上即可,主要使用场景,需要动态创建组件的场景。
鸿蒙开发:动态添加节点
|
18天前
|
人工智能 物联网 Android开发
【04】优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-自定义一个设置输入小部件组件-完成所有设置setting相关的页面-优雅草卓伊凡
【04】优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-自定义一个设置输入小部件组件-完成所有设置setting相关的页面-优雅草卓伊凡
154 92
|
18天前
|
人工智能 物联网 Android开发
【03】优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-在lib目录新建自定义库UtilsLibrary,ComponentLibrary,CommonConstLibrary完成设置SettingsView.ets初始公共类书写-优雅草卓伊凡
【03】优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-在lib目录新建自定义库UtilsLibrary,ComponentLibrary,CommonConstLibrary完成设置SettingsView.ets初始公共类书写-优雅草卓伊凡
57 23
【03】优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-在lib目录新建自定义库UtilsLibrary,ComponentLibrary,CommonConstLibrary完成设置SettingsView.ets初始公共类书写-优雅草卓伊凡
|
20天前
|
存储 调度 开发者
HarmonyOS Next 实战卡片开发 03
本文详细介绍了基于 HarmonyOS Next 的卡片开发实战,涵盖从项目创建到功能实现的全流程。首先通过新建项目和服务卡片搭建基础框架,并设置沉浸式体验优化界面。接着实现了首页轮播图功能,包括申请网络权限、初始化数据和构建轮播组件。随后深入讲解了卡片 id 的处理,涉及获取、返回、持久化存储及移除操作,确保卡片与应用间的高效通信。此外,封装了下载图片工具类,支持卡片发起通知获取网络图片,增强功能扩展性。最后实现了卡片同步轮播功能,使首页与卡片轮播状态保持一致。整个流程注重细节,结合实际案例,为开发者提供了全面的参考。
62 20
HarmonyOS Next 实战卡片开发 03
|
21天前
|
移动开发 JavaScript API
HarmonyOS Next 简单上手元服务开发
本文介绍了 HarmonyOS Next 中元服务的开发流程与关键特性。元服务是一种轻量级应用程序形态,支持免安装、秒开直达,适用于听音乐、打车等场景,大幅提升服务获取效率。文章详细讲解了元服务的开发旅程,包括在 AGC 平台上新建项目、修改名称与图标、新增卡片等内容,并提供了代码示例,如 AtomicServiceTabs 的 tab 切换和标题设置、AtomicServiceNavigation 的路由管理等。此外,还探讨了 AtomicServiceWeb 的使用方法,涵盖鸿蒙页面与 h5 页面的数据传递及方法调用。
92 20
HarmonyOS Next 简单上手元服务开发
|
18天前
|
存储 人工智能 物联网
【02】优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-登录页面LoginView.ets完成-并且详细解释关于arkui关于 CommonConst, commonColor, InputDataModel-优雅草卓伊凡
【02】优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-登录页面LoginView.ets完成-并且详细解释关于arkui关于 CommonConst, commonColor, InputDataModel-优雅草卓伊凡
48 14
【02】优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-登录页面LoginView.ets完成-并且详细解释关于arkui关于 CommonConst, commonColor, InputDataModel-优雅草卓伊凡
|
20天前
HarmonyOS Next 实战卡片开发 02
本文介绍了 HarmonyOS Next 实战中卡片开发的图片显示技术,包括本地图片和网络图片的处理方法。对于本地图片,通过截图、选择图片、复制到临时目录并传递给卡片组件完成显示;而对于网络图片,则需申请网络权限,下载图片至本地后再按本地图片流程处理。文中详细展示了代码实现步骤与关键点,如使用 `PhotoViewPicker` 选择图片、`http` 下载网络资源以及通过 `formImages` 传递图片数据,确保图片在卡片中正确显示。
43 14
HarmonyOS Next 实战卡片开发 02
|
18天前
|
人工智能 物联网 编译器
【01】优雅草星云物联网AI智控系统从0开发鸿蒙端适配完成流程-初始化鸿蒙编译器deveco studio项目结构-UI设计图切片下载-优雅草卓伊凡
【01】优雅草星云物联网AI智控系统从0开发鸿蒙端适配完成流程-初始化鸿蒙编译器deveco studio项目结构-UI设计图切片下载-优雅草卓伊凡
42 11
【01】优雅草星云物联网AI智控系统从0开发鸿蒙端适配完成流程-初始化鸿蒙编译器deveco studio项目结构-UI设计图切片下载-优雅草卓伊凡

热门文章

最新文章