在这里插入图片描述

你是不是也在想——“鸿蒙这么火,我能不能学会?”
答案是:当然可以!
这个专栏专为零基础小白设计,不需要编程基础,也不需要懂原理、背术语。我们会用最通俗易懂的语言、最贴近生活的案例,手把手带你从安装开发工具开始,一步步学会开发自己的鸿蒙应用。
不管你是学生、上班族、打算转行,还是单纯对技术感兴趣,只要你愿意花一点时间,就能在这里搞懂鸿蒙开发,并做出属于自己的App!
📌 关注本专栏《零基础学鸿蒙开发》,一起变强!
每一节内容我都会持续更新,配图+代码+解释全都有,欢迎点个关注,不走丢,我是小白酷爱学习,我们一起上路 🚀

前言

开发 HarmonyOS 应用时,很多人第一次接触 HiLog 都会遇到同一个疑惑:明明在代码里打了日志,DevEco Studio 的日志面板里却显示 <private>,完全看不到实际的值。

这不是 bug,是 HiLog 的隐私保护机制在工作。弄清楚 %{public} 和 %{private} 的区别,是写出"能用的日志"的第一步。

一、这个机制解决什么问题

应用日志在开发阶段是调试工具,但日志本身也会被系统记录,甚至在某些情况下被导出用于问题定位。如果日志里直接出现用户名、手机号、订单号、Token、URL,一旦泄露就是隐私问题。

HiLog 的解决思路是:让开发者在写日志时主动声明每个参数的隐私级别。如果你声明这个值是 public,系统就输出明文;如果声明是 private,或者干脆不声明,系统就把这个值替换成 <private>,不管实际内容是什么。

这不是调试模式和发布模式的区别,也不是 Log Level 的问题。只要你不显式标注 %{public},这个参数就永远不会在日志里以明文出现。

二、把规则弄清楚

格式字符串的写法

HiLog 的格式字符串遵循这个结构:

%{隐私标识}参数类型

比如:

  • %{public}s —— 字符串,公开输出
  • %{private}s —— 字符串,输出 <private>
  • %s —— 字符串,未标识,等同于 %{private}s,输出 <private>
  • %{public}d —— 整数,公开输出
  • %{private}d —— 整数,输出 <private>

官方文档明确说明:如果不填写隐私标识,则默认为 private,不输出明文日志。

支持的参数类型:

类型符说明
s字符串
d / i整数
f浮点数
o / O对象(按 JSON 格式输出)

模块和 API 信息

  • 所属 Kit:PerformanceAnalysisKit
  • 导入方式:import { hilog } from '@kit.PerformanceAnalysisKit';
  • 系统能力:SystemCapability.HiviewDFX.HiLog
  • 起始支持版本:API 9(对应 HarmonyOS 3.1 / 3.0 及以上)
  • 仅支持 Stage 模型

hilog 提供五个级别的打印方法,签名相同:

hilog.debug(domain: number, tag: string, format: string, ...args: unknown[]): void
hilog.info(domain: number, tag: string, format: string, ...args: unknown[]): void
hilog.warn(domain: number, tag: string, format: string, ...args: unknown[]): void
hilog.error(domain: number, tag: string, format: string, ...args: unknown[]): void
hilog.fatal(domain: number, tag: string, format: string, ...args: unknown[]): void

domain 的范围是 0x0000~0xFFFF,用来标识日志所属的子系统,可以自行按业务划分。

tag 最多 31 字节,超出部分会被截断,不支持中文字符。

三、搭一个最小验证场景

用四类典型数据做对比:

  • 用户名(一般可以公开用于调试)
  • 订单号(敏感,应该保护)
  • 错误码(业务码,通常可以公开)
  • URL(可能含有 token 参数,需要谨慎)

目标:通过同一段代码,观察不同隐私标识在日志面板中的实际输出差异。

四、核心代码实现

先建好基础结构,确认 hilog 正确导入。

import { hilog } from '@kit.PerformanceAnalysisKit';

下面是一个最小示例,在一个按钮点击后触发日志打印,涵盖四种典型数据:

import { hilog } from '@kit.PerformanceAnalysisKit';

const DOMAIN = 0x0001;
const TAG = 'LogDemo';

