本人一直使用的日志類,支持3種輸出方式(windows窗體,udp,常規(guī)文件),并格式化輸出:
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
{
44
public:
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)
{ //需要發(fā)送時(shí)發(fā)現(xiàn)
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); //達(dá)到指定時(shí)間循環(huán)到文件頭部
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( 2, 2 );
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
}
347
private:
348
void PrintString(int level,const char * data);
349
private:
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

2

/**//*3
nvlog.h4
----------------5
application logger6
2003.10 created scott 7
2005.09.10 rebuild scott8
created RegFileWriter,UdpWriter,WindowWriter to distinguish log data type9
2005.09.22 modified RegFileWriter::RegFileWriter() scott10
2005.11.10 scott add __FILE__,__LINE__11
*/12

13
#ifndef _NVLOG14
#define _NVLOG15

16
#ifdef _UNIX17
#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
#endif24

25
#ifdef WIN3226
#include <windows.h>27
#include <winsock.h>28
#include <io.h>29
#endif30

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
{44
public:45

enum WriterType
{46
UDP, 47
REGFILE,48
WINDOW,49
UNKNOWN50
};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 WIN3278

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)
{ //需要發(fā)送時(shí)發(fā)現(xiàn) 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
#endif137
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); //達(dá)到指定時(shí)間循環(huán)到文件頭部 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 WIN32232
WORD wVersionRequested;233
WSADATA wsaData;234
int err; 235
wVersionRequested = MAKEWORD( 2, 2 );236
err = WSAStartup( wVersionRequested, &wsaData );237

if ( err != 0 )
{238
return false;239
}240
#endif241
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 WIN32255
closesocket (_sock);256
#endif257
#ifdef _UNIX258
close(_sock);259
#endif260
_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_DEBUG272
}; 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*60303

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
}347
private:348
void PrintString(int level,const char * data);349
private: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
#endif419

420

posted on 2005-12-11 20:31 放屁阿狗 閱讀(3875) 評論(4) 編輯 收藏 引用 所屬分類: unix/linux/solaris/sco-unix/novell 、視頻監(jiān)控


