Files
SyncCalendar/entry/src/main/ets/common/LogUtil.ets
T

135 lines
4.6 KiB
Plaintext
Raw Normal View History

2026-09-13 15:50:37 +08:00
// entry/src/main/ets/common/LogUtil.ets
// 日志工具:默认**只输出到 console(hilog)**,不落盘。
//
// ⭐ 0.0.8 起:发行版**不再写 sync.log**(原「同步记录」/诊断落盘功能已移除)。
// 需要真机排查同步/提醒问题时,把下面的 ENABLE_FILE_LOG 改成 true 重新编译即可恢复
// 落盘(含 512KB 自动截断保留后半),其余调用点一行都不用动。
// 关闭状态下会在 init 时顺手删掉历史版本遗留的 sync.log 与 mirror_diag.txt,
// 保证升级上来的设备沙箱也是干净的。
2026-09-13 15:50:37 +08:00
import { common } from '@kit.AbilityKit';
import { fileIo as fs } from '@kit.CoreFileKit';
import { util } from '@kit.ArkTS';
import { BusinessError } from '@kit.BasicServicesKit';
2026-09-13 15:50:37 +08:00
export class LogUtil {
/** ⭐ 落盘开关:发行版置 false(仅 console);真机排查时改 true 恢复文件日志 */
private static readonly ENABLE_FILE_LOG: boolean = false;
private static dir: string = '';
private static path: string = '';
private static readonly MAX_BYTES: number = 512 * 1024;
2026-09-13 15:50:37 +08:00
static init(context: common.Context): void {
try {
LogUtil.dir = context.filesDir;
LogUtil.path = `${LogUtil.dir}/sync.log`;
} catch (err) {
LogUtil.dir = '';
LogUtil.path = '';
}
if (!LogUtil.ENABLE_FILE_LOG && LogUtil.dir !== '') {
LogUtil.removeLegacyDebugFiles();
}
}
/** 删除历史版本遗留的调试落盘文件(sync.log / mirror_diag.txt) */
private static removeLegacyDebugFiles(): void {
for (const name of ['sync.log', 'mirror_diag.txt']) {
try {
fs.unlinkSync(`${LogUtil.dir}/${name}`);
} catch (err) {
// 文件不存在属正常,忽略
}
}
2026-09-13 15:50:37 +08:00
}
static logFilePath(): string {
return LogUtil.path;
}
/** 写一行日志:console + 文件(发行版不落盘;文件失败静默,不影响业务) */
2026-09-13 15:50:37 +08:00
static write(msg: string): void {
console.info(`SyncLog ${msg}`);
if (!LogUtil.ENABLE_FILE_LOG) {
return;
}
if (LogUtil.path === '') {
return;
}
try {
const d = new Date();
const p = (n: number): string => n < 10 ? '0' + n : String(n);
const ts: string = `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}` +
` ${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`;
// 超限截断:保留最后 256KB
try {
const st: fs.Stat = fs.statSync(LogUtil.path);
if (st.size > LogUtil.MAX_BYTES) {
LogUtil.truncate();
}
} catch (err) {
// 文件不存在属正常,直接创建写入
}
const file: fs.File = fs.openSync(LogUtil.path,
fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE | fs.OpenMode.APPEND);
fs.writeSync(file.fd, `[${ts}] ${msg}\n`);
fs.closeSync(file.fd);
} catch (err) {
// 写日志失败不影响业务
}
}
/** 截断:只保留文件末尾 256KB */
private static truncate(): void {
try {
const keep: number = 256 * 1024;
const st: fs.Stat = fs.statSync(LogUtil.path);
const size: number = Math.min(st.size, keep);
const file = fs.openSync(LogUtil.path, fs.OpenMode.READ_ONLY);
const buf: ArrayBuffer = new ArrayBuffer(size);
fs.readSync(file.fd, buf, { offset: st.size - size });
fs.closeSync(file.fd);
const out = fs.openSync(LogUtil.path,
fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE | fs.OpenMode.TRUNC);
fs.writeSync(out.fd, `…(日志过长,已截断保留末尾)\n`);
fs.writeSync(out.fd, new Uint8Array(buf));
fs.closeSync(out.fd);
} catch (err) {
// 截断失败忽略,下次再试
}
2026-09-13 15:50:37 +08:00
}
static readAll(context: common.Context): string {
try {
if (LogUtil.path === '') {
LogUtil.init(context);
}
if (LogUtil.path === '') {
return '(无法确定日志路径)';
}
const st: fs.Stat = fs.statSync(LogUtil.path);
if (st.size === 0) {
return '(日志为空)';
}
const file = fs.openSync(LogUtil.path, fs.OpenMode.READ_ONLY);
const buf: ArrayBuffer = new ArrayBuffer(st.size);
fs.readSync(file.fd, buf);
fs.closeSync(file.fd);
const decoder: util.TextDecoder = util.TextDecoder.create('utf-8');
return decoder.decodeToString(new Uint8Array(buf));
} catch (err) {
return `(读取日志失败: ${(err as BusinessError).message})`;
}
2026-09-13 15:50:37 +08:00
}
static clear(context: common.Context): void {
try {
if (LogUtil.path === '') {
LogUtil.init(context);
}
fs.unlinkSync(LogUtil.path);
} catch (err) {
// 文件不存在等,忽略
}
2026-09-13 15:50:37 +08:00
}
}