目录
前言
在软件开发过程中,日志是调试和维护的关键工具。libhv 提供的 hlog 模块支持多种日志等级、格式化输出以及线程安全的日志记录,非常适合用于高性能应用。本文将介绍国产库 libhv 中的日志功能 hlog 的使用实例。hlog 提供了一套简单而强大的日志记录机制,适用于各种应用场景。
1.初始化
#include "hlog.h"
int main() {
hlog_set_level(LOG_LEVEL_DEBUG); // 设置日志等级
hlog_set_file("app.log"); // 设置日志文件
return 0;
}
2.日志记录
hlogd("This is a debug message.");
hlogi("This is an info message.");
hlogw("This is a warning message.");
hloge("This is an error message.");
hlogf("This is a fatal message.");
3.自定义格式
int userId = 42;
hlogi("User ID: %d", userId);
4.项目中的应用
4.1 案例1
int hmi_debug = 0,hmi_log = 1;
static void hmi_info_log_init(void)
{
const char *log_path = "/var/log";
const char *log_dir = "/var/log/HMILog";
const char *log_name = "hmi_info.log";
char hmi_log[128] = "hmi_info.log";
struct stat path_info; //用于存储文件或路径的状态信息
struct stat st = {0};
if (chdir(log_path) == 0) //是否切换到指定目录
{
if (hmi_debug)
{
printf("成功跳转到目录 %s\n", log_path);
}
// 检查hmi_log路径是否存在
if (stat(log_path, &path_info) == 0 && S_ISDIR(path_info.st_mode)) //获取log_path路径的状态信息,并检查是否是一个目录
{
if (hmi_debug)
{
printf("路径[%s] 存在!\n", log_path);
}
// 路径存在,继续检测log文件是否存在
if (stat(log_dir, &st) == -1)
{
if (mkdir(log_dir, 0777) == 0)
{
if (hmi_debug)
{
printf("创建文件夹[%s] 成功\n", log_dir);
}
sprintf(hmi_log, "%s/%s", log_dir, log_name);
}
else
{
if (hmi_debug)
printf("创建文件夹[%s] 失败\n", log_dir);
}
}
else
{
if (hmi_debug)
{
printf("文件夹[%s] 已存在 !\n", log_dir);
}
sprintf(hmi_log, "%s/%s", log_dir, log_name);
}
}
else
{
if (hmi_debug)
printf("路径[% s] 不存在! stat(%s, &path_info) :%d \n S_ISDIR:%d\n", log_path, log_path, stat(log_path, &path_info), S_ISDIR(path_info.st_mode));
}
}
else
{
if (hmi_debug)
{
printf("跳转到目录 %s 失败:%s\n", log_path, strerror(errno));
}
}
if (hmi_debug)
printf("hmi_log:%s\n", hmi_log);
hlog_set_file(hmi_log);
hlog_set_format("[HMI-INFO] %y-%m-%d %H:%M:%S.%z %L %s");
logger_enable_color(hlog, 1);
}
if(hmi_log)
{
hlogi("Failed to write registers: %s\n", modbus_strerror(errno));
}
4.2 案例2
#include <stdio.h>
#include <stdarg.h>
#include <pthread.h>
#include <errno.h>
#include <string.h>
// Define log levels
enum log_level {
BL_LOG_DEBUG,
BL_LOG_INFO,
BL_LOG_WARN,
BL_LOG_ERROR,
BL_LOG_FATAL
};
// Define global mutex for thread-safe logging
pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER;
// Thread-safe logging function
void log_safe(int level, const char *format, ...)
{
pthread_mutex_lock(&log_mutex);
const char* level_str = "";
switch (level) {
case BL_LOG_DEBUG: level_str = "DEBUG"; break;
case BL_LOG_INFO: level_str = "INFO"; break;
case BL_LOG_WARN: level_str = "WARN"; break;
case BL_LOG_ERROR: level_str = "ERROR"; break;
case BL_LOG_FATAL: level_str = "FATAL"; break;
}
printf("[%s] ", level_str);
va_list args;
va_start(args, format);
vprintf(format, args);
va_end(args);
printf("\n");
pthread_mutex_unlock(&log_mutex);
}
// Define logging macros
#define bls_logd(fmt, ...) log_safe(BL_LOG_DEBUG, fmt, ## __VA_ARGS__)
#define bls_logi(fmt, ...) log_safe(BL_LOG_INFO, fmt, ## __VA_ARGS__)
#define bls_logw(fmt, ...) log_safe(BL_LOG_WARN, fmt, ## __VA_ARGS__)
#define bls_loge(fmt, ...) log_safe(BL_LOG_ERROR, fmt, ## __VA_ARGS__)
#define bls_logf(fmt, ...) log_safe(BL_LOG_FATAL, fmt, ## __VA_ARGS__)
int main(void)
{
bls_logi("now init sucess !!!");
bls_loge("XSUB-XPUB proxy interrupted: %s", zmq_strerror(errno));
return 0;
}