短小的日志类

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介:
 1
  2 /*
  3    nvlog.h
  4    ----------------
  5    application logger
  6    2003.10     created        scott    
  7    2005.09.10    rebuild        scott
  8                created RegFileWriter,UdpWriter,WindowWriter to distinguish log data type
  9    2005.09.22    modified RegFileWriter::RegFileWriter()    scott
 10    2005.11.10    scott     add __FILE__,__LINE__
 11*/

 12
 13 #ifndef _NVLOG
 14 #define  _NVLOG
 15
 16 #ifdef _UNIX
 17  #include  < unistd.h >
 18  #include  < signal.h >
 19  #include  < sys / socket.h >
 20  #include  < fcntl.h >
 21  #include  < netinet / in .h >
 22  #include  < arpa / inet.h >
 23 #endif
 24
 25 #ifdef WIN32
 26  #include  < windows.h >
 27 #include  < winsock.h >
 28 #include  < io.h >
 29 #endif
 30
 31
 32 #include  < stdio.h >
 33 #include  < stdlib.h >
 34 #include  < string >
 35 #include  < string .h >
 36 #include  < stdarg.h >
 37 #include  < vector >
 38 #include  < algorithm >
 39
 40 #include  " nvlock.h "
 41 #include  " nvcalendar.h "
 42
 43 class  NVLog {
 44public:
 45    enum WriterType{
 46        UDP,    
 47        REGFILE,
 48        WINDOW,
 49        UNKNOWN
 50    }
;
 51
 52    class LogWriter{
 53    public:
 54        LogWriter(){
 55            _type = UNKNOWN;
 56        }

 57        
 58        virtual ~LogWriter(){
 59
 60        }

 61
 62        virtual int     Write(const char * data,unsigned int len){
 63            return 0;
 64        }

 65        virtual bool    Open(){
 66            return true;
 67        }

 68        virtual void    Close(){            
 69        }

 70
 71        WriterType    GetType(){
 72            return _type;
 73        }

 74    protected:
 75        WriterType    _type;
 76    }
;
 77    #ifdef WIN32
 78    class WindowWriter:public LogWriter{
 79    public:
 80
 81        virtual int     Write(const char * data,unsigned int len){
 82            if( _refind){
 83                return Write2(_win_title.c_str(),data,len);
 84            }

 85            return SendMessageToWindow(_hwnd,data,len);
 86        }

 87
 88        int     Write2(const char * wintitle,const char * data,unsigned int len){            
 89            HWND hwnd = FindWindow(0,wintitle);
 90            len = SendMessageToWindow(hwnd,data,len);
 91        //    CloseHandle(hwnd);
 92            return len;
 93        }

 94
 95        virtual bool    Open(){
 96            if( _refind){        //需要发送时发现 
 97                return true;
 98            }

 99            _hwnd = FindWindow(0,_win_title.c_str());
100            if!_hwnd){
101                //MessageBox(NULL,"cannot find window",_win_title.c_str(),MB_OK);
102                return false;
103            }

104            return true;
105        }

106        virtual void    Close(){
107            if( _hwnd ){
108                //CloseHandle(_hwnd);
109            }

110
111        }

112
113        WindowWriter(const char * wintitle,bool refind=false){
114            _win_title = wintitle;
115            _hwnd = NULL;
116            _type = WINDOW;
117            _refind = refind;
118        }

119
120    protected:
121        int SendMessageToWindow(HWND hwnd ,const char * data,unsigned int len){
122            if( hwnd == NULL){
123                return 0;
124            }

125            COPYDATASTRUCT cds;
126            cds.lpData =(void*)data;
127            cds.cbData = len;
128            SendMessage(hwnd,WM_COPYDATA ,(UINT)hwnd,(long)&cds);
129            return len;
130        }

131    private:
132        std::string        _win_title;
133        HWND            _hwnd;
134        bool            _refind;
135    }
;
136    #endif
137    
138    class RegFileWriter:public LogWriter{
139    public:
140        typedef void (*OnReachedMaxFileSizeCB)(std::string &file);
141        RegFileWriter(const char * file){
142            _cb_maxsize = NULL;
143            _fp = NULL ;
144            _file = file;
145            _type = REGFILE;
146            _cur_size = 0;
147            SetMaxFileSize();
148        }

149        virtual void OnReachedMaxFileSize(){
150            Close();
151            Open();
152        }

153        //void SetRoundTime(unsigned int round_time);    //达到指定时间循环到文件头部        
154        void SetMaxFileSize(unsigned int max_size = 1024*1024*2,OnReachedMaxFileSizeCB cb=NULL){
155            _max_size = max_size;
156            _cb_maxsize = cb;
157            
158        }

159        virtual bool    Open(){
160            _fp = fopen(_file.c_str(),"w");
161            if!_fp){
162                return false;
163            }

164            //fseek(fp,0,SEEK_END);
165            _cur_size = 0;//ftell(fp);
166            return true;
167        }

