【封装一个日志库(linux)】【转载】

原文链接:

工具库1:封装一个日志库(linux)-CSDN博客

一、,需求

(1)封装一个c/c++日志库,提供格式打印接口,编写程序代码时方便使用;

(2) 格式打印接口支持可变参数;

(3)格式打印接口封装成可变参数宏,便于使用;

二,实现

(1)提供格式打印接口;

(2)日志等级分成三个级别,分别是错误、警告、普通信息;

(3)支持输出到终端,同时支持输出到指定日志文件;

(4)格式打印接口支持可变参数;

(5)打印字符串长度无限制;

三,源码

(1)messages.h

复制代码
/**
*****************************************************************************
*  Copyright (C), 2023-2024
*
*  @file    messages.h
*  @brief   printf pretty
*
*
*  @author  sbinhuang
*  @date    2023-06-28
*  @version v1.0.0 20230628
*----------------------------------------------------------------------------
*  @note 历史版本   修改人员    修改日期      修改内容
*  @note v1.0    sbinhuang   2023-06-28   1.创建
*
*****************************************************************************
*/
#ifndef _SELF_UTILITY_MESSAGES_H_
#define _SELF_UTILITY_MESSAGES_H_
#include <iostream>
#include <fstream>

namespace SelfUtility {
// message type
enum MessageType {
    NONE  = 0,
    ERROR = 1,
    WARN  = 2,
    INFO  = 3
};

class Messages {
 public:
    // default close file and enable terminal output
    static bool Init();
    // open log file
    // mode = true, open or create file and clear file content
    // mode = false, open or create file, doesn't clear file content
    static bool OpenLogFile(const char *file_name, bool mode = 0);
    // close log file
    static bool CloseLogFile();
    // enable terminal output
    static bool EnableTerminalOutput();
    // disable terminal output
    static bool DisableTerminalOutput();
    // print message for variable argument
    static bool Message(const MessageType &type, const char *file_name,
        int line_number, const char *format, ...);
    // print message for determine argument
    static bool Message(const MessageType &type, const char *file_name,
        int line_number, const char *format);

 private:
    static std::ofstream _os;
    static bool _terminal_output;
    static bool _write_file;
};

}  // namespace SelfUtility

#define LOG_ERROR(format, ...) do { \
    SelfUtility::Messages::Message(SelfUtility::MessageType::ERROR, \
                          __FILE__, __LINE__, format, __VA_ARGS__); \
} while (0)

#define LOG_WARN(format, ...) do { \
    SelfUtility::Messages::Message(SelfUtility::MessageType::WARN, \
                         __FILE__, __LINE__, format, __VA_ARGS__); \
} while (0)

#define LOG_INFO(format, ...) do { \
    SelfUtility::Messages::Message(SelfUtility::MessageType::INFO, \
                         __FILE__, __LINE__, format, __VA_ARGS__); \
} while (0)

#define LOG_PRINT(format, ...) do { \
    SelfUtility::Messages::Message(SelfUtility::MessageType::NONE, \
                         __FILE__, __LINE__, format, __VA_ARGS__); \
} while (0)

#define LOG_INIT() do { \
    SelfUtility::Messages::Init(); \
} while (0)


#endif  // _SELF_UTILITY_MESSAGES_H_

(2) messages.cpp

复制代码
/**
*****************************************************************************
*  Copyright (C), 2023-2024
*
*  @file    messages.cpp
*  @brief   printf pretty
*
*
*  @author  sbinhuang
*  @date    2023-06-28
*  @version v1.0.0 20230628
*----------------------------------------------------------------------------
*  @note 历史版本   修改人员    修改日期      修改内容
*  @note v1.0    sbinhuang   2023-06-28   1.创建
*
*****************************************************************************
*/
#include "messages.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <iostream>
#include <fstream>
#include <string>

using SelfUtility::MessageType;
using SelfUtility::Messages;

// static variable define for class Messages
std::ofstream Messages::_os;
bool Messages::_write_file;
bool Messages::_terminal_output;

// initial log print, default output terminal
bool Messages::Init() {
    if (_os.is_open()) _os.close();
    _terminal_output = true;
    _write_file = false;
    return true;
}

// Open log file
// mode = true, open or create file and clear file content
// mode = false, open or create file, doesn't clear file content
bool Messages::OpenLogFile(const char *file_name, bool mode) {
    if (!file_name) {
        std::cout << "Log file name is null pointer!" << std::endl;
        return false;
    }

    // open file
    if (true == mode) {
        _os.open(file_name, std::ios::out);
    } else {
        _os.open(file_name, std::ios::app);
    }

    if (!_os.is_open()) {
        std::cout << "File open failed!" << "(" << file_name
                  << ")" << std::endl;
        return false;
    }

    _write_file = true;
    return true;
}

