自己网页制作的目标和受众,一个新的网站怎么做SEO优化,WordPress前端发布文章,wordpress 首页无法访问一#xff0c;模块主要成员 该模块的主要作用是对日志消息进行格式化#xff0c;将日志消息组织成制定格式的字符串。 该模块主要成员有两个#xff1a;1.格式化字符串。 2.格式化子项数组 1.1 格式化字符串 格式化字符串的主要功能是保存日志输出的格式字符串。其格式化字…一模块主要成员 该模块的主要作用是对日志消息进行格式化将日志消息组织成制定格式的字符串。 该模块主要成员有两个1.格式化字符串。 2.格式化子项数组 1.1 格式化字符串 格式化字符串的主要功能是保存日志输出的格式字符串。其格式化字符主要有下面几种 格式化字符串定义了日志的输出格式而格式化字符更有助于用户自由的控制日志的输出格式 。这里要注意的是由于我们信息中的日期为时间戳因此在设置其格式化字符时还应设置对应的子格式化字符如[%d{%H:%M:%S}]指的是按照年月日输出时间 1.2 格式化子项数组 格式化子项数组:用于按顺序保存格式化字符串对应的子格式化对象(FormatItem类)。 那么什么是子格式化类(FormatItem类)?子格式化类主要负责日志消息子项的获取以及格式化其下包含诸多子类通过继承关系实现多态即使是不同的子类也能依靠多态由相同的父类指针指向从而保存到同一个vector中Formatltem主要有以下子类: 格式化字符以及格式化子项的关系如下这里我们以日期为例子 1.3 举例说明 例子:[%d{%H:%M:%S}] %m%n pattern [%d{%H:%M:%S}] %m%n
items {{OtherFormatItem(), [},{TimeFormatItem(), %H:%M:%S},{OtherFormatItem(), ]},{MsgFormatItem (), },{NLineFormatItem (), }
}
message msg {size_t _line 22;size_t _ctime 12345678;std::thread::id _tid 0x12345678;std::string _logger logger;std::string _file main.cpp;std::string _payload 创建套接字失败;LogLevel::level _level ERROR;
};格式化的过程其实就是按次序从Msg中取出需要的数据进⾏字符串的连接的过程。 最终组织出来的格式化消息 [22:32:54] 创建套接字失败\n 二代码实现
2.1 代码 核心代码bool AnalyPattern()的分析如下 #ifndef _M_FORMAT_H_
#define _M_FORMAT_H_#include level.hpp
#include message.hpp
#include util.hpp
#include vector
#include memory
#include sstreamnamespace mjwlog
{// 格式化子项基类class Formatlem{public:using ptrstd::shared_ptrFormatlem;virtual void format(std::ostream os, const message msg) 0;};// 格式化子项子类// 日期类子类class TimeFormatlem : public Formatlem{public:TimeFormatlem(std::string format%H:%M:%S):_fromat(format){}void format(std::ostream os, const message msg) override{struct tm time;localtime_r((time_t*)msg._time,time);char str[32];strftime(str,sizeof(str)-1,_fromat.c_str(),time);osstr;}private:std::string _fromat;//用来控制输出格式};//缩进子类class TabFormatlem : public Formatlem{public:void format(std::ostream os, const message msg) override{os\t;}};//线程id子类class ThreadFormatlem : public Formatlem{public:void format(std::ostream os, const message msg) override{osmsg._id;}};//日志级别子类class LevelFormatlem : public Formatlem{public:void format(std::ostream os, const message msg) override{osLogLevel::LeveltoString(msg._level);}};//日志器名称子类class NameFormatlem : public Formatlem{public:void format(std::ostream os, const message msg) override{osmsg._logger;}};//文件名子类class CFileFormatlem : public Formatlem{public:void format(std::ostream os, const message msg) override{osmsg._filename;}};//行号子类class CLineFormatlem : public Formatlem{public:void format(std::ostream os, const message msg) override{osmsg._line;}};//日志消息主体子类class MsgFormatlem : public Formatlem{public:void format(std::ostream os, const message msg) override{osmsg._msg;}};//换行子类class NLineFormatlem : public Formatlem{public:void format(std::ostream os, const message msg) override{os\n;}};//其他字符子类直接原路返回class OtherFormatlem : public Formatlem{public:OtherFormatlem(std::string str):_str(str){}void format(std::ostream os, const message msg) override{os_str;}private:std::string _str;};//格式化类class Formatter{/*%d 日期%T 缩进%t 线程id%p 日志级别%c 日志器名称%f 文件名%l 行号%m 日志消息%n 换行*/public://默认格式:时间{年-月-日 时:分:秒}缩进 线程ID 缩进 [日志级别] 缩进 [日志器名称] 缩进 文件名:行号 缩进 消息换行Formatter(std::string pattern[%d{%H:%M:%S}]%T[%t]%T[%p]%T[%c]%T[%f:%l]%T%n):_pattern(pattern){}//对msg进行格式化nvoid format(std::ostream os,const message msg)//将格式化后的内容写入os执行流{if(AnalyPattern()){for(auto it:_items){it-format(os,msg);}}}std::string format(const message msg)//将格式化后的内容以string方式返回{std::stringstream str;if(AnalyPattern()){for(auto it:_items){it-format(str,msg);}}return str.str();}//对格式化字符串进行分析bool AnalyPattern(){//遍历_parttern进行逐一分析int cur0;std::string key,val;//abc[%%d{%H:%M:%S}]while(cur_pattern.size()){//先排查非格式化字符如abcif(_pattern[cur]!%){val_pattern[cur];//特殊情况:aaaa[%%d{%H:%M:%S}]if(cur_pattern.size()){_items.push_back(createItem(key,val));}continue;}//到这一步说明碰到%,这是需要排除%[ %%等情况//%[//if(_pattern[cur]%_pattern[cur1]%)if(_pattern[cur]%(!isalpha(_pattern[cur1]))){val_pattern[cur];//特殊情况:aaaa[%%d{%H:%M:%S}%/* if(cur_pattern.size()){_items.push_back(createItem(key,val));} */continue;}//此时key为空val中全是非格式化字符字符//不过也有可能val中没有任何字符if(!val.empty()) _items.push_back(createItem(key,val));key.clear();val.clear();//cur1_pattern.size()if(cur1_pattern.size()){std::cout格式化字符关键字%后数据错误std::endl;return false;}//到这一步说明目前cur指向%,且cur1指向的为一个字母字符curcur1;key_pattern[cur];//abc[%%d{%H:%M:%S}],此时cur指向d后面的{//因此这时候我们需要判断后面是否是子格式化字符if(cur_pattern.size()_pattern[cur]{){cur;while(cur_pattern.size()_pattern[cur]!}){val_pattern[cur];}//出while循环有下面两种可能//1.cur_pattern.size(),说明没有找到},说明这是非法子格式化字符if(cur_pattern.size()){std::cout非法子格式化字符....std::endl;abort();}//2._pattern[cur]}_items.push_back(createItem(key,val));key.clear();val.clear();//此时cur指向}因此进入下一个循环前cur应该cur;}else{_items.push_back(createItem(key,val));key.clear();val.clear();}}return true;}private://根据不同的格式创建不同的格式化子类对象//key用来存储格式化字符val用来存储格式化字符子字符如[%d{%H:%M:%S}]std::shared_ptrFormatlem createItem(const std::string key,const std::string val){if(keyd) return Formatlem::ptr(new TimeFormatlem(val));if(keyT) return Formatlem::ptr(new TabFormatlem());if(keyp) return Formatlem::ptr(new LevelFormatlem());if(keyt) return Formatlem::ptr(new ThreadFormatlem());if(keyc) return Formatlem::ptr(new NameFormatlem());if(keyf) return Formatlem::ptr(new CFileFormatlem());if(keyl) return Formatlem::ptr(new CLineFormatlem());if(keyn) return Formatlem::ptr(new NLineFormatlem());//当key为空时则说明val里存储的是非格式化化字符如abcdif(key.empty()) return Formatlem::ptr(new OtherFormatlem(val));//还有一种情况就是key中存储的不是设定的格式字符如%gstd::cout没有该格式化字符%keystd::endl;abort();return nullptr;}private:std::string _pattern;std::vectorFormatlem::ptr _items;};
}#endif
3.1 测试