C++日志调试打印接口

来源:互联网 发布:官方双色球选号软件 编辑:程序博客网 时间:2024/06/10 21:25

1、debug_log.h头文件

/******************************************************************************            版权所有 (C), 2016-2017, 西安网络科技有限公司 ******************************************************************************    文 件 名 : debug_log.h    版 本 号 : V1.0    作    者 : zhangcan    生成日期 : 2017年2月28日    功能描述 : 日志类头文件    修改历史 :******************************************************************************/#ifdef __cplusplus#include <string>#endif#ifndef _DEBUG_LOG_H_#define _DEBUG_LOG_H_#ifdef __cplusplusnamespace debug_log {class DebugLog {public:DebugLog() :m_debugLevel(-1),m_fileName("") { }virtual ~DebugLog();virtual void write(int level, const std::string &msg);bool isLogFileSet();bool isLogLevelSet();void setDebugLogLevel(int level);void setDebugLogFile(std::string fileName, std::string *error);const std::string& getDebugLogFile();int getDebugLogLevel();private:/* 日志级别 */int m_debugLevel;/* 日志文件 */std::string m_fileName;};}  // namespace debug_log#endif  // __cplusplus#endif  // _DEBUG_LOG_H_


2、debug_log.cpp接口实现

/******************************************************************************            版权所有 (C), 2016-2017, 西安网络科技有限公司 ******************************************************************************    文 件 名 : debug_log.cpp    版 本 号 : V1.0    作    者 : zhangcan    生成日期 : 2017年2月28日    功能描述 : 日志类接口实现    修改历史 :******************************************************************************/#include <stddef.h>#include <fstream>#include "debug_log.h"#include "debug_log_writer.h"namespace debug_log {/*****************************************************************************    函 数 名 : debug_log.DebugLog.~DebugLog    功能描述 : 析构函数    输入参数 : 无    输出参数 : 无    返 回 值 : 无    作    者 : zhangcan    日    期 : 2017年2月28日*****************************************************************************/DebugLog::~DebugLog() {DebugLogWriter::getInstance().close(this->m_fileName);}/*****************************************************************************    函 数 名 : debug_log.DebugLog.setDebugLogFile    功能描述 : 设置日志文件    输入参数 : std::string fileName                 std::string *error         输出参数 : 无    返 回 值 : 无    作    者 : zhangcan    日    期 : 2017年2月28日*****************************************************************************/void DebugLog::setDebugLogFile(std::string fileName, std::string *error) {if (this->isLogFileSet()) {DebugLogWriter::getInstance().close(this->m_fileName);}this->m_fileName = fileName;DebugLogWriter::getInstance().open(this->m_fileName, error);}/*****************************************************************************    函 数 名 : debug_log.DebugLog.setDebugLogLevel    功能描述 : 设置日志级别    输入参数 : int level      输出参数 : 无    返 回 值 : 无    作    者 : zhangcan    日    期 : 2017年2月28日*****************************************************************************/void DebugLog::setDebugLogLevel(int level) {this->m_debugLevel = level;}/*****************************************************************************    函 数 名 : debug_log.DebugLog.isLogFileSet    功能描述 : 是否设置日志文件    输入参数 : 无    输出参数 : 无    返 回 值 : bool    作    者 : zhangcan    日    期 : 2017年2月28日*****************************************************************************/bool DebugLog::isLogFileSet() {return (this->m_fileName.empty() == false);}/*****************************************************************************    函 数 名 : debug_log.DebugLog.isLogLevelSet    功能描述 : 是否设置日志级别    输入参数 : 无    输出参数 : 无    返 回 值 : bool    作    者 : zhangcan    日    期 : 2017年2月28日*****************************************************************************/bool DebugLog::isLogLevelSet() {return (this->m_debugLevel != -1);}/*****************************************************************************    函 数 名 : debug_log.DebugLog.getDebugLogFile    功能描述 : 获取日志文件    输入参数 : 无    输出参数 : 无    返 回 值 : const std::string&    作    者 : zhangcan    日    期 : 2017年2月28日*****************************************************************************/const std::string& DebugLog::getDebugLogFile() {return this->m_fileName;}/*****************************************************************************    函 数 名 : debug_log.DebugLog.getDebugLogLevel    功能描述 : 获取日志级别    输入参数 : 无    输出参数 : 无    返 回 值 : int    作    者 : zhangcan    日    期 : 2017年2月28日*****************************************************************************/int DebugLog::getDebugLogLevel() {return (this->m_debugLevel < 0) ? 0 : this->m_debugLevel;}/*****************************************************************************    函 数 名 : debug_log.DebugLog.write    功能描述 : 写日志    输入参数 : int level                         const std::string &msg      输出参数 : 无    返 回 值 : 无    作    者 : zhangcan    日    期 : 2017年2月28日*****************************************************************************/void DebugLog::write(int level, const std::string &msg) {if (level <= this->m_debugLevel) {std::string msgf = "[" + std::to_string(level) + "]" + msg;DebugLogWriter &d = DebugLogWriter::getInstance();d.write_log(this->m_fileName, msgf);}}}  // namespace debug_log

