日志对于软件开发者几乎是绕不开的墙,一个强大的程序需要开发者能够随时监控到每个细节,而对于记录程序的运行状态、操作记录等等更是必不可少的,当然,有很多高大上的开源日志系统可供选择,在开源中国上能搜一大堆...
对于后台程序,我就需要一个简单、实用、稳定日志,不需要各种花里胡哨的功能,控制台输出也无妨,但最好能落地便于查找。基于此类需求,就自己开发了一个日志组件,能够融合到各类后台系统中,包含了常规的功能,能满足最低需求啦。
功能主要包括:可同步/异步记录日志、落地/控制台(可高亮)输出、简单格式化、读取/写入一组日志到指定文件中,具体的看贴上的代码,是否对于开发者是否有帮助,请批评指正咯..
ILog.h
#ifndef _UTIL_LOG_H_ #define _UTIL_LOG_H_ #include <vector> #include <string> #define UTIL_LOG_API //日志信息默认包裹符( "[]", "()", ... ) #define DEFAULT_TEXT_LEFT_WRAP "[" #define DEFAULT_TEXT_RIGHT_WRAP "]" //日志信息默认分割符( "\t", "-", " " ) #define DEFAULT_TEXT_SEPARATE " " ///日志信息级别定义 enum EU_LOG_SEVERITY { ///调试信息输出(非DEBUG模式无效) EU_LOG_DEBUG=0, ///正常信息输出 EU_LOG_MSG=1, ///警告信息输出 EU_LOG_WARN=2, ///错误信息输出 EU_LOG_ERR=3, ///无标记信息输出 EU_LOG_CLEAR=4 }; ///日志输出高亮颜色定义 enum EU_TEXT_COLOR { EU_TEXT_BLACK=0, EU_TEXT_RED=1, EU_TEXT_GREEN=2, EU_TEXT_BROWN=3, EU_TEXT_BLUE=4, EU_TEXT_MAGENTA=5, EU_TEXT_CYAN=6, EU_TEXT_WHITE=7, EU_TEXT_YELLOW=8, EU_TEXT_LRED=9, EU_TEXT_LGREEN=10, EU_TEXT_LBLUE=11, EU_TEXT_LMAGENTA=12, EU_TEXT_LCYAN=13, EU_TEXT_LWHITE=14 }; ///日志回调函数定义 ///@param severity信息级别 ///@param msg日志信息 ///@param len日志信息长度 typedef void (* util_log_cb)(int severity, const char *msg, size_t len); ///类ILog ///@remark 日志组件接口定义 class ILog { public: ///初始化日志组件 ///@param async是否异步 ///@param print是否输出显示 ///@param save是否保存至文件 ///@param defaultPath日志默认文件路径, 格式"\\xxx\\xxx" ///@param cb记录日志后回调函数指针 ///@return 成功返回0, 失败返回负值 virtual int init(bool async=true, bool print=true, bool save=true, const char *defaultPath=".\\log", util_log_cb cb=0) = 0; ///设置日志打包符号 ///@param left_wrap左包裹符 ///@param right_wrap右包裹符 ///@param separate分割符 virtual void set_text_packsign(const char *left_wrap="", const char *right_wrap="", const char *separate="\t") = 0; ///设置日志输出高亮配置 ///@param config_path配置路径 virtual void set_text_highlight(const char *config_path) = 0; ///运行日志组件 virtual void run() = 0; ///停止日志组件 virtual void stop() = 0; ///记录日志, 包括屏幕显示和储存至默认路径下文件 ///@param severity信息级别 ///@param fmt参数传入格式 virtual void log(EU_LOG_SEVERITY severity, const char *fmt, ...) = 0; ///记录日志, 储存至指定路径下文件, 文件格式"\\xxx\\xxx" ///@param filePath指定路径下文件 ///@param severity信息级别 ///@param fmt参数传入格式 virtual void log2file(const char *filePath, EU_LOG_SEVERITY severity, const char *fmt, ...) = 0; ///读取指定路径下日志文件所有内容 ///@param fileName文件名称 ///@param result文件所有日志信息 virtual void read_file_text(const char *fileName, std::vector<std::string> &result) = 0; ///写入内容到指定路径下日志文件 ///@param fileName文件名称 ///@param result日志内容 virtual void write_file_text(const char *fileName, std::vector<std::string> &result) = 0; protected: virtual ~ILog(){} }; ///创建日志组件 UTIL_LOG_API ILog *CreateLoger(); ///销毁日志组件 UTIL_LOG_API void DestroyLoger(ILog *&p); #endif//_UTIL_LOG_H_
Log.h
#ifndef _UTIL_LOG_IMPL_H_ #define _UTIL_LOG_IMPL_H_ #include "ILog.h" #include <boost/thread.hpp> #include <boost/thread/mutex.hpp> #include <boost/thread/condition.hpp> #include <boost/make_shared.hpp> #include <list> ///日志信息最大长度定义, 10k const int log_text_max_len = 1024 * 10; ///日志信息结构定义 struct log_message { public: log_message(EU_LOG_SEVERITY s, const std::string &p, const std::string &t) : m_severity(s), m_path(p), m_text(t){} EU_LOG_SEVERITY m_severity; std::string m_path; std::string m_text; }; typedef boost::shared_ptr<log_message> MessagePtr; class util_log_impl : public ILog { public: util_log_impl(); virtual ~util_log_impl(); virtual int init(bool async, bool print, bool save, const char *defaultPath, util_log_cb cb); virtual void set_text_packsign(const char *left_wrap, const char *right_wrap, const char *separate); virtual void set_text_highlight(const char *config_path); virtual void run(); virtual void stop(); virtual void log(EU_LOG_SEVERITY severity, const char *fmt, ...); virtual void log2file(const char *filePath, EU_LOG_SEVERITY severity, const char *fmt, ...); virtual void read_file_text(const char *fileName, std::vector<std::string> &result); virtual void write_file_text(const char *fileName, std::vector<std::string> &result); private: ///设置日志输出高亮 void set_text_highlight(std::string text, EU_TEXT_COLOR color); ///打包日志信息 void pack_log_text(const char *filePath, EU_LOG_SEVERITY severity, const char *fmt, va_list ap); ///处理日志信息 void handle_log_msg(const log_message &msg); ///打印日志信息 void print_log_text(const std::string &logText); ///保存日志信息 void save_log_text(const std::string &filePath, const std::string &logText); ///获取日志文件名称包括路径 std::string get_log_file_name(const std::string &filePath); ///获取日志文件路径 std::string get_log_file_path(const std::string &fileName); ///更新默认日志文件 void update_default_file(); ///异步处理日志 void async_process_log(); ///克隆日志队列当前所有信息 void clone_log_list(std::list<MessagePtr> &messages); ///检查/创建路径 bool check_file_path(const std::string &filePath); void create_file_path(const std::string &filePath); private: //日志状态控制 bool m_run_state; bool m_async_state; bool m_print_state; bool m_save_state; std::string m_default_path; util_log_cb m_log_cb; //日志打包符号 std::string m_left_wrap; std::string m_right_wrap; std::string m_separate; //日志输出高亮 bool m_custom_highlight; std::map<std::string, EU_TEXT_COLOR> m_text_highlight_grp; //当前日志保存文件句柄 FILE *m_current_file; std::string m_current_date; //日志信息队列 boost::mutex m_mt_msg; boost::condition m_con_msg; std::list<MessagePtr> m_message_list; boost::shared_ptr<boost::thread> m_th_process_log; }; #endif//_UTIL_LOG_IMPL_H_