【封装一个日志库(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;
}

相关推荐

  1. 封装一个日志linux)】【转载

    2024-01-18 16:02:03       52 阅读
  2. 如何二次封装一个Vue3组件

    2024-01-18 16:02:03       51 阅读
  3. .NET封装一个简单的单例模式异步的日志

    2024-01-18 16:02:03       45 阅读
  4. 如何在程序中写一个日志程序,linux,c++

    2024-01-18 16:02:03       48 阅读
  5. linux下tcp/udp协议网络通信接口封装+日志打印对象

    2024-01-18 16:02:03       37 阅读
  6. 使用 hiredis 客户端封装一个简单的 Redis 类

    2024-01-18 16:02:03       35 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-18 16:02:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-18 16:02:03       101 阅读
  3. 在Django里面运行非项目文件

    2024-01-18 16:02:03       82 阅读
  4. Python语言-面向对象

    2024-01-18 16:02:03       91 阅读

热门阅读

  1. 4bit/8bit 启动 Mixtral 8*7B 大语言模型

    2024-01-18 16:02:03       61 阅读
  2. Pytorch

    Pytorch

    2024-01-18 16:02:03      51 阅读
  3. docker部署wiki.js

    2024-01-18 16:02:03       59 阅读
  4. tcpdump 用法

    2024-01-18 16:02:03       51 阅读
  5. C和指针课后答案

    2024-01-18 16:02:03       56 阅读