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( 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 }
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
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( 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 }
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