Merge branch 'master' of ssh://115.28.86.8:29418/~admin/昆仑_1025
1 文件已重命名
10个文件已修改
15个文件已添加
3个文件已删除
New file |
| | |
| | | #include <iostream> |
| | | #include <memory> |
| | | #include <mutex> |
| | | #include <string> |
| | | #include <mysql_driver.h> |
| | | #include <mysql_connection.h> |
| | | #include <cppconn/statement.h> |
| | | #include <cppconn/resultset.h> |
| | | |
| | | class DatabaseOperator { |
| | | private: |
| | | // ç§ææé 彿° |
| | | DatabaseOperator() { |
| | | try { |
| | | driver = sql::mysql::get_mysql_driver_instance(); |
| | | connection = driver->connect("tcp://127.0.0.1:3306", "username", "password"); |
| | | connection->setSchema("your_database"); |
| | | } catch (sql::SQLException &e) { |
| | | std::cerr << "æ°æ®åºè¿æ¥é误: " << e.what() << std::endl; |
| | | } |
| | | } |
| | | |
| | | static DatabaseOperator* instance; |
| | | static std::mutex mutex; |
| | | sql::Driver* driver; |
| | | std::unique_ptr<sql::Connection> connection; |
| | | |
| | | public: |
| | | // è·ååä¾å®ä¾ |
| | | static DatabaseOperator* getInstance() { |
| | | std::lock_guard<std::mutex> lock(mutex); |
| | | if (instance == nullptr) { |
| | | instance = new DatabaseOperator(); |
| | | } |
| | | return instance; |
| | | } |
| | | |
| | | // æ§è¡æ¥è¯¢æä½ï¼ç¤ºä¾ï¼ |
| | | sql::ResultSet* query(const std::string& sql) { |
| | | try { |
| | | std::unique_ptr<sql::Statement> stmt(connection->createStatement()); |
| | | return stmt->executeQuery(sql); |
| | | } catch (sql::SQLException &e) { |
| | | std::cerr << "æ¥è¯¢é误: " << e.what() << std::endl; |
| | | } |
| | | return nullptr; |
| | | } |
| | | }; |
| | | |
| | | std::mutex DatabaseOperator::mutex; |
| | | DatabaseOperator* DatabaseOperator::instance = nullptr; |
New file |
| | |
| | | #!/bin/bash |
| | | |
| | | # æ°æ®åºè¿æ¥åæ° |
| | | DB_USER="your_username" |
| | | DB_PASS="your_password" |
| | | DB_NAME="your_database_name" |
| | | BACKUP_DIR="/path/to/backup/directory" |
| | | |
| | | # è·åå½åæ¥æï¼ç¨äºæä»¶å |
| | | DATE=$(date +%Y%m%d%H%M%S) |
| | | |
| | | # å¤ä»½æä»¶å |
| | | BACKUP_FILE="${BACKUP_DIR}/backup_${DATE}.sql" |
| | | |
| | | # å建å¤ä»½ç®å½ï¼å¦æä¸åå¨ï¼ |
| | | mkdir -p $BACKUP_DIR |
| | | |
| | | # 使ç¨mysqldumpè¿è¡æ°æ®åºå¤ä»½ |
| | | mysqldump -u $DB_USER -p$DB_PASS $DB_NAME > $BACKUP_FILE |
| | | |
| | | if [ $? -eq 0 ]; then |
| | | echo "æ°æ®åºå¤ä»½æåï¼$BACKUP_FILE" |
| | | else |
| | | echo "æ°æ®åºå¤ä»½å¤±è´¥" |
| | | fi |
| | | |
| | | # æ·»å 宿¶ä»»å¡ï¼ä½¿ç¨crontab -eæ¥ç¼è¾å®æ¶ä»»å¡ï¼ |
| | | # ä¾å¦ï¼æ¯å¤©åæ¨2ç¹æ§è¡å¤ä»½ |
| | | # 0 2 * * * /path/to/this/script.sh |
New file |
| | |
| | | #include "MySQL.h" |
| | | #include <WinSock2.h> |
| | | #include <mysql.h> |
| | | #include <iostream> |
| | | #include <string> |
| | | using namespace std; |
| | | int main() { |
| | | MYSQL mysql; |
| | | mysql_init(&mysql);//åå§å |
| | | //è¿æ¥æ°æ®åºæå¡å¨æå¡å¨ IP ç¨æ·å å¯ç æ°æ®åºç«¯å£å· |
| | | mysql_real_connect(&mysql, "192.168.136.128", "root", "123456", "wang", 3306, NULL, 0); |
| | | |
| | | string sql="set names gbk"; |
| | | mysql_real_query(&mysql, sql.c_str(), sql.size()); |
| | | mysql_close(&mysql); |
| | | return 0; |
New file |
| | |
| | | #include <iostream> |
| | | #include <list> |
| | | #include <mutex> |
| | | #include <condition_variable> |
| | | #include <mysql_driver.h> |
| | | #include <mysql_connection.h> |
| | | #include <cppconn/statement.h> |
| | | #include <cppconn/resultset.h> |
| | | |
| | | class SQLConnectionPool { |
| | | private: |
| | | SQLConnectionPool(int minConns, int maxConns) : |
| | | minConnections(minConns), maxConnections(maxConns), currentConnections(0) {} |
| | | |
| | | static SQLConnectionPool* instance; |
| | | static std::mutex mutex; |
| | | std::condition_variable cv; |
| | | int minConnections; |
| | | int maxConnections; |
| | | int currentConnections; |
| | | std::list<std::unique_ptr<sql::Connection>> connections; |
| | | |
| | | // å建ä¸ä¸ªæ°çæ°æ®åºè¿æ¥ |
| | | std::unique_ptr<sql::Connection> createConnection() { |
| | | try { |
| | | sql::Driver* driver = sql::mysql::get_mysql_driver_instance(); |
| | | std::unique_ptr<sql::Connection> conn(driver->connect("tcp://127.0.0.1:3306", "username", "password")); |
| | | conn->setSchema("your_database"); |
| | | return conn; |
| | | } catch (sql::SQLException &e) { |
| | | std::cerr << "åå»ºè¿æ¥é误: " << e.what() << std::endl; |
| | | return nullptr; |
| | | } |
| | | } |
| | | |
| | | public: |
| | | // è·ååä¾å®ä¾ |
| | | static SQLConnectionPool* getInstance(int minConns, int maxConns) { |
| | | std::lock_guard<std::mutex> lock(mutex); |
| | | if (instance == nullptr) { |
| | | instance = new SQLConnectionPool(minConns, maxConns); |
| | | instance->initializePool(); |
| | | } |
| | | return instance; |
| | | } |
| | | |
| | | // åå§åè¿æ¥æ± |
| | | void initializePool() { |
| | | for (int i = 0; i < minConnections; ++i) { |
| | | std::unique_ptr<sql::Connection> conn = createConnection(); |
| | | if (conn) { |
| | | connections.push_back(std::move(conn)); |
| | | currentConnections++; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // è·åæ°æ®åºè¿æ¥ |
| | | std::unique_ptr<sql::Connection> getConnection() { |
| | | std::unique_lock<std::mutex> lock(mutex); |
| | | while (connections.empty() && currentConnections >= maxConnections) { |
| | | cv.wait(lock); |
| | | } |
| | | |
| | | std::unique_ptr<sql::Connection> conn; |
| | | if (!connections.empty()) { |
| | | conn = std::move(connections.front()); |
| | | connections.pop_front(); |
| | | } else if (currentConnections < maxConnections) { |
| | | conn = createConnection(); |
| | | if (conn) { |
| | | currentConnections++; |
| | | } |
| | | } |
| | | return conn; |
| | | } |
| | | |
| | | // å½è¿æ°æ®åºè¿æ¥ |
| | | void releaseConnection(std::unique_ptr<sql::Connection>& conn) { |
| | | std::lock_guard<std::mutex> lock(mutex); |
| | | if (currentConnections > minConnections) { |
| | | currentConnections--; |
| | | } else { |
| | | connections.push_back(std::move(conn)); |
| | | } |
| | | cv.notify_one(); |
| | | } |
| | | }; |
| | | |
| | | std::mutex SQLConnectionPool::mutex; |
| | | SQLConnectionPool* SQLConnectionPool::instance = nullptr; |
New file |
| | |
| | | #include <iostream> |
| | | #include <mysql_driver.h> |
| | | #include <mysql_connection.h> |
| | | #include <cppconn/statement.h> |
| | | #include <cppconn/prepared_statement.h> |
| | | #include <cppconn/resultset.h> |
| | | #include <string> |
| | | #include <regex> |
| | | |
| | | class DatabaseUtils { |
| | | public: |
| | | // è¿æ¥æ°æ®åº |
| | | static sql::Connection* connect() { |
| | | try { |
| | | sql::mysql::MySQL_Driver* driver = sql::mysql::get_mysql_driver_instance(); |
| | | sql::Connection* con = driver->connect("tcp://127.0.0.1:3306", "mayi", "123456"); |
| | | con->setSchema("your_database"); |
| | | return con; |
| | | } catch (sql::SQLException& e) { |
| | | std::cerr << "æ°æ®åºè¿æ¥é误: " << e.what() << std::endl; |
| | | return nullptr; |
| | | } |
| | | } |
| | | |
| | | // æ£æ¥SQLè¯å¥æ¯å¦å卿½å¨æ³¨å
¥é£é©ï¼ç®åæ£åæ ¡éªï¼ |
| | | static bool isSafeSQL(const std::string& sql) { |
| | | // ç®åçæ£å表达å¼ï¼é²æ¢å¸¸è§ç注å
¥å
³é®è¯ |
| | | std::regex injectionRegex("(drop|delete|update|insert|select\\s+\\*\\s+from)", std::regex_constants::icase); |
| | | return!std::regex_search(sql, injectionRegex); |
| | | } |
| | | |
| | | // 使ç¨åæ°åæ¥è¯¢æ§è¡SQLè¯å¥ |
| | | static sql::ResultSet* executeSafeQuery(sql::Connection* con, const std::string& sql, const std::vector<std::string>& params) { |
| | | try { |
| | | sql::PreparedStatement* pstmt = con->prepareStatement(sql); |
| | | for (size_t i = 0; i < params.size(); ++i) { |
| | | pstmt->setString(i + 1, params[i]); |
| | | } |
| | | return pstmt->executeQuery(); |
| | | } catch (sql::SQLException& e) { |
| | | std::cerr << "æ¥è¯¢æ§è¡é误: " << e.what() << std::endl; |
| | | return nullptr; |
| | | } |
| | | } |
| | | }; |
| | | |
| | | int main() { |
| | | sql::Connection* con = DatabaseUtils::connect(); |
| | | if (con) { |
| | | std::string sql = "SELECT * FROM your_table WHERE column_name =?"; |
| | | std::vector<std::string> params = {"test_value"}; |
| | | if (DatabaseUtils::isSafeSQL(sql)) { |
| | | sql::ResultSet* res = DatabaseUtils::executeSafeQuery(con, sql, params); |
| | | if (res) { |
| | | while (res->next()) { |
| | | // å¤çç»æ |
| | | std::cout << res->getString(1) << std::endl; |
| | | } |
| | | delete res; |
| | | } |
| | | } else { |
| | | std::cerr << "æ½å¨çSQL注å
¥é£é©" << std::endl; |
| | | } |
| | | delete con; |
| | | } |
| | | return 0; |
| | | } |
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 |