pstrace

Форк
0
/
log.c 
246 строк · 5.7 Кб
1

2
#include <time.h>
3
#include <stdlib.h>
4
#include <stdbool.h>
5

6
#include "log.h"
7

8
const char * const severity_map[] = {
9
		" [DEBUG]  : ",
10
        " [INFO]   : ",
11
        " [WARNING]: ",
12
        " [ERROR]  : "
13
};
14

15
static void format_string(pst_logger* log, const char* fmt, va_list args)
16
{
17
    log->mStringLen += vsnprintf(log->mString + log->mStringLen, log->mStringSize - log->mStringLen, fmt, args);
18
}
19

20
static void format_prefix(pst_logger* log, SC_LogSeverity severity)
21
{
22
    time_t rawTime;
23
    struct tm * timeinfo;
24
    time(&rawTime);
25
    timeinfo = gmtime(&rawTime);
26

27
    log->mStringLen += strftime(log->mString, sizeof(log->mString), "%d-%m-%Y %H:%M:%S", timeinfo);
28
    log->mStringLen += snprintf(log->mString + log->mStringLen, sizeof(log->mString) - log->mStringLen, "%s", severity_map[(int)severity]);
29
}
30

31
static void format_postfix(pst_logger* log)
32
{
33
    if((log->mStringLen + 2) < log->mStringSize) {
34
        log->mString[log->mStringLen++] = '\n';
35
        log->mString[log->mStringLen++] = 0;
36
    }
37
}
38

39
//variable argument number logging
40
static void log_base(pst_logger* log, SC_LogSeverity severity, const char* fmt, ...)
41
{
42
    if (severity < log->mCurrentSeverity)
43
        return;
44

45
    pthread_mutex_lock(&log->mLock);
46

47
    if(!log->is_opened(log)) {
48
        log->open(log);
49
    }
50

51
    log->mStringLen = 0;
52
    format_prefix(log, severity);
53
    va_list args;
54
    va_start(args, fmt);
55
    format_string(log, fmt, args);
56
    va_end(args);
57
    format_postfix(log);
58
    log->send_message(log, severity);
59

60
    pthread_mutex_unlock(&log->mLock);
61
}
62

63
static void log_init_base(pst_logger* plog, const char* source)
64
{
65
    // methods
66
    plog->log = log_base;
67

68
    // fields
69
    plog->mpSource = 0;
70
    if(source) {
71
        plog->mpSource = strdup(source);
72
    }
73
    plog->mString[0] = 0;
74
    plog->mStringSize = sizeof(plog->mString);
75
    plog->mStringLen = 0;
76
    plog->mCurrentSeverity = SEVERITY_DEBUG;
77
    pthread_mutex_init(&plog->mLock, NULL);
78
    plog->child = 0;
79
}
80

81
void pst_log_fini(pst_logger* log)
82
{
83
    pthread_mutex_destroy(&log->mLock);
84
    log->close(log);
85
    if(log->mpSource) {
86
        free(log->mpSource);
87
        log->mpSource = 0;
88
    }
89
}
90

91

92
//
93
// Console logger implementation
94
//
95
#define RED     "\e[0;31m"
96
#define GREEN   "\e[0;32m"
97
#define YELLOW  "\e[1;33m"
98
#define NC      "\e[0m" // No Color
99

100
//actually sends message to the source
101
static void send_msg_console(pst_logger* log, SC_LogSeverity severity)
102
{
103
    const char* color = NC;
104
    switch(severity) {
105
        case SEVERITY_DEBUG:
106
            color = NC;
107
            break;
108
        case SEVERITY_ERROR:
109
            color = RED;
110
            break;
111
        case SEVERITY_INFO:
112
            color = GREEN;
113
            break;
114
        case SEVERITY_WARNING:
115
            color = YELLOW;
116
            break;
117
        default:
118
            color = NC;
119
            break;
120
    }
121

122
    fprintf(stderr, "%s%s%s", color, log->mString, NC);
123
}
124

