From d0bef3ac4389858ece0d6edb80e9bc175a631dbb Mon Sep 17 00:00:00 2001
From: fufu <2398318817@qq.com>
Date: 星期二, 29 十月 2024 14:24:58 +0800
Subject: [PATCH] 添加日志模块代码

---
 Server/马丽萍/code/log/log.cpp                       |  164 ++++++++++++++++
 Server/马丽萍/code/log/.vscode/launch.json           |   24 ++
 Server/马丽萍/code/log/log.h                         |   69 ++++++
 Server/马丽萍/code/log/.vscode/settings.json         |   59 +++++
 Server/马丽萍/code/log/README.md                     |    9 
 Server/马丽萍/code/log/.vscode/c_cpp_properties.json |   18 +
 Server/马丽萍/code/log/block_queue.h                 |  212 +++++++++++++++++++++
 7 files changed, 555 insertions(+), 0 deletions(-)

diff --git "a/Server/\351\251\254\344\270\275\350\220\215/code/log/.vscode/c_cpp_properties.json" "b/Server/\351\251\254\344\270\275\350\220\215/code/log/.vscode/c_cpp_properties.json"
new file mode 100644
index 0000000..cea4d3f
--- /dev/null
+++ "b/Server/\351\251\254\344\270\275\350\220\215/code/log/.vscode/c_cpp_properties.json"
@@ -0,0 +1,18 @@
+{
+  "configurations": [
+    {
+      "name": "windows-gcc-x64",
+      "includePath": [
+        "${workspaceFolder}/**"
+      ],
+      "compilerPath": "gcc",
+      "cStandard": "${default}",
+      "cppStandard": "${default}",
+      "intelliSenseMode": "windows-gcc-x64",
+      "compilerArgs": [
+        ""
+      ]
+    }
+  ],
+  "version": 4
+}
\ No newline at end of file
diff --git "a/Server/\351\251\254\344\270\275\350\220\215/code/log/.vscode/launch.json" "b/Server/\351\251\254\344\270\275\350\220\215/code/log/.vscode/launch.json"
new file mode 100644
index 0000000..6d3cc50
--- /dev/null
+++ "b/Server/\351\251\254\344\270\275\350\220\215/code/log/.vscode/launch.json"
@@ -0,0 +1,24 @@
+{
+  "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
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git "a/Server/\351\251\254\344\270\275\350\220\215/code/log/.vscode/settings.json" "b/Server/\351\251\254\344\270\275\350\220\215/code/log/.vscode/settings.json"
new file mode 100644
index 0000000..bb879da
--- /dev/null
+++ "b/Server/\351\251\254\344\270\275\350\220\215/code/log/.vscode/settings.json"
@@ -0,0 +1,59 @@
+{
+  "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
+}
\ No newline at end of file
diff --git "a/Server/\351\251\254\344\270\275\350\220\215/code/log/README.md" "b/Server/\351\251\254\344\270\275\350\220\215/code/log/README.md"
new file mode 100644
index 0000000..d6dec71
--- /dev/null
+++ "b/Server/\351\251\254\344\270\275\350\220\215/code/log/README.md"
@@ -0,0 +1,9 @@
+
+鍚屾/寮傛鏃ュ織绯荤粺
+===============
+鍚屾/寮傛鏃ュ織绯荤粺涓昏娑夊強浜嗕袱涓ā鍧楋紝涓�涓槸鏃ュ織妯″潡锛屼竴涓槸闃诲闃熷垪妯″潡,鍏朵腑鍔犲叆闃诲闃熷垪妯″潡涓昏鏄В鍐冲紓姝ュ啓鍏ユ棩蹇楀仛鍑嗗.
+> * 鑷畾涔夐樆濉為槦鍒�
+> * 鍗曚緥妯″紡鍒涘缓鏃ュ織
+> * 鍚屾鏃ュ織
+> * 寮傛鏃ュ織
+> * 瀹炵幇鎸夊ぉ銆佽秴琛屽垎绫�
diff --git "a/Server/\351\251\254\344\270\275\350\220\215/code/log/block_queue.h" "b/Server/\351\251\254\344\270\275\350\220\215/code/log/block_queue.h"
new file mode 100644
index 0000000..34c77bd
--- /dev/null
+++ "b/Server/\351\251\254\344\270\275\350\220\215/code/log/block_queue.h"
@@ -0,0 +1,212 @@
+/*************************************************************
+*寰幆鏁扮粍瀹炵幇鐨勯樆濉為槦鍒楋紝m_back = (m_back + 1) % m_max_size;  
+*绾跨▼瀹夊叏锛屾瘡涓搷浣滃墠閮借鍏堝姞浜掓枼閿侊紝鎿嶄綔瀹屽悗锛屽啀瑙i攣
+**************************************************************/
+
+#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
diff --git "a/Server/\351\251\254\344\270\275\350\220\215/code/log/log.cpp" "b/Server/\351\251\254\344\270\275\350\220\215/code/log/log.cpp"
new file mode 100644
index 0000000..411f8eb
--- /dev/null
+++ "b/Server/\351\251\254\344\270\275\350\220\215/code/log/log.cpp"
@@ -0,0 +1,164 @@
+#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)
+{
+    //濡傛灉璁剧疆浜唌ax_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;
+    }
+    //鍐欏叆涓�涓猯og锛屽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();
+}
diff --git "a/Server/\351\251\254\344\270\275\350\220\215/code/log/log.h" "b/Server/\351\251\254\344\270\275\350\220\215/code/log/log.h"
new file mode 100644
index 0000000..64972af
--- /dev/null
+++ "b/Server/\351\251\254\344\270\275\350\220\215/code/log/log.h"
@@ -0,0 +1,69 @@
+#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;
+        //浠庨樆濉為槦鍒椾腑鍙栧嚭涓�涓棩蹇梥tring锛屽啓鍏ユ枃浠�
+        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

--
Gitblit v1.8.0