3、debug_log_writer.h头文件

/******************************************************************************            版权所有 (C), 2016-2017, 西安网络科技有限公司 ******************************************************************************    文 件 名 : debug_log_writer.h    版 本 号 : V1.0    作    者 : zhangcan    生成日期 : 2017年2月28日    功能描述 : 写日志类头文件    修改历史 :******************************************************************************/#include <stdio.h>#include <sys/ipc.h>#include <sys/shm.h>#include <sys/types.h>#include <map>#include <string>#include <cstring>#include <iostream>#ifndef _DEBUG_LOG_WRITER_H_#define _DEBUG_LOG_WRITER_H_namespace debug_log {class DebugLogWriter {public:static DebugLogWriter &getInstance() {static DebugLogWriter instance;return instance;}void write_log(const std::string &fileName, const std::string &msg);void close(const std::string &fileName);int open(const std::string &fileName, std::string *error);private:DebugLogWriter() { }~DebugLogWriter() { }    // C++ 03    // ========    // Dont forget to declare these two. You want to make sure they    // are unacceptable otherwise you may accidentally get copies of    // your singleton appearing.DebugLogWriter(DebugLogWriter const&);void operator=(DebugLogWriter const&);};}  // namespace debug_log#endif  // _DEBUG_LOG_WRITER_H_

4、debug_log_writer.cpp接口实现

/******************************************************************************            版权所有 (C), 2016-2017, 西安网络科技有限公司 ******************************************************************************    文 件 名 : debug_log_writer.cpp    版 本 号 : V1.0    作    者 : zhangcan    生成日期 : 2017年2月28日    功能描述 : 写日志文件类接口实现    修改历史 :******************************************************************************/#include <errno.h>#include <fcntl.h>#include <pthread.h>#include <stdio.h>#include <sys/ipc.h>#include <sys/shm.h>#include <sys/stat.h>#include <sys/types.h>#include <unistd.h>#include <fstream>#include "shared_files.h"#include "debug_log_writer.h"namespace debug_log {/*****************************************************************************    函 数 名 : debug_log.DebugLogWriter.open    功能描述 : 打开文件    输入参数 : const std::string &fileName                 std::string *error               输出参数 : 无    返 回 值 : int    作    者 : zhangcan    日    期 : 2017年2月28日*****************************************************************************/int DebugLogWriter::open(const std::string &fileName, std::string *error) {return utils::SharedFiles::getInstance().open(fileName, error);}/*****************************************************************************    函 数 名 : debug_log.DebugLogWriter.close    功能描述 : 关闭文件句柄    输入参数 : const std::string &fileName      输出参数 : 无    返 回 值 : 无    作    者 : zhangcan    日    期 : 2017年2月28日*****************************************************************************/void DebugLogWriter::close(const std::string &fileName) {utils::SharedFiles::getInstance().close(fileName);}/*****************************************************************************    函 数 名 : debug_log.DebugLogWriter.write_log    功能描述 : 写日志文件    输入参数 : const std::string &fileName                 const std::string &msg       输出参数 : 无    返 回 值 : 无    作    者 : zhangcan    日    期 : 2017年2月28日*****************************************************************************/void DebugLogWriter::write_log(const std::string &fileName,const std::string &msg) {std::string err;std::string lmsg = msg + "\n";utils::SharedFiles::getInstance().write(fileName, lmsg, &err);if (err.size() > 0) {printf("[%s:%d] %s\n", __FUNCTION__, __LINE__, err.c_str());}}}  // namespace debug_log

