【封装一个日志库(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;
}
相关推荐
极客先躯3 分钟前
如何自动提取Git指定时间段的修改文件?Win/Linux双平台解决方案
linux·git·elasticsearch
suijishengchengde41 分钟前
****LINUX时间同步配置*****
linux·运维
qiuqyue1 小时前
基于虹软Linux Pro SDK的多路RTSP流并发接入、解码与帧级处理实践
linux·运维·网络
切糕师学AI1 小时前
Linux 操作系统简介
linux
南烟斋..2 小时前
GDB调试核心指南
linux·服务器
爱跑马的程序员2 小时前
Linux 如何查看文件夹的大小(du、df、ls、find)
linux·运维·ubuntu
oMcLin4 小时前
如何在 Ubuntu 22.04 LTS 上部署并优化 Magento 电商平台,提升高并发请求的响应速度与稳定性?
linux·运维·ubuntu
Qinti_mm4 小时前
Linux io_uring:高性能异步I/O革命
linux·i/o·io_uring
优雅的38度5 小时前
linux环境下,使用docker安装apache kafka (docker-compose)
linux·架构
想唱rap5 小时前
表的约束条件
linux·数据库·mysql·ubuntu·bash