// close log file
bool Messages::CloseLogFile() {
    if (_os.is_open()) _os.close();
    _write_file = false;
    return true;
}

// enable terminal output
bool Messages::EnableTerminalOutput() {
    _terminal_output = true;
    return true;
}

// disable terminal output
bool Messages::DisableTerminalOutput() {
    _terminal_output = false;
    return true;
}

// print message for variable argument
bool Messages::Message(const MessageType &type, const char *file_name,
    int line_number, const char *format, ...) {
    // print title
    if (MessageType::ERROR == type) {
        if (true == _terminal_output) {
            if (file_name) {
                std::cout << "[" << file_name << ": "
                    << line_number << "]";
            }
            std::cout << "ERROR: ";
        }

        if (true == _write_file) {
            if (file_name) {
                _os << "[" << file_name << ": "
                    << line_number << "]";
            }
            _os << "ERROR: ";
        }
    } else if (MessageType::WARN == type) {
        if (true == _terminal_output) {
            if (file_name) {
                std::cout << "[" << file_name << ": "
                    << line_number << "]";
            }
            std::cout << "WARN: ";
        }

        if (true == _write_file) {
            if (file_name) {
                _os << "[" << file_name << ": "
                    << line_number << "]";
            }
            _os << "WARN: ";
        }
    } else if (MessageType::INFO == type) {
        if (true == _terminal_output) std::cout << "INFO: ";
        if (true == _write_file) std::cout << "INFO: ";
    }

    // print message
    char *buf = NULL;
    va_list arg_ptr;
    va_start(arg_ptr, format);
    vasprintf(&buf, format, arg_ptr);
    va_end(arg_ptr);

    if (true == _terminal_output) {
        std::cout << buf;
    }

    if (true == _write_file) {
        _os << buf;
    }

    free(buf);
    buf = NULL;
    return true;
}

// print message for determine argument
bool Messages::Message(const MessageType &type, const char *file_name,
    int line_number, const char *format) {
    // print title
    if (MessageType::ERROR == type) {
        if (true == _terminal_output) {
            if (file_name) {
                std::cout << "[" << file_name << ": "
                    << line_number << "]";
            }
            std::cout << "ERROR: ";
        }

        if (true == _write_file) {
            if (file_name) {
                _os << "[" << file_name << ": "
                    << line_number << "]";
            }
            _os << "ERROR: ";
        }
    } else if (MessageType::WARN == type) {
        if (true == _terminal_output) {
            if (file_name) {
                std::cout << "[" << file_name << ": "
                    << line_number << "]";
            }
            std::cout << "WARN: ";
        }

        if (true == _write_file) {
            if (file_name) {
                _os << "[" << file_name << ": "
                    << line_number << "]";
            }
            _os << "WARN: ";
        }
    } else if (MessageType::INFO == type) {
        if (true == _terminal_output) std::cout << "INFO: ";
        if (true == _write_file) std::cout << "INFO: ";
    }

    // print message
    if (true == _terminal_output) std::cout << format;
    if (true == _write_file) _os << format;
    return true;
}
相关推荐
@小博的博客21 小时前
【Linux探索学习】第二篇Linux的基本指令(2)——开启Linux学习第二篇
linux·运维·学习
openHiTLS密码开源社区1 天前
【密码学实战】openHiTLS passwd命令行:专业密码哈希生成工具
linux·密码学·哈希算法·ldap·密码策略·随机盐值
WTCLLB1 天前
netgear r6220 路由器,刷openwrt后,系统备份还原
linux·网络·智能路由器·openwrt
迎風吹頭髮1 天前
UNIX下C语言编程与实践38-UNIX 信号操作:signal 函数与信号捕获函数的编写
linux·c语言·unix
做运维的阿瑞1 天前
Linux系统性能监控与故障定位实战:CPU/内存/I/O/网络
linux·运维·网络
驱动探索者1 天前
车库到双子星:惠普的百年科技传奇
linux
啊?啊?1 天前
1 玩转Linux命令行:基础文件操作实战教程
linux·服务器·基础指令
Code Warrior1 天前
【Linux】线程概念与控制(2)
linux
Java 码农1 天前
CentOS 7 上安装 PostgreSQL
linux·postgresql·centos
筑梦之路1 天前
CentOS 7 升级perl版本到5.40.3 —— 筑梦之路
linux·运维·centos