5、shared_files.h头文件

/******************************************************************************            版权所有 (C), 2016-2017, 西安网络科技有限公司 ******************************************************************************    文 件 名 : shared_files.h    版 本 号 : V1.0    作    者 : zhangcan    生成日期 : 2017年5月8日    功能描述 : 共享文件操作类头文件    修改历史 :******************************************************************************/#ifndef _UTILS_SHARED_FILES_H_#define _UTILS_SHARED_FILES_H_#include <errno.h>#include <fcntl.h>#include <pthread.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/ipc.h>#include <sys/shm.h>#include <sys/stat.h>#include <sys/types.h>#include <unistd.h>#include <utility>#include <vector>#include <fstream>#include <string>namespace utils {typedef struct file_handler {    int shm_id_structure;    pthread_mutex_t lock;    char file_name[];} file_handler_t;class SharedFiles {public:bool open(const std::string &fileName, std::string *error);void close(const std::string &fileName);bool write(const std::string &fileName, const std::string &msg,        std::string *error);    static SharedFiles& getInstance() {    static SharedFiles instance;    return instance;    }protected:std::pair<file_handler_t *, FILE *> find_handler(const std::string &fileName);std::pair<file_handler_t *, FILE *> add_new_handler(const std::string &fileName, std::string *error);private: SharedFiles() {}~SharedFiles() {}    // C++ 03    // ========    // Dont forget to declare these two. You want to make sure they    // are unacceptable otherwise you may accidentally get copies of    // your singleton appearing.    SharedFiles(SharedFiles const&);    void operator=(SharedFiles const&);std::vector<std::pair<std::string,std::pair<file_handler_t *, FILE *> > > m_handlers;};}  // namespace utils#endif  // _UTILS_SHARED_FILES_H_

6、shared_files.cpp接口实现

