240717班级,工业化控制系统,煤矿相关行业,昆仑系统
fufu
2024-10-30 d8318ea48f3b7594726283b766db63b70493368a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#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)
{
    if (max_queue_size >= 1)
    {
        m_is_async = true;
        m_log_queue = new block_queue<string>(max_queue_size);
        pthread_t tid;
        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);
    const char *p = strrchr(file_name, '/');
    char log_full_name[256] = {0};
 
    if (p == NULL)
    {
        snprintf(log_full_name, 255, "%d_%02d_%02d_%s", sys_tm->tm_year + 1900, sys_tm->tm_mon + 1, sys_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, sys_tm->tm_year + 1900, sys_tm->tm_mon + 1, sys_tm->tm_mday, log_name);
    }
 
    m_today = sys_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;
    gettimeofday(&now, NULL);
    time_t t = now.tv_sec;
    struct tm *sys_tm = localtime(&t);
    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;
    }
 
    m_mutex.lock();
    m_count++;
 
    if (m_today != sys_tm->tm_mday || m_count % m_split_lines == 0)
    {
        char new_log[256] = {0};
        fflush(m_fp);
        fclose(m_fp);
        char tail[16] = {0};
        snprintf(tail, 16, "%d_%02d_%02d_", sys_tm->tm_year + 1900, sys_tm->tm_mon + 1, sys_tm->tm_mday);
        
        if (m_today != sys_tm->tm_mday)
        {
            snprintf(new_log, 255, "%s%s%s", dir_name, tail, log_name);
            m_today = sys_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");
    }
 
    // 在写入之前检查日志文件大小
    if (check_log_size())
    {
        rotate_logs(); // 如果超过最大文件大小,进行日志轮换
    }
 
    va_list valst;
    va_start(valst, format);
 
    string log_str;
    int n = snprintf(m_buf, 48, "%d-%02d-%02d %02d:%02d:%02d.%06ld %s ",
                     sys_tm->tm_year + 1900, sys_tm->tm_mon + 1, sys_tm->tm_mday,
                     sys_tm->tm_hour, sys_tm->tm_min, sys_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();
}
 
// 添加的文件大小检查函数
bool Log::check_log_size()
{
    if (m_fp)
    {
        fseek(m_fp, 0, SEEK_END);
        long file_size = ftell(m_fp);
        return file_size >= max_size; // 返回文件是否超出限制
    }
    return false;
}
 
void Log::rotate_logs()
{
    fclose(m_fp); // 关闭当前日志文件
    char new_log[256] = {0};
    snprintf(new_log, sizeof(new_log), "%s/%s.%lld", dir_name, log_name, m_count / m_split_lines);
    m_fp = fopen(new_log, "a"); // 打开新的日志文件
    m_count = 0; // 重置日志计数
}