DEV Community

Cover image for HarmonyOS Next - Mastering Log Knowledge in One Article
kouwei qing
kouwei qing

Posted on

HarmonyOS Next - Mastering Log Knowledge in One Article

Logs are essential debugging tools in daily development. Good log tools and proper log calls can help us quickly locate issues during development or in the online environment, greatly improving development efficiency. Besides supporting the console printing of logs for TS in HarmonyOS Next, it also provides the hilog tool, which can implement log output at the ArkTS layer and the C++ layer. Additionally, we can use encapsulated and persistent log tools to help locate and solve online problems.

Next, these tools will be introduced in detail respectively.

1. console Tool

The Console module provides a simple debugging console, similar to the JavaScript console mechanism provided by browsers.

The console module offers the following functions according to log levels:

  • console.debug
  • console.info
  • console.warn
  • console.error
  • console.assert
  • console.log

These functions print log information of different levels in a formatted output way. console.info has the same function as console.log, and console.info is an alias for console.log. The function parameters are as follows:

Parameter Name Type Required Description
message string Yes Represents the text information to be printed.
arguments any[] No Represents other information to be printed or replacement values for the message.

Examples:

const number = 5;
console.info('count: %d', number);  // Formatted output, replacing the text in the message.
// count: 5 
console.info('count:', number);  // Prints the message and the rest of the information
// count: 5 
console.info('count:'); // Only prints the message
// count: 

const str = "name should be string";
console.warn('warn: %d', str);  // Formatted output, replacing the text in the message.
// warn: name should be string
console.warn('warn:', str);  // Prints the message and the rest of the information
// warn: name should be string
console.warn('warn:'); // Only prints the message
// warn: 

const str = "value is not defined";
console.error('error: %d', str);  // Formatted output, replacing the text in the message.
// error: value is not defined
console.error('error:', str);  // Prints the message and the rest of the information
// error: value is not defined
console.error('error:'); // Only prints the message
// error: 
Enter fullscreen mode Exit fullscreen mode

The parameters of the assertion printing function are slightly different:

Parameter Name Type Required Description
value Object No The result value of the statement. If value is false or omitted, the output starts with "Assertion failed". If value is true, nothing will be printed.
arguments Object No Prints the subsequent error message when value is false. If omitted, nothing will be printed.

Examples:

console.assert(true, 'does nothing');  // The expression result value is true, so nothing is printed.
console.assert(2 % 1 == 0, 'does nothing');  // The expression result value is true, so nothing is printed.

console.assert(false, 'console %s work', 'didn\'t');
// Assertion failed: console didn't work

console.assert();
// Assertion failed
Enter fullscreen mode Exit fullscreen mode

The console also provides the count function, which maintains an internal counter. When called, it prints the label name and the corresponding count number.

Example:

console.count()
// default: 1
console.count('default')
// default: 2
console.count('abc')
// abc: 1
console.count('xyz')
// xyz: 1
console.count('abc')
// abc: 2
console.count()
// default: 3
Enter fullscreen mode Exit fullscreen mode

You can use console.countReset to clear the count of the specified label name.

console.dir is used to print the content of an object:

class bar {
  baz: boolean = true;
}
let b: bar = {baz: true}
class foo{
  bar: bar = b;
}
let c: foo = {bar: b}
class  c1{
  foo: foo = c;
}
let a: c1 = {foo: c}
console.dir(a);
// Object: {"foo":{"bar":{"baz":true}}}

console.dir(); // Nothing will be printed
Enter fullscreen mode Exit fullscreen mode

console.dirxml is implemented by internally calling console.log(). This method does not generate any XML format. Its usage is the same as that of console.log(), and it can also be regarded as an alias for console.log().

const number = 5;
console.dirxml('count: %d', number);
// count: 5 
console.dirxml('count:', number);
// count: 5 
console.dirxml('count:');
// count: 
Enter fullscreen mode Exit fullscreen mode

console.group will, by default, increase the indentation of the subsequent lines by two spaces. If there is information that needs to be printed, it will print the information first without additional indentation.

console.log("outter");
// outter
console.group();
console.log("level 1");
//   level 1
console.group("in level1");
//   in level1
console.log("level 2");
//     level 2
Enter fullscreen mode Exit fullscreen mode

console.groupCollapsed has the same usage and function as console.group(). console.groupEnd will reduce the indentation of the subsequent lines by two spaces:

console.log("outter");
// outter
console.group();
console.log("level 1");
//   level 1
console.groupEnd();
console.log("outter");
// outter
Enter fullscreen mode Exit fullscreen mode

console.table prints data in a tabular form:

console.table([1, 2, 3]);
// ┌─────────┬────────┐
// │ (index) │ Values │
// ├─────────┼────────┤
// │    0    │   1    │
// │    1    │   2    │
// │    2    │   3    │ 
// └─────────┴────────┘

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

// ┌─────────┬───┬───┬───┬───┬───┬───┬────────┐
// │ (index) │ 0 │ 1 │ 2 │ 3 │ 4 │ e │ Values │
// ├─────────┼───┼───┼───┼───┼───┼───┼────────┤
// │    a    │ 1 │ 2 │ 3 │ 4 │ 5 │   │        │
// │    b    │   │   │   │   │   │   │   5    │
// │    c    │   │   │   │   │   │ 5 │        │
// └─────────┴───┴───┴───┴───┴───┴───┴────────┘
Enter fullscreen mode Exit fullscreen mode

console.time starts a timer that can be used to calculate the duration of an operation. You can use console.timeEnd() to stop the timer and print the elapsed time (in milliseconds).

console.time('abc');
console.timeEnd('abc');
// abc: 225.438ms
Enter fullscreen mode Exit fullscreen mode

console.timeLog prints the elapsed time and other data parameters for a timer previously started by calling console.time().

console.time('timer1');
console.timeLog('timer1', 17);
// timer1: 365.227ms 17
console.timeEnd('timer1');
// timer1: 513.22ms
Enter fullscreen mode Exit fullscreen mode

console.trace is used to print the current stack.

console.trace();
// Trace:
//     xxxxxxxxxx(Current stack information)
console.trace("Show the trace");
// Trace: Show the trace
//     xxxxxxxxxx(Current stack information)
Enter fullscreen mode Exit fullscreen mode

console.traceHybridStack can print the current thread's hybrid stack information in the main thread/worker thread:

console.traceHybridStack();
// TraceHybridStack:
//     xxxxxxxxxx(Current thread hybrid stack information)
Enter fullscreen mode Exit fullscreen mode

2. hilog

The hilog logging system enables applications/services to output log content according to specified levels, identifiers, and format strings, helping developers understand the running status of applications/services and better debug programs.

2.1 hilog in ArkTS

First, you need to import the module:

import { hilog } from '@kit.PerformanceAnalysisKit';
Enter fullscreen mode Exit fullscreen mode

hilog also provides log printing functions for different levels:

  • hilog.debug: DEBUG-level logs are not printed by default in the official release version. They will only be printed in the debug version or when the debug switch is turned on.
  • hilog.info
  • hilog.warn
  • hilog.error
  • hilog.fatal

Parameter Explanation:

Parameter Name Type Required Description
domain number Yes The domain identifier corresponding to the log, with a range of 0x0~0xFFFF.

It is recommended that developers customize the division according to their needs within the application.
tag string Yes Specifies the log identifier, which can be any string. It is recommended to use it to identify the class or business behavior where the call is located. The tag can be at most 31 bytes. If it exceeds this length, it will be truncated. It is not recommended to use Chinese characters, as there may be garbled characters or alignment problems.
format string Yes The format string used for the formatted output of the log. Multiple parameters can be set in the format string, and the parameters need to include the parameter type and privacy identifier.

The privacy identifiers are divided into {public} and {private}. The default is {private}. The content marked with {public} will be output in plain text, and the content marked with {private} will be filtered and displayed as <private>.
args any[] No A variable-length parameter list corresponding to the format string format. The number and types of parameters must correspond one-to-one with the identifiers in the format string.

Here's an explanation of the role of the privacy identifier:
Output a FATAL message with the format string "%{public}s World %{private}d". Here, the variable parameter %{public}s is a string displayed in plain text, and %{private}d is a private integer.
hilog.fatal(0x0001, "testTag", "%{public}s World %{private}d", "hello", 3);
The string "hello" is filled into %{public}s, and the integer 3 is filled into %{private}d. The output log is:
08-05 12:21:47.579 2695 2703 F A00001/testTag: hello World <private>. If you find that the output log is private, remember to check here.

hilog also provides the isLoggable function. Call this interface before printing logs to check whether logs with the specified domain identifier, log identifier, and level can be printed. The parameter description is as follows:

Parameter Name Type Required Description
domain number Yes The domain identifier corresponding to the log, with a range of 0x0~0xFFFF.

It is recommended that developers customize the division according to their needs within the application.
tag string Yes Specifies the log identifier, which can be any string. It is recommended to use it to identify the class or business behavior where the call is located. The tag can be at most 31 bytes. If it exceeds this length, it will be truncated. It is not recommended to use Chinese characters, as there may be garbled characters or alignment problems.
level LogLevel Yes The log level.

If it returns true, the logs with the specified domain identifier, log identifier, and level can be printed; otherwise, they cannot be printed.

2.2 hilog in C++

In C++ code, developers can use these interfaces to implement log-related functions. When outputting logs, they can specify the log type, the business domain to which they belong, the log TAG identifier, the log level, and so on.

During the application development process, log information can be output at key code points. After running the application, analyze the application's execution situation by viewing the log information (such as whether the application is running normally, the code's running sequence, whether the running logic branches are normal, etc.).

The HiLog logging system is provided for the system framework, services, and applications to print logs and record user operations, system running status, and so on.

The HiLog defines five log levels: DEBUG, INFO, WARN, ERROR, and FATAL, and provides corresponding methods to output logs of different levels. The interfaces are shown in the following table:

Method/Macro Interface Description
bool OH_LOG_IsLoggable(unsigned int domain, const char *tag, LogLevel level) Checks whether logs with the specified domain, tag, and log level can be printed.

If the specified log can be printed, it returns true; otherwise, it returns false.
int OH_LOG_Print(LogType type, LogLevel level, unsigned int domain, const char *tag, const char *fmt,...) Outputs logs with the specified domain, tag, and log level, and determines the variable parameters to be output according to the printf format type and privacy indication.

If the printing is successful, it returns the total number of bytes of the log; if it fails, it returns -1.
#define OH_LOG_DEBUG(type,...) ((void)OH_LOG_Print((type), LOG_DEBUG, LOG_DOMAIN, LOG_TAG, __VA_ARGS__)) Writes DEBUG-level logs, a macro-encapsulated interface.
#define OH_LOG_INFO(type,...) ((void)OH_LOG_Print((type), LOG_INFO, LOG_DOMAIN, LOG_TAG, __VA_ARGS__)) Writes INFO-level logs, a macro-encapsulated interface.
#define OH_LOG_WARN(type,...) ((void)OH_LOG_Print((type), LOG_WARN, LOG_DOMAIN, LOG_TAG, __VA_ARGS__)) Writes WARN-level logs, a macro-encapsulated interface.
#define OH_LOG_ERROR(type,...) ((void)OH_LOG_Print((type), LOG_ERROR, LOG_DOMAIN, LOG_TAG, __VA_ARGS__)) Writes ERROR-level logs, a macro-encapsulated interface.
#define OH_LOG_FATAL(type,...) ((void)OH_LOG_Print((type), LOG_FATAL, LOG_DOMAIN, LOG_TAG, __VA_ARGS__)) Writes FATAL-level logs, a macro-encapsulated interface.
void OH_LOG_SetCallback(LogCallback callback) A registration function. After registration, all hilog logs of the current process can be obtained through the LogCallback callback.

OH_LOG_IsLoggable() and OH_LOG_Print() should use consistent domain, tag, and level.

  • domain: Used to specify the business domain corresponding to the output log, with a value range of 0x0000~0xFFFF. Developers can customize it according to their needs.
  • tag: Used to specify the log identifier, which can be any string. It is recommended to use it to identify the class or business behavior where the call is located. The tag can be at most 31 bytes. If it exceeds this length, it will be truncated. It is not recommended to use Chinese characters, as there may be garbled characters or alignment problems.
  • level: Used to specify the log level. See LogLevel for the value.
  • fmt: The format string used for the formatted output of the log. The formatted parameters for log printing should be printed in the format of "%{private flag}specifier".
Privacy Identifier (private flag) Description
private Indicates that the log printing result is invisible, and the output result is <private>.
public Indicates that the log printing result is visible, and the parameter is displayed in plain text.
None The default value is private, and the log printing result is invisible.
Format Specifier (specifier) Description Example
d/i Supports printing number, bool, and bigint types. 123
s Supports printing string, undefined, and null types. "123"
  • Multiple parameters can be set in the format string. For example, if the format string is "%s World", "%s" is the variable parameter identifier with the parameter type string, and the specific

Top comments (0)