240717班级,工业化控制系统,煤矿相关行业,昆仑系统
lzh
2024-10-31 9af600e364f8758150291a590fb40428e834b58c
Server/ÂíÀöƼ/code/log/log.h
@@ -5,65 +5,92 @@
#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