/******************************************************************************            版权所有 (C), 2016-2017, 西安网络科技有限公司 ******************************************************************************    文 件 名 : shared_files.cpp    版 本 号 : V1.0    作    者 : zhangcan    生成日期 : 2017年5月8日    功能描述 : 共享文件操作接口实现    修改历史 :******************************************************************************/#include <errno.h>#include <fcntl.h>#include <pthread.h>#include <stdio.h>#include <sys/ipc.h>#include <sys/shm.h>#include <sys/stat.h>#include <sys/types.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <utility>#include <fstream>#include <string>#include "shared_files.h"namespace utils {/*****************************************************************************    函 数 名 : utils.SharedFiles.find_handler    功能描述 : 查找文件句柄    输入参数 : const std::string &fileName      输出参数 : 无    返 回 值 : std::pair<file_handler_t *, FILE *>    作    者 : zhangcan    日    期 : 2017年5月8日*****************************************************************************/std::pair<file_handler_t *, FILE *> SharedFiles::find_handler(const std::string &fileName) {for (auto i : this->m_handlers) {if (i.first == fileName) {return i.second;}}return std::pair<file_handler_t *, FILE *>(NULL, NULL);}/*****************************************************************************    函 数 名 : utils.SharedFiles.add_new_handler    功能描述 : 添加文件句柄    输入参数 : const std::string &fileName                 std::string *error               输出参数 : 无    返 回 值 : std::pair<file_handler_t *, FILE *>    作    者 : zhangcan    日    期 : 2017年5月8日*****************************************************************************/std::pair<file_handler_t *, FILE *> SharedFiles::add_new_handler(const std::string &fileName, std::string *error) {int ret;FILE *fp;int shm_id;bool toBeCreated = true;key_t mem_key_structure;file_handler_t *new_debug_log;struct shmid_ds shared_mem_info;/* 打开文件 */fp = fopen(fileName.c_str(), "a");if (fp == NULL) {error->assign("Failed to open file: " + fileName);goto err_fh;}/* 创建IPC通讯ID */mem_key_structure = ftok(fileName.c_str(), 1);if (mem_key_structure < 0) {error->assign("Failed to select key for the shared memory (1): ");        error->append(strerror(errno));        goto err_mem_key;}/* 创建共享内存对象 */shm_id = shmget(mem_key_structure, sizeof(file_handler_t) + fileName.size() + 1, \IPC_CREAT | IPC_EXCL | 0666);if (shm_id < 0) {toBeCreated = false;shm_id = shmget(mem_key_structure, sizeof(file_handler_t) + fileName.size() + 1, \IPC_CREAT | 0666);if (shm_id < 0) {error->assign("Failed to allocate shared memory (1): ");            error->append(strerror(errno));            goto err_shmget1;}}/* 获得共享内存的状态 */ret = shmctl(shm_id, IPC_STAT, &shared_mem_info);if (ret < 0) {error->assign("Failed to get information on shared memory (1): ");        error->append(strerror(errno));        goto err_shmctl1;}/* 把共享内存区对象映射到调用进程的地址空间 */new_debug_log = reinterpret_cast<file_handler_t *>(shmat(shm_id, NULL, 0));if ((reinterpret_cast<char *>(new_debug_log)[0]) == -1) {error->assign("Failed to attach shared memory (1): ");        error->append(strerror(errno));        goto err_shmat1;}if ((toBeCreated == false) && (shared_mem_info.shm_nattch == 0)) {toBeCreated = true;}if (toBeCreated == true) {memset(new_debug_log, '\0', sizeof(file_handler_t));pthread_mutex_init(&new_debug_log->lock, NULL);new_debug_log->shm_id_structure = shm_id;memcpy(new_debug_log->file_name, fileName.c_str(), fileName.size());new_debug_log->file_name[fileName.size()] = '\0';}this->m_handlers.push_back(std::make_pair(fileName, std::make_pair(new_debug_log, fp)));return std::make_pair(new_debug_log, fp);err_shmget1:err_shmctl1:err_shmat1:shmdt(new_debug_log);err_mem_key:fclose(fp);err_fh:return std::pair<file_handler_t *, FILE *>(NULL, NULL);}/*****************************************************************************    函 数 名 : utils.SharedFiles.open    功能描述 : 打开文件    输入参数 : const std::string &fileName                 std::string *error               输出参数 : 无    返 回 值 : bool    作    者 : zhangcan    日    期 : 2017年5月8日*****************************************************************************/bool SharedFiles::open(const std::string &fileName, std::string *error) {bool bRet = true;std::pair<file_handler_t *, FILE *> a;/* 查找文件句柄 */a = this->find_handler(fileName);if (a.first == NULL) {/* 创建文件句柄 */a = this->add_new_handler(fileName, error);}if ((a.first == NULL) && (error->size() == 0)) {error->assign("Not able to open: " + fileName);bRet = false;}return bRet;}/*****************************************************************************    函 数 名 : utils.SharedFiles.close    功能描述 : 关闭文件    输入参数 : const std::string &fileName      输出参数 : 无    返 回 值 : 无    作    者 : zhangcan    日    期 : 2017年5月8日*****************************************************************************/void SharedFiles::close(const std::string &fileName) {std::pair<file_handler_t *, FILE *> a;if (fileName.empty()) {return;}a = this->find_handler(fileName);if ((a.first == NULL) || (a.second == NULL)) {return;}/* 关闭文件 */fclose(a.second);a.second = NULL;/* 删除共享内存 */shmctl(a.first->shm_id_structure, IPC_RMID, NULL);}/*****************************************************************************    函 数 名 : utils.SharedFiles.write    功能描述 : 写数据    输入参数 : const std::string &fileName                 const std::string &msg                      std::string *error               输出参数 : 无    返 回 值 : bool    作    者 : zhangcan    日    期 : 2017年5月8日*****************************************************************************/bool SharedFiles::write(const std::string &fileName,const std::string &msg, std::string *error) {bool ret = true;size_t wrote;std::pair<file_handler_t *, FILE *> a;a = this->find_handler(fileName);if (a.first == NULL) {error->assign("file is not open: " + fileName);        return false;}pthread_mutex_lock(&a.first->lock);    wrote = fwrite(reinterpret_cast<const char *>(msg.c_str()), 1, msg.size(), a.second);    if (wrote < msg.size()) {        error->assign("failed to write: " + fileName);        ret = false;    }    fflush(a.second);    pthread_mutex_unlock(&a.first->lock);    return ret;}}  // namespace utils

