|
@@ -0,0 +1,194 @@
|
|
|
+#include "stdafx.h"
|
|
|
+#include "log.h"
|
|
|
+//#include <sys/file.h>
|
|
|
+//#include <stdarg.h>
|
|
|
+#include <time.h>
|
|
|
+#include <stdlib.h>
|
|
|
+//#include <string.h>
|
|
|
+//#include <errno.h>
|
|
|
+#include <io.h>
|
|
|
+//#include <sys/stat.h>
|
|
|
+#include <direct.h>
|
|
|
+
|
|
|
+#ifndef R_OK
|
|
|
+#define R_OK 4
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifndef W_OK
|
|
|
+#define W_OK 2
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifndef X_OK
|
|
|
+#define X_OK 6
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifndef F_OK
|
|
|
+#define F_OK 0
|
|
|
+#endif
|
|
|
+
|
|
|
+Log_Writer WARN_W;
|
|
|
+Log_Writer INFO_W;
|
|
|
+char Log_Writer::m_buffer[_LOG_BUFFSIZE] = {0};
|
|
|
+
|
|
|
+bool log_init(LogLevel l, const char* p_modulename, const char* p_logdir)
|
|
|
+{
|
|
|
+ //如果路径存在文件夹,则判断是否存在
|
|
|
+ if (_access(p_logdir, 0) == -1)
|
|
|
+ {
|
|
|
+ if (mkdir(p_logdir ) < 0)
|
|
|
+ fprintf(stderr, "create folder failed\n");
|
|
|
+ }
|
|
|
+ char _location_str[MAX_PATH];
|
|
|
+ _snprintf(_location_str, MAX_PATH, "%s\\%s.log", p_logdir, p_modulename);
|
|
|
+ INFO_W.loginit(l, _location_str);
|
|
|
+ _snprintf(_location_str, MAX_PATH, "%s\\%s.error", p_logdir, p_modulename);
|
|
|
+ //warning级别以上日志去WARN_W 去向由宏决定的 请见macro_define.h
|
|
|
+ if(l > LL_WARNING)
|
|
|
+ WARN_W.loginit(l, _location_str);
|
|
|
+ else
|
|
|
+ WARN_W.loginit(LL_WARNING, _location_str);
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+const char* Log_Writer::logLevelToString(LogLevel l)
|
|
|
+{
|
|
|
+ switch ( l )
|
|
|
+ {
|
|
|
+ case LL_DEBUG:
|
|
|
+ return "DEBUG";
|
|
|
+ case LL_TRACE:
|
|
|
+ return "TRACE";
|
|
|
+ case LL_NOTICE:
|
|
|
+ return "NOTICE";
|
|
|
+ case LL_WARNING:
|
|
|
+ return "WARN" ;
|
|
|
+ case LL_ERROR:
|
|
|
+ return "ERROR";
|
|
|
+ default:
|
|
|
+ return "UNKNOWN";
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+bool Log_Writer::checklevel(LogLevel l)
|
|
|
+{
|
|
|
+ if(l >= m_system_level)
|
|
|
+ return true;
|
|
|
+ else
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+bool Log_Writer::loginit(LogLevel l, const char *filelocation, bool append, bool issync)
|
|
|
+{
|
|
|
+ MACRO_RET(NULL != fp, false);
|
|
|
+ m_system_level = l;
|
|
|
+ m_isappend = append;
|
|
|
+ m_issync = issync;
|
|
|
+ if(strlen(filelocation) >= (sizeof(m_filelocation) -1))
|
|
|
+ {
|
|
|
+ fprintf(stderr, "the path of log file is too long:%d limit:%d\n", strlen(filelocation), sizeof(m_filelocation) -1);
|
|
|
+ exit(0);
|
|
|
+ }
|
|
|
+ //本地存储filelocation 以防止在栈上的非法调用调用
|
|
|
+ strncpy(m_filelocation, filelocation, sizeof(m_filelocation));
|
|
|
+ m_filelocation[sizeof(m_filelocation) -1] = '\0';
|
|
|
+
|
|
|
+ if('\0' == m_filelocation[0])
|
|
|
+ {
|
|
|
+ fp = stdout;
|
|
|
+ fprintf(stderr, "now all the running-information are going to put to stderr\n");
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ fp = fopen(m_filelocation, append ? "a":"w");
|
|
|
+ if(fp == NULL)
|
|
|
+ {
|
|
|
+ fprintf(stderr, "cannot open log file,file location is %s\n", m_filelocation);
|
|
|
+ exit(0);
|
|
|
+ }
|
|
|
+ //setvbuf (fp, io_cached_buf, _IOLBF, sizeof(io_cached_buf)); //buf set _IONBF _IOLBF _IOFBF
|
|
|
+ setvbuf (fp, (char *)NULL, _IOLBF, _LOG_BUFFSIZE);
|
|
|
+ fprintf(stderr, "now all the running-information are going to the file %s\n", m_filelocation);
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+int Log_Writer::premakestr(char* m_buffer, LogLevel l)
|
|
|
+{
|
|
|
+ time_t now;
|
|
|
+ now = time(&now);;
|
|
|
+ struct tm vtm = *localtime(&now);
|
|
|
+
|
|
|
+ // 获取今年年份;
|
|
|
+ //__time64_t gmt = time(NULL); // 获取当前日历时间(1900-01-01开始的Unix时间戳);
|
|
|
+ //struct tm gmtm = { 0 };
|
|
|
+ //localtime_s(&gmtm, &gmt); // 时间戳转成本地时间;
|
|
|
+
|
|
|
+ return _snprintf(m_buffer, _LOG_BUFFSIZE, "%s: %02d-%02d %02d:%02d:%02d ", logLevelToString(l),
|
|
|
+ vtm.tm_mon + 1, vtm.tm_mday, vtm.tm_hour, vtm.tm_min, vtm.tm_sec);
|
|
|
+}
|
|
|
+
|
|
|
+bool Log_Writer::log(LogLevel l, char* logformat, ...)
|
|
|
+{
|
|
|
+ MACRO_RET(!checklevel(l), false);
|
|
|
+ int _size;
|
|
|
+ int prestrlen = 0;
|
|
|
+
|
|
|
+ memset(m_buffer, 0, _LOG_BUFFSIZE);
|
|
|
+ char * star = m_buffer;
|
|
|
+ prestrlen = premakestr(star, l);
|
|
|
+ star += prestrlen;
|
|
|
+
|
|
|
+ va_list args = NULL;
|
|
|
+ va_start(args, logformat);
|
|
|
+ _size = _vstprintf_s(star, _LOG_BUFFSIZE - prestrlen, logformat, args);//_vstprintf_s _vsntprintf
|
|
|
+ va_end(args);
|
|
|
+
|
|
|
+ if(NULL == fp)
|
|
|
+ fprintf(stderr, "%s", m_buffer);
|
|
|
+ else
|
|
|
+ _write(m_buffer, prestrlen + _size);
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+bool Log_Writer::_write(char *_pbuffer, int len)
|
|
|
+{
|
|
|
+ if(0 != _access(m_filelocation, W_OK))
|
|
|
+ {
|
|
|
+ AutoThreadSection _cs(&m_mutex);
|
|
|
+ //锁内校验 access 看是否在等待锁过程中被其他线程loginit了 避免多线程多次close 和init
|
|
|
+ if(0 != _access(m_filelocation, W_OK))
|
|
|
+ {
|
|
|
+ logclose();
|
|
|
+ loginit(m_system_level, m_filelocation, m_isappend, m_issync);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(1 == fwrite(_pbuffer, len, 1, fp)) //only write 1 item
|
|
|
+ {
|
|
|
+ if(m_issync)
|
|
|
+ fflush(fp);
|
|
|
+ *_pbuffer='\0';
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ int x = errno;
|
|
|
+ fprintf(stderr, "Failed to write to logfile. errno:%s message:%s", strerror(x), _pbuffer);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+LogLevel Log_Writer::get_level()
|
|
|
+{
|
|
|
+ return m_system_level;
|
|
|
+}
|
|
|
+
|
|
|
+bool Log_Writer::logclose()
|
|
|
+{
|
|
|
+ if(fp == NULL)
|
|
|
+ return false;
|
|
|
+ fflush(fp);
|
|
|
+ fclose(fp);
|
|
|
+ fp = NULL;
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|