@Entry
@Component
struct LogDemoPage {
  build() {
    Column({ space: 20 }) {
      Button('触发日志演示')
        .onClick(() => {
          this.printDemoLogs();
        })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }

  printDemoLogs(): void {
    const username: string = 'Alice';
    const orderId: string = 'ORD-20250601-99281';
    const errorCode: number = 4042;
    const requestUrl: string = 'https://api.example.com/orders?token=abc123';

    // 用户名:公开,调试时需要看到具体值
    hilog.info(DOMAIN, TAG, 'username: %{public}s', username);

    // 订单号:私有,输出 <private>
    hilog.info(DOMAIN, TAG, 'orderId: %{private}s', orderId);

    // 错误码:公开,排查问题需要明文
    hilog.error(DOMAIN, TAG, 'errorCode: %{public}d', errorCode);

    // URL(含 token 参数):私有保护
    hilog.info(DOMAIN, TAG, 'requestUrl: %{private}s', requestUrl);

    // 演示未标识时的默认行为(等同于 private)
    hilog.info(DOMAIN, TAG, 'no-tag orderId: %s', orderId);
  }
}

点击按钮后,日志面板中预期看到的输出:

I  username: Alice
I  orderId: <private>
E  errorCode: 4042
I  requestUrl: <private>
I  no-tag orderId: <private>

五、几个关键点拆开看

1. 未标识不等于"运行时可见"

很多人以为不写 {public} 或 {private} 的话,日志默认是可见的——这个理解是反的。

官方规定是:未标注隐私级别,一律视为 private。写 %s 和写 %{private}s 在日志输出上完全一致,都会看到 <private>。

这也是为什么很多人第一次使用 HiLog 时,觉得"日志打了没反应"。

2. %{public} 不受 Log Level 影响

有开发者会猜:是不是 DEBUG 模式下 private 才显示明文?

不是。HiLog 的隐私标识是独立于日志级别的机制,%{private} 在 debug、info、error 等任意级别下都只会显示 <private>,与是否是调试包无关。

3. 混用标识时,每个参数独立处理

一条日志里可以同时包含 public 和 private 参数,系统分别处理每个占位符:

hilog.info(DOMAIN, TAG, 'user: %{public}s, token: %{private}s', username, token);
// 输出:user: Alice, token: <private>

每个参数只关心自己的标识,互不影响。

4. domain 和 tag 的实际作用

domain 是数值型的日志域标识,在 DevEco Studio 日志面板中用于过滤,实际开发里可以按模块划分,比如 0x0001 对应订单模块,0x0002 对应账户模块。

tag 是字符串标签,方便在日志面板直接搜索定位。注意它不支持中文,且超过 31 字节会被截断,命名时注意控制长度。

5. 对象类型用 %o / %O

如果要把一个对象整体打出来,用 %{public}o 或 %{public}O,系统会按 JSON 格式输出对象内容。同样,不标 public 的话整个对象都是 <private>。

六、容易踩坑的地方

坑 1:用 console.log 替代 HiLog

HarmonyOS 应用开发中 console.log 也能输出日志,但它没有隐私保护机制,也没有 domain/tag 管理,在生产阶段可能造成敏感信息泄露。官方推荐使用 hilog,不建议在应用代码里依赖 console.log 做正式日志。

坑 2:把 URL 整体标为 public

URL 参数里经常携带 token、session_id 等敏感字段。如果图方便把整个 URL 字符串标成 %{public}s,实际上把这些参数也一并暴露在日志里了。更稳妥的方式是只打出 URL 的路径部分,把包含参数的完整 URL 标成 private,或者在打印前手动把敏感参数过滤掉。

坑 3:tag 写了中文

tag 参数不支持中文,如果写了中文标签,实际输出时 tag 字段会出现乱码或截断,导致在日志面板里按 tag 过滤失效。建议始终用英文或拼音缩写。

坑 4:format 和 args 数量不匹配

format 里有几个占位符,args 里就要传几个对应的值。数量不一致不会在编译期报错,但运行时日志输出可能出现参数错位或显示异常。

七、实际排查思路

如果遇到日志中出现 <private>,排查顺序建议这样走:

  1. 确认是否忘记写隐私标识 —— 检查 format 字符串,看是否写了 %s、%d 这类没有 {public} 的占位符。
  2. 确认是否显式写了 {private} —— 如果业务上这个值本来就不应该明文输出,那 <private> 是正常行为。
  3. 确认 domain 和 tag 是否在日志面板过滤条件内 —— 有时候不是 <private> 的问题,而是这条日志压根没被筛选出来。
  4. 确认 hilog.isLoggable 是否拦截了这条日志 —— 如果在代码里用了 isLoggable 做前置判断,注意 domain/tag/level 三个参数必须完全匹配才能返回 true。
  5. 确认 import 路径是否正确 —— 应该是 import { hilog } from '@kit.PerformanceAnalysisKit',不是其他路径。

开发经验总结

  • HiLog 不标隐私级别的参数,默认就是 private,这个设计是主动保护,不是 bug。
  • %{public} 和 %{private} 是写在 format 字符串里的,不是函数参数,初次接触容易找错位置。
  • 敏感数据的判断没有统一标准,核心原则是:如果这个值出现在日志文件里被他人看到会造成问题,就用 private。
  • tag 只支持英文,写中文是无效的,DevEco Studio 里会搜不到。
  • 真正养成习惯之后,%{public} 和 %{private} 加起来不过几个字符,但对于日志合规来说是必要的成本。

如果你的项目里目前用的还是裸 %s 或者 console.log,可以搜一下代码里有多少地方直接打印了带敏感字段的字符串,逐步替换成明确标注隐私级别的 hilog 调用,这比事后出了问题再修代价小很多。

❤️ 如果本文帮到了你…

  • 请点个赞,让我知道你还在坚持阅读技术长文!
  • 请收藏本文,因为你以后一定还会用上!
  • 如果你在学习过程中遇到bug,请留言,我帮你踩坑!
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