168
169        virtual int     Write(const char * data,unsigned int len){
170            int ret;
171            if( _cur_size >= _max_size){
172                OnReachedMaxFileSize();
173            }

174            if( _fp == NULL){
175                return -1;
176            }

177            ret = fwrite(data,len,1,_fp);
178            fflush(_fp);
179            _cur_size += len;
180            return len;
181        }

182
183        void    Close(){
184            if( _fp ){
185                fclose(_fp);
186            }

187            _fp = NULL;            
188        }

189        
190    private:
191        unsigned int _cur_size,_max_size;
192        OnReachedMaxFileSizeCB    _cb_maxsize;
193        
194        FILE *         _fp;
195        std::string _file;
196    }
;
197    class Socket{
198    public:
199        Socket(){
200            _sock = -1;
201        }

202        
203
204    protected:
205        std::string        _host;
206        unsigned short    _port;
207        int    _sock;
208    }
;
209    class UdpWriter:public Socket,public LogWriter{
210    public:
211
212        ~UdpWriter(){
213            Close();
214        }

215
216        UdpWriter(const char * dest,unsigned short port){
217            _host =  dest;
218            _port =  port;
219            _type =  UDP;
220        }

221        
222        virtual int     Write(const char * data,unsigned int len){
223            if( _sock < 0 ){
224                return 0;
225            }

226            return send(_sock,data,len,0);
227        }

228
229        virtual bool    Open(){
230            sockaddr_in sa;    
231            #ifdef WIN32
232            WORD wVersionRequested;
233            WSADATA wsaData;
234            int err; 
235            wVersionRequested = MAKEWORD( 22 );
236            err = WSAStartup( wVersionRequested, &wsaData );
237            if ( err != 0 ) {
238                return false;
239            }

240            #endif
241            sa.sin_family = AF_INET;
242            sa.sin_port = htons(_port);
243            sa.sin_addr.s_addr = inet_addr(_host.c_str());                    
244            _sock = socket(AF_INET,SOCK_DGRAM,0);
245            if( _sock <0  ){
246                return false;
247            }

248            connect(_sock,(sockaddr*)&sa,sizeof(sa));
249            return true;
250        }

251
252        virtual void    Close(){
253            if( _sock >= 0 ){
254#ifdef  WIN32
255                closesocket (_sock);
256#endif
257#ifdef _UNIX
258                close(_sock);
259#endif
260                _sock = -1;
261            }

262        }

263    }
;
264
265
266    enum LEVEL{
267        LOG_ERROR     =0x01,        
268        LOG_WARNING =0x02,
269        LOG_MESSAGE =0x04,
270        LOG_DEBUG    =0x08,
271        LOG_ALL    =LOG_ERROR|LOG_WARNING|LOG_MESSAGE|LOG_DEBUG
272    }
;        
273
274    bool     SetWriter(LogWriter * w){
275        _writer_lock.Lock();
276        _writer_list.push_back(w);
277        _writer_lock.Unlock();
278        return true;
279    }

