harmony-log 是一个面向 HarmonyOS 的日志库,接口风格对齐 apple/swift-log,支持:
Logger值语义式使用(copy())LoggingSystem.bootstrap(...)全局一次性初始化- 结构化 metadata(标量/数组/字典)
MetadataProvider/MDC上下文注入- 多后端组合(
MultiplexLogHandler) - 标准后端:
Console、HiLog、Stream、InMemory、NoOp - 惰性消息与日志级别裁剪
- GitHub: https://github.com/NeptuneKit/harmony-log
- Issues: https://github.com/NeptuneKit/harmony-log/issues
通过 ohpm 安装:
ohpm install harmony-log
# 或
ohpm i harmony-log安装后从 Index.ets 导出使用:
import { Logger, HarmonyLogLevel } from 'harmony-log';import { Logger, HarmonyLogLevel } from 'harmony-log';
const logger = Logger.logger('Order');
logger.level = HarmonyLogLevel.DEBUG;
logger.info('create order', { orderId: 1001 });
logger.error(
'create failed',
{ orderId: 1001, reason: 'network' },
'OrderService',
'src/main/ets/order/OrderService.ets',
'createOrder',
42
);bootstrap 只能调用一次;后续再次调用会抛错(与 swift-log 语义一致)。
import { LoggingSystem, Logger, HarmonyLogLevel } from 'harmony-log';
LoggingSystem.bootstrap((label: string) => ({
minimumLevel: HarmonyLogLevel.INFO,
log(record) {
console.info(`[${label}] ${record.message}`);
}
}));
Logger.logger('Network').info('request sent');- 支持结构化值:
string | number | boolean | null | array | dictionary - 合并顺序:
logger metadatametadata providerlog-site metadata
- 同 key 后者覆盖前者
- 值为
undefined时表示删除该 key
import { LoggingSystem, Logger, MDC, HarmonyLogLevel } from 'harmony-log';
MDC.global.set('requestId', 'req-1001');
MDC.global.set('userId', 42);
LoggingSystem.bootstrap(
() => ({
minimumLevel: HarmonyLogLevel.INFO,
log(record) {
console.info(record.metadata);
}
}),
MDC.metadataProvider()
);
Logger.logger('Checkout').info('start');- 输出到
console.debug/info/warn/error
- 输出到 Harmony
hilog - 默认 domain:
0xD001
standardOutput(label)/standardError(label)- 适合统一文本流格式输出
import { StreamLogHandler, Logger, HarmonyLogLevel } from 'harmony-log';
const stream = StreamLogHandler.standardOutput('App');
stream.minimumLevel = HarmonyLogLevel.DEBUG;
stream.setMetadata('service', 'checkout');
Logger.setGlobalHandlers([stream]);- 组合多个 handler
- 会按各子 handler 的
minimumLevel分发
import {
Logger,
MultiplexLogHandler,
ConsoleLogHandler,
HiLogHandler
} from 'harmony-log';
Logger.setGlobalHandlers([
new MultiplexLogHandler([
new ConsoleLogHandler(),
new HiLogHandler(0xD002)
])
]);- 用于测试、缓冲和调试
import { InMemoryLogHandler, Logger } from 'harmony-log';
const memory = new InMemoryLogHandler();
Logger.setGlobalHandlers([memory]);
Logger.logger('Test').info('hello');
console.info(memory.getEntries());
memory.clear();- 丢弃全部日志(压测或静默场景)
import { Logger, HarmonyLogNoOpHandler } from 'harmony-log';
Logger.setGlobalHandlers([new HarmonyLogNoOpHandler()]);实现 HarmonyLogHandler 即可接入你自己的日志后端(例如远程上报):
import {
HarmonyLogHandler,
HarmonyLogLevel,
HarmonyLogRecord,
Logger
} from 'harmony-log';
class RemoteLogHandler implements HarmonyLogHandler {
minimumLevel: HarmonyLogLevel = HarmonyLogLevel.WARNING;
private queue: HarmonyLogRecord[] = [];
log(record: HarmonyLogRecord): void {
if (record.level < this.minimumLevel) {
return;
}
this.queue.push(record);
if (this.queue.length >= 20 || record.level >= HarmonyLogLevel.ERROR) {
this.flush();
}
}
private flush(): void {
const batch = [...this.queue];
this.queue = [];
// TODO: 替换为真实网络上报逻辑
// uploadLogs(batch)
console.info(`[RemoteLogHandler] upload ${batch.length} logs`);
}
}
// 方案 1:全局注册
Logger.addGlobalHandler(new RemoteLogHandler());只给某个 logger 使用时:
const logger = Logger.logger('Payment');
logger.handlers = [new RemoteLogHandler()];消息和 metadata 支持闭包形式,未命中级别时不会求值:
import { Logger, HarmonyLogLevel } from 'harmony-log';
Logger.setCompileTimeMinimumLevel(HarmonyLogLevel.WARNING);
const logger = Logger.logger('Perf');
let heavyCall = 0;
logger.info(() => {
heavyCall += 1;
return 'expensive';
});
// heavyCall 仍为 0import { Logger, HarmonyLogLevel } from 'harmony-log';
const a = Logger.logger('Copy');
a.level = HarmonyLogLevel.INFO;
a.setMetadata('key', 'v1');
const b = a.copy();
b.level = HarmonyLogLevel.ERROR;
b.setMetadata('key', 'v2');
// a 与 b 的 level/metadata 互不影响node --test tests/harmony-log-core.test.mjs当前测试覆盖:
- bootstrap 单次约束
- metadata 合并/删除
- provider/MDC 注入
- multiplex/no-op/stream/in-memory 行为
- 惰性求值与级别裁剪
- source 推断与 copy 语义
MIT License. See LICENSE.