工具库1:封装一个日志库(linux)

一、,需求

(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)工具库编译参考文档
工具库编译参考

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值