Backend Development 15 min read

Logging Best Practices and Log4j Log Levels in Software Development

This article explains the importance of proper logging in software, outlines common logging requirements such as readability, performance, disk usage, and timeliness, and details Log4j components, log level definitions, hierarchy, recommended usage, and provides concrete macro and log‑statement examples.

Architecture Digest
Architecture Digest
Architecture Digest
Logging Best Practices and Log4j Log Levels in Software Development

Writing logs in a program is crucial for maintenance, debugging, auditing, performance analysis, and data tracking, yet developers often neglect it due to time pressure. Good logging habits should be established early, allocating sufficient time for log creation.

1.1 Purpose of Logs

Logs serve multiple needs: audit user actions, quickly locate issues, trace program execution, monitor data changes, gather statistics and performance data, and collect environment information. When an exception occurs, logs provide the first‑hand evidence needed to diagnose the problem.

1.2 Requirements for Writing Logs

Readability : Logs must be understandable by other developers; avoid excessive decorative symbols and use English to prevent encoding issues.

Performance : Logging consumes I/O resources; limit logging in tight loops and check log level before formatting (e.g., isDebugEnabled() ).

Disk Space : Use rotating logs and regularly clean old files to prevent disk exhaustion.

Timeliness : Retain logs for a reasonable period to allow retrospective analysis.

Log Levels : In production, logs are usually at INFO or higher; ensure sufficient information is available at these levels.

Content : Include business‑related descriptions, avoid sensitive data, and keep encoding consistent.

Format : Typical log entries contain timestamp, level, code location, message, and error code.

2 Log Levels and Their Meaning

Log4j, an Apache logging framework, allows configuration of log destinations, formats, and levels via a configuration file. Its three core components are:

Logger – controls which log statements are enabled and their level restrictions.

Appender – determines where logs are output (console, file, etc.).

Layout – defines the visual format of log messages.

Log4j defines six levels (from most detailed to most severe): TRACE , DEBUG , INFO , WARN , ERROR , FATAL . Only messages at or above the configured threshold are emitted.

Level descriptions:

TRACE : Very fine‑grained events, typically function entry/exit.

DEBUG : Detailed information useful during development.

INFO : High‑level runtime information important for production monitoring.

WARN : Potential issues that do not stop execution.

ERROR : Errors that allow the program to continue running.

FATAL : Severe errors causing application termination.

The level hierarchy is ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF , but Log4j recommends using the four levels DEBUG , INFO , WARN , and ERROR for most cases.

3 Log Specification Examples

Macro definitions for custom log levels (C/C++ style):

#define DRV_LOG_FATAL(fmt, ...)   hlog_format(HLOG_LEVEL_FATAL, "PluginDriver", "[%s(%d)] " fmt, __FUNCTION__, __LINE__, __VA_ARGS__)
#define DRV_LOG_ERROR(fmt, ...)   hlog_format(HLOG_LEVEL_ERROR, "PluginDriver", "[%s(%d)] " fmt, __FUNCTION__, __LINE__, __VA_ARGS__)
#define DRV_LOG_WARN(fmt, ...)    hlog_format(HLOG_LEVEL_WARN,  "PluginDriver", "[%s(%d)] " fmt, __FUNCTION__, __LINE__, __VA_ARGS__)
#define DRV_LOG_INFO(fmt, ...)    hlog_format(HLOG_LEVEL_INFO,  "PluginDriver", "[%s(%d)] " fmt, __FUNCTION__, __LINE__, __VA_ARGS__)
#define DRV_LOG_DEBUG(fmt, ...)   hlog_format(HLOG_LEVEL_DEBUG, "PluginDriver", "[%s(%d)] " fmt, __FUNCTION__, __LINE__, __VA_ARGS__)
#define DRV_LOG_TRACE(fmt, ...)   hlog_format(HLOG_LEVEL_TRACE, "PluginDriver", "[%s(%d)] " fmt, __FUNCTION__, __LINE__, __VA_ARGS__)

Sample log entries:

2022-05-22 15:35:53.850 TRACE TDWZLog [0x00001b10] <36> <TDWZProtocol::Init>,TDWZProtocol::Init
2022-05-22 15:39:36.382 WARN TrackLog [0x000029fc] - [ internal WARN htrace_server_convert_msgstring_to_contextintls(493) ] detect input id error, trace_id span_id, this chain may not be tracked.

Typical usage examples for each level:

DRV_LOG_TRACE("Connect Execute start");
DRV_LOG_DEBUG("- 输出报警情况:电网编号:%d,报警数量:%d,报警内容:%s.", datas.data1.chn, datas.data1.alarm_num, datas.data1.alarms);
DRV_LOG_INFO("- UpdataEvent nchal= %d,EventID = %d.", iChannelNo, nEventType);
DRV_LOG_WARN("[0x%08x] - invaild event msg,discard it", DRV_INVALID_ARG);
DRV_LOG_ERROR("Init DwSDK failed;
", initRet);

Understanding these practices and configurations helps developers produce clear, efficient, and maintainable logs, which are essential for troubleshooting and system reliability.

Backendsoftware developmentBest Practiceslogginglog4jlog levels
Architecture Digest
Written by

Architecture Digest

Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.