New file |
| | |
| | | { |
| | | "configurations": [ |
| | | { |
| | | "name": "windows-gcc-x64", |
| | | "includePath": [ |
| | | "${workspaceFolder}/**" |
| | | ], |
| | | "compilerPath": "gcc", |
| | | "cStandard": "${default}", |
| | | "cppStandard": "${default}", |
| | | "intelliSenseMode": "windows-gcc-x64", |
| | | "compilerArgs": [ |
| | | "" |
| | | ] |
| | | } |
| | | ], |
| | | "version": 4 |
| | | } |
New file |
| | |
| | | { |
| | | "version": "0.2.0", |
| | | "configurations": [ |
| | | { |
| | | "name": "C/C++ Runner: Debug Session", |
| | | "type": "cppdbg", |
| | | "request": "launch", |
| | | "args": [], |
| | | "stopAtEntry": false, |
| | | "externalConsole": true, |
| | | "cwd": "d:/git_1026/æä»_1025/Server/马丽è/code/log", |
| | | "program": "d:/git_1026/æä»_1025/Server/马丽è/code/log/build/Debug/outDebug", |
| | | "MIMode": "gdb", |
| | | "miDebuggerPath": "gdb", |
| | | "setupCommands": [ |
| | | { |
| | | "description": "Enable pretty-printing for gdb", |
| | | "text": "-enable-pretty-printing", |
| | | "ignoreFailures": true |
| | | } |
| | | ] |
| | | } |
| | | ] |
| | | } |
New file |
| | |
| | | { |
| | | "C_Cpp_Runner.cCompilerPath": "gcc", |
| | | "C_Cpp_Runner.cppCompilerPath": "g++", |
| | | "C_Cpp_Runner.debuggerPath": "gdb", |
| | | "C_Cpp_Runner.cStandard": "", |
| | | "C_Cpp_Runner.cppStandard": "", |
| | | "C_Cpp_Runner.msvcBatchPath": "C:/Program Files/Microsoft Visual Studio/VR_NR/Community/VC/Auxiliary/Build/vcvarsall.bat", |
| | | "C_Cpp_Runner.useMsvc": false, |
| | | "C_Cpp_Runner.warnings": [ |
| | | "-Wall", |
| | | "-Wextra", |
| | | "-Wpedantic", |
| | | "-Wshadow", |
| | | "-Wformat=2", |
| | | "-Wcast-align", |
| | | "-Wconversion", |
| | | "-Wsign-conversion", |
| | | "-Wnull-dereference" |
| | | ], |
| | | "C_Cpp_Runner.msvcWarnings": [ |
| | | "/W4", |
| | | "/permissive-", |
| | | "/w14242", |
| | | "/w14287", |
| | | "/w14296", |
| | | "/w14311", |
| | | "/w14826", |
| | | "/w44062", |
| | | "/w44242", |
| | | "/w14905", |
| | | "/w14906", |
| | | "/w14263", |
| | | "/w44265", |
| | | "/w14928" |
| | | ], |
| | | "C_Cpp_Runner.enableWarnings": true, |
| | | "C_Cpp_Runner.warningsAsError": false, |
| | | "C_Cpp_Runner.compilerArgs": [], |
| | | "C_Cpp_Runner.linkerArgs": [], |
| | | "C_Cpp_Runner.includePaths": [], |
| | | "C_Cpp_Runner.includeSearch": [ |
| | | "*", |
| | | "**/*" |
| | | ], |
| | | "C_Cpp_Runner.excludeSearch": [ |
| | | "**/build", |
| | | "**/build/**", |
| | | "**/.*", |
| | | "**/.*/**", |
| | | "**/.vscode", |
| | | "**/.vscode/**" |
| | | ], |
| | | "C_Cpp_Runner.useAddressSanitizer": false, |
| | | "C_Cpp_Runner.useUndefinedSanitizer": false, |
| | | "C_Cpp_Runner.useLeakSanitizer": false, |
| | | "C_Cpp_Runner.showCompilationTime": false, |
| | | "C_Cpp_Runner.useLinkTimeOptimization": false, |
| | | "C_Cpp_Runner.msvcSecureNoWarnings": false |
| | | } |
New file |
| | |
| | | |
| | | 忥/弿¥æ¥å¿ç³»ç» |
| | | =============== |
| | | 忥/弿¥æ¥å¿ç³»ç»ä¸»è¦æ¶åäºä¸¤ä¸ªæ¨¡åï¼ä¸ä¸ªæ¯æ¥å¿æ¨¡åï¼ä¸ä¸ªæ¯é»å¡é忍¡å,å
¶ä¸å å
¥é»å¡é忍¡åä¸»è¦æ¯è§£å³å¼æ¥åå
¥æ¥å¿ååå¤. |
| | | > * èªå®ä¹é»å¡éå |
| | | > * å便¨¡å¼å建æ¥å¿ |
| | | > * 忥æ¥å¿ |
| | | > * 弿¥æ¥å¿ |
| | | > * å®ç°æå¤©ãè¶
è¡åç±» |
New file |
| | |
| | | /************************************************************* |
| | | *å¾ªç¯æ°ç»å®ç°çé»å¡éåï¼m_back = (m_back + 1) % m_max_size; |
| | | *线ç¨å®å
¨ï¼æ¯ä¸ªæä½åé½è¦å
å äºæ¥éï¼æä½å®åï¼åè§£é |
| | | **************************************************************/ |
| | | |
| | | #ifndef BLOCK_QUEUE_H |
| | | #define BLOCK_QUEUE_H |
| | | |
| | | #include <iostream> |
| | | #include <stdlib.h> |
| | | #include <pthread.h> |
| | | #include <sys/time.h> |
| | | #include "../lock/locker.h" |
| | | using namespace std; |
| | | |
| | | template <class T> |
| | | class block_queue |
| | | { |
| | | public: |
| | | block_queue(int max_size = 1000) |
| | | { |
| | | if (max_size <= 0) |
| | | { |
| | | exit(-1); |
| | | } |
| | | |
| | | m_max_size = max_size; |
| | | m_array = new T[max_size]; |
| | | m_size = 0; |
| | | m_front = -1; |
| | | m_back = -1; |
| | | } |
| | | |
| | | void clear() |
| | | { |
| | | m_mutex.lock(); |
| | | m_size = 0; |
| | | m_front = -1; |
| | | m_back = -1; |
| | | m_mutex.unlock(); |
| | | } |
| | | |
| | | ~block_queue() |
| | | { |
| | | m_mutex.lock(); |
| | | if (m_array != NULL) |
| | | delete [] m_array; |
| | | |
| | | m_mutex.unlock(); |
| | | } |
| | | //夿é忝妿»¡äº |
| | | bool full() |
| | | { |
| | | m_mutex.lock(); |
| | | if (m_size >= m_max_size) |
| | | { |
| | | |
| | | m_mutex.unlock(); |
| | | return true; |
| | | } |
| | | m_mutex.unlock(); |
| | | return false; |
| | | } |
| | | //夿é忝å¦ä¸ºç©º |
| | | bool empty() |
| | | { |
| | | m_mutex.lock(); |
| | | if (0 == m_size) |
| | | { |
| | | m_mutex.unlock(); |
| | | return true; |
| | | } |
| | | m_mutex.unlock(); |
| | | return false; |
| | | } |
| | | //è¿åéé¦å
ç´ |
| | | bool front(T &value) |
| | | { |
| | | m_mutex.lock(); |
| | | if (0 == m_size) |
| | | { |
| | | m_mutex.unlock(); |
| | | return false; |
| | | } |
| | | value = m_array[m_front]; |
| | | m_mutex.unlock(); |
| | | return true; |
| | | } |
| | | //è¿åéå°¾å
ç´ |
| | | bool back(T &value) |
| | | { |
| | | m_mutex.lock(); |
| | | if (0 == m_size) |
| | | { |
| | | m_mutex.unlock(); |
| | | return false; |
| | | } |
| | | value = m_array[m_back]; |
| | | m_mutex.unlock(); |
| | | return true; |
| | | } |
| | | |
| | | int size() |
| | | { |
| | | int tmp = 0; |
| | | |
| | | m_mutex.lock(); |
| | | tmp = m_size; |
| | | |
| | | m_mutex.unlock(); |
| | | return tmp; |
| | | } |
| | | |
| | | int max_size() |
| | | { |
| | | int tmp = 0; |
| | | |
| | | m_mutex.lock(); |
| | | tmp = m_max_size; |
| | | |
| | | m_mutex.unlock(); |
| | | return tmp; |
| | | } |
| | | //å¾éåæ·»å å
ç´ ï¼éè¦å°ææä½¿ç¨éåç线ç¨å
å¤é |
| | | //彿å
ç´ pushè¿éå,ç¸å½äºç产è
ç产äºä¸ä¸ªå
ç´ |
| | | //è¥å½å没æçº¿ç¨çå¾
æ¡ä»¶åé,åå¤éæ æä¹ |
| | | bool push(const T &item) |
| | | { |
| | | |
| | | m_mutex.lock(); |
| | | if (m_size >= m_max_size) |
| | | { |
| | | |
| | | m_cond.broadcast(); |
| | | m_mutex.unlock(); |
| | | return false; |
| | | } |
| | | |
| | | m_back = (m_back + 1) % m_max_size; |
| | | m_array[m_back] = item; |
| | | |
| | | m_size++; |
| | | |
| | | m_cond.broadcast(); |
| | | m_mutex.unlock(); |
| | | return true; |
| | | } |
| | | //popæ¶,妿å½åéåæ²¡æå
ç´ ,å°ä¼çå¾
æ¡ä»¶åé |
| | | bool pop(T &item) |
| | | { |
| | | |
| | | m_mutex.lock(); |
| | | while (m_size <= 0) |
| | | { |
| | | |
| | | if (!m_cond.wait(m_mutex.get())) |
| | | { |
| | | m_mutex.unlock(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | m_front = (m_front + 1) % m_max_size; |
| | | item = m_array[m_front]; |
| | | m_size--; |
| | | m_mutex.unlock(); |
| | | return true; |
| | | } |
| | | |
| | | //å¢å äºè¶
æ¶å¤ç |
| | | bool pop(T &item, int ms_timeout) |
| | | { |
| | | struct timespec t = {0, 0}; |
| | | struct timeval now = {0, 0}; |
| | | gettimeofday(&now, NULL); |
| | | m_mutex.lock(); |
| | | if (m_size <= 0) |
| | | { |
| | | t.tv_sec = now.tv_sec + ms_timeout / 1000; |
| | | t.tv_nsec = (ms_timeout % 1000) * 1000; |
| | | if (!m_cond.timewait(m_mutex.get(), t)) |
| | | { |
| | | m_mutex.unlock(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | if (m_size <= 0) |
| | | { |
| | | m_mutex.unlock(); |
| | | return false; |
| | | } |
| | | |
| | | m_front = (m_front + 1) % m_max_size; |
| | | item = m_array[m_front]; |
| | | m_size--; |
| | | m_mutex.unlock(); |
| | | return true; |
| | | } |
| | | |
| | | private: |
| | | locker m_mutex; |
| | | cond m_cond; |
| | | |
| | | T *m_array; |
| | | int m_size; |
| | | int m_max_size; |
| | | int m_front; |
| | | int m_back; |
| | | }; |
| | | |
| | | #endif |
New file |
| | |
| | | #include <string.h> |
| | | #include <time.h> |
| | | #include <sys/time.h> |
| | | #include <stdarg.h> |
| | | #include "log.h" |
| | | #include <pthread.h> |
| | | using namespace std; |
| | | |
| | | Log::Log() |
| | | { |
| | | m_count = 0; |
| | | m_is_async = false; |
| | | } |
| | | |
| | | Log::~Log() |
| | | { |
| | | if (m_fp != NULL) |
| | | { |
| | | fclose(m_fp); |
| | | } |
| | | } |
| | | //弿¥éè¦è®¾ç½®é»å¡éåçé¿åº¦ï¼åæ¥ä¸éè¦è®¾ç½® |
| | | bool Log::init(const char *file_name, int close_log, int log_buf_size, int split_lines, int max_queue_size) |
| | | { |
| | | //å¦æè®¾ç½®äºmax_queue_size,åè®¾ç½®ä¸ºå¼æ¥ |
| | | if (max_queue_size >= 1) |
| | | { |
| | | m_is_async = true; |
| | | m_log_queue = new block_queue<string>(max_queue_size); |
| | | pthread_t tid; |
| | | //flush_log_thread为åè°å½æ°,è¿é表示å建线ç¨å¼æ¥åæ¥å¿ |
| | | pthread_create(&tid, NULL, flush_log_thread, NULL); |
| | | } |
| | | |
| | | m_close_log = close_log; |
| | | m_log_buf_size = log_buf_size; |
| | | m_buf = new char[m_log_buf_size]; |
| | | memset(m_buf, '\0', m_log_buf_size); |
| | | m_split_lines = split_lines; |
| | | |
| | | time_t t = time(NULL); |
| | | struct tm *sys_tm = localtime(&t); |
| | | struct tm my_tm = *sys_tm; |
| | | |
| | | |
| | | const char *p = strrchr(file_name, '/'); |
| | | char log_full_name[256] = {0}; |
| | | |
| | | if (p == NULL) |
| | | { |
| | | snprintf(log_full_name, 255, "%d_%02d_%02d_%s", my_tm.tm_year + 1900, my_tm.tm_mon + 1, my_tm.tm_mday, file_name); |
| | | } |
| | | else |
| | | { |
| | | strcpy(log_name, p + 1); |
| | | strncpy(dir_name, file_name, p - file_name + 1); |
| | | snprintf(log_full_name, 255, "%s%d_%02d_%02d_%s", dir_name, my_tm.tm_year + 1900, my_tm.tm_mon + 1, my_tm.tm_mday, log_name); |
| | | } |
| | | |
| | | m_today = my_tm.tm_mday; |
| | | |
| | | m_fp = fopen(log_full_name, "a"); |
| | | if (m_fp == NULL) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | void Log::write_log(int level, const char *format, ...) |
| | | { |
| | | struct timeval now = {0, 0}; |
| | | gettimeofday(&now, NULL); |
| | | time_t t = now.tv_sec; |
| | | struct tm *sys_tm = localtime(&t); |
| | | struct tm my_tm = *sys_tm; |
| | | char s[16] = {0}; |
| | | switch (level) |
| | | { |
| | | case 0: |
| | | strcpy(s, "[debug]:"); |
| | | break; |
| | | case 1: |
| | | strcpy(s, "[info]:"); |
| | | break; |
| | | case 2: |
| | | strcpy(s, "[warn]:"); |
| | | break; |
| | | case 3: |
| | | strcpy(s, "[erro]:"); |
| | | break; |
| | | default: |
| | | strcpy(s, "[info]:"); |
| | | break; |
| | | } |
| | | //åå
¥ä¸ä¸ªlogï¼å¯¹m_count++, m_split_linesæå¤§è¡æ° |
| | | m_mutex.lock(); |
| | | m_count++; |
| | | |
| | | if (m_today != my_tm.tm_mday || m_count % m_split_lines == 0) //everyday log |
| | | { |
| | | |
| | | char new_log[256] = {0}; |
| | | fflush(m_fp); |
| | | fclose(m_fp); |
| | | char tail[16] = {0}; |
| | | |
| | | snprintf(tail, 16, "%d_%02d_%02d_", my_tm.tm_year + 1900, my_tm.tm_mon + 1, my_tm.tm_mday); |
| | | |
| | | if (m_today != my_tm.tm_mday) |
| | | { |
| | | snprintf(new_log, 255, "%s%s%s", dir_name, tail, log_name); |
| | | m_today = my_tm.tm_mday; |
| | | m_count = 0; |
| | | } |
| | | else |
| | | { |
| | | snprintf(new_log, 255, "%s%s%s.%lld", dir_name, tail, log_name, m_count / m_split_lines); |
| | | } |
| | | m_fp = fopen(new_log, "a"); |
| | | } |
| | | |
| | | m_mutex.unlock(); |
| | | |
| | | va_list valst; |
| | | va_start(valst, format); |
| | | |
| | | string log_str; |
| | | m_mutex.lock(); |
| | | |
| | | //åå
¥çå
·ä½æ¶é´å
å®¹æ ¼å¼ |
| | | int n = snprintf(m_buf, 48, "%d-%02d-%02d %02d:%02d:%02d.%06ld %s ", |
| | | my_tm.tm_year + 1900, my_tm.tm_mon + 1, my_tm.tm_mday, |
| | | my_tm.tm_hour, my_tm.tm_min, my_tm.tm_sec, now.tv_usec, s); |
| | | |
| | | int m = vsnprintf(m_buf + n, m_log_buf_size - n - 1, format, valst); |
| | | m_buf[n + m] = '\n'; |
| | | m_buf[n + m + 1] = '\0'; |
| | | log_str = m_buf; |
| | | |
| | | m_mutex.unlock(); |
| | | |
| | | if (m_is_async && !m_log_queue->full()) |
| | | { |
| | | m_log_queue->push(log_str); |
| | | } |
| | | else |
| | | { |
| | | m_mutex.lock(); |
| | | fputs(log_str.c_str(), m_fp); |
| | | m_mutex.unlock(); |
| | | } |
| | | |
| | | va_end(valst); |
| | | } |
| | | |
| | | void Log::flush(void) |
| | | { |
| | | m_mutex.lock(); |
| | | //强å¶å·æ°åå
¥æµç¼å²åº |
| | | fflush(m_fp); |
| | | m_mutex.unlock(); |
| | | } |
New file |
| | |
| | | #ifndef LOG_H |
| | | #define LOG_H |
| | | |
| | | #include <stdio.h> |
| | | #include <iostream> |
| | | #include <string> |
| | | #include <stdarg.h> |
| | | #include <pthread.h> |
| | | #include "block_queue.h" |
| | | |
| | | using namespace std; |
| | | |
| | | class Log |
| | | { |
| | | public: |
| | | //C++11以å,使ç¨å±é¨åéææ±ä¸ç¨å é |
| | | static Log *get_instance() |
| | | { |
| | | static Log instance; |
| | | return &instance; |
| | | } |
| | | |
| | | static void *flush_log_thread(void *args) |
| | | { |
| | | Log::get_instance()->async_write_log(); |
| | | } |
| | | //å¯éæ©çåæ°ææ¥å¿æä»¶ãæ¥å¿ç¼å²åºå¤§å°ãæå¤§è¡æ°ä»¥åæé¿æ¥å¿æ¡éå |
| | | bool init(const char *file_name, int close_log, int log_buf_size = 8192, int split_lines = 5000000, int max_queue_size = 0); |
| | | |
| | | void write_log(int level, const char *format, ...); |
| | | |
| | | void flush(void); |
| | | |
| | | private: |
| | | Log(); |
| | | virtual ~Log(); |
| | | void *async_write_log() |
| | | { |
| | | string single_log; |
| | | //ä»é»å¡éåä¸ååºä¸ä¸ªæ¥å¿stringï¼åå
¥æä»¶ |
| | | while (m_log_queue->pop(single_log)) |
| | | { |
| | | m_mutex.lock(); |
| | | fputs(single_log.c_str(), m_fp); |
| | | m_mutex.unlock(); |
| | | } |
| | | } |
| | | |
| | | private: |
| | | char dir_name[128]; //è·¯å¾å |
| | | char log_name[128]; //logæä»¶å |
| | | int m_split_lines; //æ¥å¿æå¤§è¡æ° |
| | | int m_log_buf_size; //æ¥å¿ç¼å²åºå¤§å° |
| | | long long m_count; //æ¥å¿è¡æ°è®°å½ |
| | | int m_today; //å 为æå¤©åç±»,è®°å½å½åæ¶é´æ¯é£ä¸å¤© |
| | | FILE *m_fp; //æå¼logçæä»¶æé |
| | | char *m_buf; |
| | | block_queue<string> *m_log_queue; //é»å¡éå |
| | | bool m_is_async; //æ¯å¦åæ¥æ å¿ä½ |
| | | locker m_mutex; |
| | | int m_close_log; //å
³éæ¥å¿ |
| | | }; |
| | | |
| | | #define LOG_DEBUG(format, ...) if(0 == m_close_log) {Log::get_instance()->write_log(0, format, ##__VA_ARGS__); Log::get_instance()->flush();} |
| | | #define LOG_INFO(format, ...) if(0 == m_close_log) {Log::get_instance()->write_log(1, format, ##__VA_ARGS__); Log::get_instance()->flush();} |
| | | #define LOG_WARN(format, ...) if(0 == m_close_log) {Log::get_instance()->write_log(2, format, ##__VA_ARGS__); Log::get_instance()->flush();} |
| | | #define LOG_ERROR(format, ...) if(0 == m_close_log) {Log::get_instance()->write_log(3, format, ##__VA_ARGS__); Log::get_instance()->flush();} |
| | | |
| | | #endif |