| | |
| | | #include <iostream> |
| | | #include <string> |
| | | #include <stdarg.h> |
| | | #include <pthread.h> |
| | | #include <thread> |
| | | #include "block_queue.h" |
| | | #include "locker.h" // ç¡®ä¿ locker.h 被å
å« |
| | | #include <fstream> |
| | | |
| | | using namespace std; |
| | | |
| | | // æ¥å¿çº§å«æä¸¾ |
| | | enum LogLevel { |
| | | DEBUG = 0, |
| | | INFO, |
| | | WARN, |
| | | ERROR |
| | | }; |
| | | |
| | | // åå¨è§£ææ¥å¿æä»¶çç»æä½ |
| | | struct ParsedLog { |
| | | std::string timestamp; // æ¶é´æ³ |
| | | std::string device_id; // 设å¤ID |
| | | std::string level; // æ¥å¿çº§å« |
| | | std::string content; // æ¥å¿å
容 |
| | | }; |
| | | |
| | | 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 flush_log_thread(); // ä¿®æ¹ä¸ºééææå彿° |
| | | |
| | | // åå§åæ¥å¿ç³»ç»ï¼åæ°å
æ¬æä»¶åãæ¯å¦å
³éæ¥å¿ãç¼å²åºå¤§å°ãæå¤§è¡æ°åæå¤§éåå¤§å° |
| | | bool Log::init(const char *file_name, int close_log, int log_buf_size, int split_lines, int max_queue_size); |
| | | |
| | | |
| | | // åå
¥æ¥å¿ |
| | | 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(); |
| | | } |
| | | } |
| | | //æ¥æ¶åå§çè¦å
Œ
±ç±» |
| | | void receiveLog(const std::string& raw_log); // æ¥æ¶åå§æ¥å¿ |
| | | |
| | | 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; //å
³éæ¥å¿ |
| | | Log(); // æé 彿° |
| | | virtual ~Log(); // ææå½æ° |
| | | |
| | | void async_write_log(); // 弿¥åå
¥æ¥å¿ |
| | | bool check_log_size(); // æ£æ¥æ¥å¿æä»¶å¤§å° |
| | | void rotate_logs(); // è½®æ¢æ¥å¿æä»¶ |
| | | |
| | | ParsedLog parseLog(const std::string& log); // è§£ææ¥å¿ |
| | | bool init(const std::string &file_name, int close_log, int log_buf_size, int split_lines, int max_queue_size); |
| | | void queryLogs(const std::string &device_id); // æ¥è¯¢æ¥å¿ |
| | | |
| | | const char* log_level_to_string(int level); // å°æ¥å¿çº§å«è½¬æ¢ä¸ºå符串 |
| | | int levelToInt(const std::string &level); |
| | | |
| | | private: |
| | | char dir_name[128]; // æ¥å¿æä»¶ç®å½ |
| | | char log_name[128]; // æ¥å¿æä»¶å |
| | | int m_split_lines; // æ¥å¿æå¤§è¡æ° |
| | | int m_log_buf_size; // æ¥å¿ç¼å²åºå¤§å° |
| | | long long m_count; // æ¥å¿è¡æ°è®°å½ |
| | | int m_today; // è®°å½å½åæ¶é´ |
| | | std::ofstream m_fp; // å° FILE * m_fp æ´æ¹ä¸º std::ofstream m_fp |
| | | char *m_buf; // æ¥å¿ç¼å²åº |
| | | block_queue<string> *m_log_queue; // é»å¡éå |
| | | bool m_is_async; // æ¯å¦å¼æ¥æ å¿ä½ |
| | | locker m_mutex; // äºæ¥é |
| | | int m_close_log; // å
³éæ¥å¿çæ å¿ |
| | | long max_size = 10 * 1024 * 1024; // 10MB |
| | | //æµè¯æä»¶éé¢ç |
| | | 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();} |
| | | // å®å®ä¹ç¨äºä¸å级å«çæ¥å¿è®°å½ |
| | | #define LOG_DEBUG(format, ...) if(0 == m_close_log) {Log::get_instance()->write_log(DEBUG, format, ##__VA_ARGS__); Log::get_instance()->flush();} |
| | | #define LOG_INFO(format, ...) if(0 == m_close_log) {Log::get_instance()->write_log(INFO, format, ##__VA_ARGS__); Log::get_instance()->flush();} |
| | | #define LOG_WARN(format, ...) if(0 == m_close_log) {Log::get_instance()->write_log(WARN, format, ##__VA_ARGS__); Log::get_instance()->flush();} |
| | | #define LOG_ERROR(format, ...) if(0 == m_close_log) {Log::get_instance()->write_log(ERROR, format, ##__VA_ARGS__); Log::get_instance()->flush();} |
| | | |
| | | #endif |