7、编译以上代码生成动态库

CC     := g++ --std=c++11TARGET := libDebugLog.soINCS   := ./debug_log ./utils ../includeFLAGES := $(addprefix -I, $(INCS))SRCS   := $(wildcard ./debug_log/*.cpp)SRCS   += $(wildcard ./utils/*.cpp)$(TARGET): $(SRCS)$(CC) -shared -fPIC $(FLAGES) -o $@ $^@mv $(TARGET) ./libs/.PHONY: cleanclean:@rm -rf ./debug_log/*.o ./utils/*.o@rm -rf ./libs/$(TARGET)

8、测试代码

/******************************************************************************            版权所有 (C), 2016-2017, 西安网络科技有限公司 ******************************************************************************    文 件 名 : test_debug_log.h    版 本 号 : V1.0    作    者 : zhangcan    生成日期 : 2017年5月12日    功能描述 : 测试DebugLog类头文件    修改历史 :******************************************************************************/#ifdef __cplusplus#include <stdio.h>#include <string>#include <sstream>#include <fstream>#include <iostream>#endif#ifndef _TEST_DEBUG_LOG_H_#define _TEST_DEBUG_LOG_H_#include "debug_log.h"#ifdef __cplusplususing debug_log::DebugLog;class Test_1 {public:Test_1() :m_debugLog(new DebugLog()){}~Test_1(){if (m_debugLog != NULL) {delete m_debugLog;}}void init(int level, std::string fileName);void debug(int level, const std::string &msg);void test();private:DebugLog *m_debugLog;};#endif  // __cplusplus#endif  // _TEST_DEBUG_LOG_H_

/******************************************************************************            版权所有 (C), 2016-2017, 西安网络科技有限公司 ******************************************************************************    文 件 名 : test_debug_log.cpp    版 本 号 : V1.0    作    者 : zhangcan    生成日期 : 2017年5月11日    功能描述 : 测试DebugLog功能    修改历史 :******************************************************************************/#include "test_debug_log.h"void Test_1::init(int level, std::string fileName) {if (m_debugLog != NULL) {std::string msg;m_debugLog->setDebugLogLevel(level);m_debugLog->setDebugLogFile(fileName, &msg);if (msg.size() > 0) {std::cout << msg << std::endl;}}else {std::cout << "new DebugLog failed!" << std::endl;}}void Test_1::debug(int level, const std::string &msg) {if (m_debugLog != NULL) {m_debugLog->write(level, msg);}}void Test_1::test() {std::string msg;std::stringstream head;head << "[" << __FUNCTION__ << ":" << __LINE__ << "] ";msg = "123456789";msg = head.str() + msg;debug(1, msg);}int main() {Test_1 *pTest = new Test_1();if (pTest != NULL) {pTest->init(9, "debug.log");}else{std::cout << "new Test_1 failed!" << std::endl;return -1;}pTest->test();return 0;}

编译代码

CC     := g++ --std=c++11INCS   := ./ ../utils ../../includeLIBS   := DebugLogFLAGES := $(addprefix -I, $(INCS))FLAGES += -L../libs/ -Wl,-rpath ../libs/ $(addprefix -l, $(LIBS))out :$(CC) -o test_debug_log test_debug_log.cpp $(FLAGES).PHONY:cleanclean:@rm -rf test_debug_log

原创粉丝点击