280
281    void    RemoveWriter(LogWriter*w){
282        std::vector<LogWriter* >::iterator itr;
283        _writer_lock.Lock();
284        itr = std::find(_writer_list.begin(),_writer_list.end(),w);
285        if(itr != _writer_list.end()){
286            _writer_list.erase(itr);
287        }

288        _writer_lock.Unlock();
289    }

290
291    NVLog(){
292        SetFormat();
293        SetLevel();
294    }

295    ~NVLog(){
296
297    }

298
299    void     SetLevel(int level = LOG_ERROR|LOG_WARNING|LOG_MESSAGE|LOG_DEBUG){
300        _level = level;
301    }

302    #define LOG_MAX_BUFF_SIZE 1024*60
303    void    Error(const char * fmt,){
304        va_list marker;        
305        char buff[LOG_MAX_BUFF_SIZE];
306        va_start(marker,fmt);    
307        vsprintf(buff,fmt,marker);
308        va_end(marker); 
309        PrintString(LOG_ERROR,buff);
310    }

311    void    Debug(const char * fmt,){
312        va_list marker;        
313        char buff[LOG_MAX_BUFF_SIZE];
314        va_start(marker,fmt);    
315        vsprintf(buff,fmt,marker);
316        va_end(marker); 
317        PrintString(LOG_DEBUG,buff);
318    }

319    void    Warning(const char * fmt,){
320        va_list marker;        
321        char buff[LOG_MAX_BUFF_SIZE];
322        va_start(marker,fmt);    
323        vsprintf(buff,fmt,marker);
324        va_end(marker); 
325        PrintString(LOG_WARNING,buff);
326    }

327    void    Message(const char * fmt,){
328        va_list marker;        
329        char buff[LOG_MAX_BUFF_SIZE];
330        va_start(marker,fmt);    
331        vsprintf(buff,fmt,marker);
332        va_end(marker); 
333        PrintString(LOG_MESSAGE,buff);
334    }

335    void    Print(int level,const char * fmt,){
336        va_list marker;        
337        char buff[LOG_MAX_BUFF_SIZE];
338        va_start(marker,fmt);    
339        vsprintf(buff,fmt,marker);
340        va_end(marker); 
341        PrintString(level,buff);
342    }

343
344    void    SetFormat(const char *format="<TIME>\t<LEVEL>\t<MESSAGE>\n"){
345        _format = format;
346    }

347private:
348    void    PrintString(int level,const char * data);
349private:
350    std::vector<LogWriter* > _writer_list;
351    NVLock                    _writer_lock;
352    std::string                _format;    // "<LOGLEVEL><LINENO><TIME><MESSAGE>\n"
353    unsigned int             _level;
354}
;
355
356 inline 
357 void     NVLog::PrintString( int  level, const   char   *  data) {
358    char *levelname;    
359    if!(level & _level) ){    
360        return;    
361    }

362    
363    switch(level){
364        case LOG_ERROR:
365            levelname = "ERROR";
366            break;
367        case LOG_WARNING:
368            levelname = "WARNING";
369            break;
370        case LOG_MESSAGE:
371            levelname = "MESSAGE";
372            break;
373        case LOG_DEBUG:
374            levelname = "DEBUG";
375            break;
376        default:
377            return;
378    }

379    if( _format == "" ){
380        return ;
381    }

382    
383    std::string format;
384    char * mark;
385    char * occur;
386    format = _format;
387    mark = "<LEVEL>";
388    int len;
389    len = strlen(mark);
390    if( occur = (char*)strstr( format.c_str(),(const char*)mark) ) {
391        format.replace( occur-format.c_str(),len,levelname);
392    }

393    mark = "<TIME>";
394    len = strlen(mark);
395    if( occur = (char*)strstr( format.c_str(),(const char*)mark) ) {
396        format.replace( occur-format.c_str(),len,NVCalendar::GetCurTimeStr().c_str());
397    }

398    mark = "<MESSAGE>";
399    len = strlen(mark);
400    if( occur = (char*)strstr( format.c_str(),mark) ) {
401        format.replace( occur-format.c_str(),len,data);
402    }

