How to Improve Logging in ArkTS: A Better Alternative to hilog with LogManager?



This content originally appeared on DEV Community and was authored by HarmonyOS

Read the original article:How to Improve Logging in ArkTS: A Better Alternative to hilog with LogManager?

AI Generated Image

Overcome hilog’s limitations in HarmonyOS by using a reusable LogManager class for better formatting, filtering, and chunking.

Introduction

When developing HarmonyOS applications with ArkTS, developers typically use the low-level hilog API for runtime logging. While functional, hilog lacks essential features for large-scale or production-grade applications. Its limitations—such as a 4096-byte message cap, lack of runtime log level control, and unstructured outputs—can quickly become obstacles.

In this article, we’ll explore a robust solution: a reusable LogManager class that wraps hilog and addresses its shortcomings with structured output, dynamic filtering, and automatic chunking for large log messages.

Why hilog Falls Short in Real Projects

hilog is the native logging interface provided in HarmonyOS and ArkTS. However, it comes with the following issues:

  • Message Length Limit: Any message over 4096 bytes is truncated or dropped without warning, potentially hiding critical debug information.
  • No Runtime Filtering: You can’t change the logging level dynamically across environments, making it difficult to control verbosity in development vs production.
  • Unformatted Output: hilog provides raw logs without timestamps or consistent tagging, complicating debugging and log analysis. These gaps are often manually patched in individual modules, leading to inconsistent log patterns and maintenance overhead.

The LogManager Class: A Unified Logging Utility

To address the above challenges, we created a customLogManagerutility that enhanceshilogwhile preserving its native performance.

Key Features

  • Automatic Message Chunking: Breaks messages exceeding 4000 characters into safe chunks to prevent truncation.
  • Timestamped Output: Each log entry includes a timestamp, log level, and user-defined tag.
  • Runtime Log Level Control: Developers can adjust the active log level at runtime without modifying source code.
  • Unified API: Includes level-specific methods (debug, info, warn, error) and a general-purpose log() method.

Code Implementation: LogManager.ets

Example Usage

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

type LogLevel = 'debug' | 'info' | 'warn' | 'error';

export class LogManager {
  private static readonly MAX_LOG_LENGTH = 4000;
  private static readonly DOMAIN_ID = 0x1000;
  private static readonly LEVELS: LogLevel[] = ['debug', 'info', 'warn', 'error'];
  private static LOG_LEVEL: LogLevel = 'debug';

  static setLogLevel(level: LogLevel): void {
    if (LogManager.LEVELS.includes(level)) {
      LogManager.LOG_LEVEL = level;
    }
  }

  private static isLevelEnabled(level: LogLevel): boolean {
    const currentIndex = LogManager.LEVELS.indexOf(LogManager.LOG_LEVEL);
    const levelIndex = LogManager.LEVELS.indexOf(level);
    return levelIndex >= currentIndex;
  }

  private static getTimestamp(): string {
    return new Date().toISOString();
  }

  private static chunkAndLog(
    levelFn: (domain: number, tag: string, message: string) => void,
    levelLabel: string,
    tag: string,
    message: string
  ): void {
    const timestamp = LogManager.getTimestamp();
    const prefix = `[${levelLabel}] [${timestamp}] [${tag}] `;
    const fullMessage = prefix + message;

    for (let i = 0; i < fullMessage.length; i += LogManager.MAX_LOG_LENGTH) {
      const part = fullMessage.substring(i, i + LogManager.MAX_LOG_LENGTH);
      levelFn(LogManager.DOMAIN_ID, tag, part);
    }
  }

  static debug(tag: string, message: string): void {
    if (!LogManager.isLevelEnabled('debug')) return;
    LogManager.chunkAndLog(hilog.debug, 'DEBUG', tag, message);
  }

  static info(tag: string, message: string): void {
    if (!LogManager.isLevelEnabled('info')) return;
    LogManager.chunkAndLog(hilog.info, 'INFO', tag, message);
  }

  static warn(tag: string, message: string): void {
    if (!LogManager.isLevelEnabled('warn')) return;
    LogManager.chunkAndLog(hilog.warn, 'WARN', tag, message);
  }

  static error(tag: string, message: string): void {
    if (!LogManager.isLevelEnabled('error')) return;
    LogManager.chunkAndLog(hilog.error, 'ERROR', tag, message);
  }

  static log(level: LogLevel, tag: string, message: string): void {
    switch (level) {
      case 'debug':
        return LogManager.debug(tag, message);
      case 'info':
        return LogManager.info(tag, message);
      case 'warn':
        return LogManager.warn(tag, message);
      case 'error':
        return LogManager.error(tag, message);
    }
  }
}

Runtime Level Filtering

LogManager.setLogLevel('warn');

LogManager.debug('AuthService', 'Debug info'); // Ignored
LogManager.warn('AuthService', 'Warning message'); // Logged
LogManager.error('AuthService', 'Critical failure'); // Logged

Using the Generic log() Method

LogManager.log('info', 'LoginScreen', 'User opened login screen');

Logging Large Messages Safely

const bigMessage = 'A'.repeat(10000);
LogManager.info('SyncService', bigMessage); // Safely chunked and logged

🧠 Pro Tip

Centralizing log logic not only prevents data loss from truncation but also promotes consistency and easier debugging. It’s especially valuable in multi-module apps or enterprise-scale HarmonyOS projects.

Conclusion

Native hilog is suitable for simple logging, but it quickly shows its limits in complex HarmonyOS applications. By introducing LogManager, we gain:

  • Resilience against message truncation
  • Structured and timestamped logs
  • Centralized log level management
  • Cleaner, more maintainable logging practices

Ready to take your ArkTS logging to the next level? Try integrating LogManager and experience the difference.

References

hiLog

https://forums.developer.huawei.com/forumPortal/en/topic/0203190278605586072?fid=0101187876626530001

Written by Arif Emre Ankara


This content originally appeared on DEV Community and was authored by HarmonyOS