125
static void close_console(pst_logger* log) {
126
    // do nothing
127
}
128

129
static bool open_console(pst_logger* log) {
130
    return true;
131
}
132

133
static bool is_opened_console(pst_logger* log) {
134
    return true;
135
}
136

137
void pst_log_init_console(pst_logger* log)
138
{
139
    log_init_base(log, NULL);
140
    log->close = close_console;
141
    log->open = open_console;
142
    log->is_opened = is_opened_console;
143
    log->send_message = send_msg_console;
144
}
145

146
//
147
// Log to file
148
//
149

150
typedef struct _file_spec {
151
    FILE*       fd;
152
    uint64_t    max_bytes;
153
    uint64_t    num_bytes;
154
    char*       dir;
155
    char*       fname;
156
} file_spec;
157

158
//open file for writing
159
static bool open_file(pst_logger* log)
160
{
161
    file_spec* fsp = (file_spec*)log->child;
162
    if(!fsp) {
163
        fprintf(stderr, "Wrong initialization of File-based logger\n");
164
        return false;
165
    }
166

167
    if(!fsp->fd) {
168
        // extract log and path names
169
        uint32_t namelen = strlen(log->mpSource);
170
        if(namelen) {
171
            const char* ptr = strrchr(log->mpSource, '/');
172
            uint32_t pathlen = 0;
173
            if(ptr) {
174
                pathlen = ptr - log->mpSource + 1;
175
                namelen -= pathlen + 1;
176
            }
177

178
            fsp->dir = strndup(log->mpSource, pathlen);
179
            fsp->fname = strndup(log->mpSource + pathlen, namelen);
180

181
            //open the file finally
182
            fsp->fd = fopen(log->mpSource, "a+");
183
        }
184
    }
185

186
    return (fsp->fd != 0);
187
}
188

189
static void close_file(pst_logger* log)
190
{
191
    file_spec* fsp = (file_spec*)log->child;
192
    if(!fsp) {
193
        fprintf(stderr, "Wrong initialization of File-based logger while close\n");
194
        return;
195
    }
196

197
    if(fsp->fd) {
198
        fclose(fsp->fd);
199
    }
200

201
    fsp->fd = 0;
202
    fsp->max_bytes = 0;
203
}
204

205
static bool is_file_opened(pst_logger* log)
206
{
207
    file_spec* fsp = (file_spec*)log->child;
208
    if(!fsp) {
209
        fprintf(stderr, "Wrong initialization of File-based logger while check open\n");
210
        return 0;
211
    }
212
    return (fsp->fd != 0);
213
}
214

215
static void send_msg_file(pst_logger* log, SC_LogSeverity severity)
216
{
217
    file_spec* fsp = (file_spec*)log->child;
218
    if(!fsp) {
219
        fprintf(stderr, "Wrong initialization of File-based logger while check send message\n");
220
        return;
221
    }
222
    if(fsp->fd && fsp->num_bytes < fsp->max_bytes) {
223
        if(fputs(log->mString, fsp->fd) >= 0) {
224
            fflush(fsp->fd);
225
            fsp->num_bytes += log->mStringLen;
226
        } else {
227
            fclose(fsp->fd);
228
            fsp->fd = 0;
229
        }
230
    }
231
}
232

233
void pst_log_init_file(pst_logger* log, const char* path, uint64_t max_bytes)
234
{
235
    log_init_base(log, path);
236
    file_spec* fsp = (file_spec*)malloc(sizeof(file_spec));
237
    fsp->fd = 0;
238
    fsp->max_bytes = max_bytes;
239
    fsp->num_bytes = 0;
240
    log->child = fsp;
241

242
    log->close = close_file;
243
    log->open = open_file;
244
    log->is_opened = is_file_opened;
245
    log->send_message = send_msg_file;
246

247
}
248

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.