403    std::vector<LogWriter* >::iterator itr;
404    _writer_lock.Lock();
405    for( itr= _writer_list.begin();itr!=_writer_list.end();itr++){
406        (*itr)->Write(format.c_str(),format.size());
407    }
    
408    _writer_lock.Unlock();
409}

410
411
412
413 #define  NVLOG_ADD_UDP_WRITER(log,host,port)    \
414                     NVLog::UdpWriter  *  w  =   new  NVLog::UdpWriter(host,port);\
415                     w -> Open();\
416                     (log).SetWriter(w);
417
418 #endif
419
420
相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
6月前
|
存储 数据采集 Kubernetes
一文详解K8s环境下Job类日志采集方案
本文介绍了K8s中Job和Cronjob控制器用于非常驻容器编排的场景,以及Job容器的特点:增删频率高、生命周期短和突发并发大。文章重点讨论了Job日志采集的关键考虑点,包括容器发现速度、开始采集延时和弹性支持,并对比了5种采集方案:DaemonSet采集、Sidecar采集、ECI采集、同容器采集和独立存储采集。对于短生命周期Job,建议使用Sidecar或ECI采集,通过调整参数确保数据完整性。对于突发大量Job,需要关注服务端资源限制和采集容器的资源调整。文章总结了不同场景下的推荐采集方案,并指出iLogtail和SLS未来可能的优化方向。
|
2月前
|
设计模式 SQL 安全
PHP中的设计模式:单例模式的深入探索与实践在PHP的编程实践中,设计模式是解决常见软件设计问题的最佳实践。单例模式作为设计模式中的一种,确保一个类只有一个实例,并提供全局访问点,广泛应用于配置管理、日志记录和测试框架等场景。本文将深入探讨单例模式的原理、实现方式及其在PHP中的应用,帮助开发者更好地理解和运用这一设计模式。
在PHP开发中,单例模式通过确保类仅有一个实例并提供一个全局访问点,有效管理和访问共享资源。本文详细介绍了单例模式的概念、PHP实现方式及应用场景,并通过具体代码示例展示如何在PHP中实现单例模式以及如何在实际项目中正确使用它来优化代码结构和性能。
49 2
|
2月前
|
存储 运维 监控
超级好用的C++实用库之日志类
超级好用的C++实用库之日志类
41 0
|
6月前
|
Java 计算机视觉 Python
我的自描外挂制作日志——FPS类游戏的自瞄【优化改进1】
我的自描外挂制作日志——FPS类游戏的自瞄【优化改进1】
126 1
|
3月前
|
数据采集 监控 Kubernetes
Job类日志采集问题之iLogtail以减小容器发现和开始采集的延时如何优化
Job类日志采集问题之iLogtail以减小容器发现和开始采集的延时如何优化
|
3月前
|
数据采集 Kubernetes Java
Job类日志采集问题之在日志中添加容器的元信息标签,如何操作
Job类日志采集问题之在日志中添加容器的元信息标签,如何操作
|
3月前
|
存储 容器
Job类日志采集问题之DaemonSet采集方式的参数以减小采集延时如何调整
Job类日志采集问题之DaemonSet采集方式的参数以减小采集延时如何调整
|
3月前
|
容器
Job类日志采集问题之ECI产品采集方式对于弹性扩缩容是如何支持的
Job类日志采集问题之ECI产品采集方式对于弹性扩缩容是如何支持的
|
3月前
|
存储 数据采集 容器
Job类日志采集问题之DaemonSet采集方式在Job日志采集上如何表现
Job类日志采集问题之DaemonSet采集方式在Job日志采集上如何表现
|
3月前
|
存储 Kubernetes 数据处理
Job类日志采集问题之为什么Job容器的日志采集要考虑容器发现速度和开始采集延时,如何理解
Job类日志采集问题之为什么Job容器的日志采集要考虑容器发现速度和开始采集延时,如何理解
下一篇
无影云桌面