forked from NJUST-FishTeam/OnlineJudgeCore
-
Notifications
You must be signed in to change notification settings - Fork 2
/
logger.h
157 lines (143 loc) · 4.12 KB
/
logger.h
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
/*
*
* LOGGER v0.0.3
* A simple logger for c/c++ under linux, multiprocess-safe
*
* ---- CopyLeft by Felix021 @ http://www.felix021.com ----
*
* LOG Format:
* --LEVEL_NOTE--\x7 [Y-m-d H:m:s]\x7 [FILE:LINE]\x7 [EXTRA_INFO]\x7 log_info
* // LEVEL_NOTE stands for one of DEBUG/TRACE/NOTICE...
* // \x7 is a special character to separate logged fields.
*
* Usage:
* //Open log file first. Supply a log file name.
* log_open("log.txt");
*
* //use it just as printf
* FM_LOG_TRACE("some info %d", 123);
*
* //6 level: DEBUG, TRACE, NOTICE, MONITOR, WARNING, FATAL
* FM_LOG_DEBUG("hi there");
*
* //Need EXTRA_INFO to be logged automatically?
* log_add_info("pid:123");
*
* //You don't need to call log_close manually, it'll be called at exit
* log_close();
*
*/
#ifndef __LOGGER__
#define __LOGGER__
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#include <error.h>
#include <sys/file.h>
int log_open(const char *filename);
void log_close();
static void log_write(int, const char *, const int, const char *, ...);
void log_add_info(const char *info);
const int LOG_FATAL = 0;
const int LOG_WARNING = 1;
const int LOG_MONITOR = 2;
const int LOG_NOTICE = 3;
const int LOG_TRACE = 4;
const int LOG_DEBUG = 5;
static char LOG_LEVEL_NOTE[][10] =
{ "FATAL", "WARNING", "MONITOR", "NOTICE", "TRACE", "DEBUG" };
#define FM_LOG_DEBUG(x...) log_write(LOG_DEBUG, __FILE__, __LINE__, ##x)
#define FM_LOG_TRACE(x...) log_write(LOG_TRACE, __FILE__, __LINE__, ##x)
#define FM_LOG_NOTICE(x...) log_write(LOG_NOTICE, __FILE__, __LINE__, ##x)
#define FM_LOG_MONITOR(x...) log_write(LOG_MONITOR, __FILE__ __LINE__, ##x)
#define FM_LOG_WARNING(x...) log_write(LOG_WARNING, __FILE__, __LINE__, ##x)
#define FM_LOG_FATAL(x...) log_write(LOG_FATAL, __FILE__, __LINE__, ##x)
static FILE *log_fp = NULL;
static char *log_filename = NULL;
static int log_opened = 0;
#define log_buffer_size 8192
static char log_buffer[log_buffer_size];
static char log_extra_info[log_buffer_size];
int log_open(const char* filename)
{
if (log_opened == 1)
{
fprintf(stderr, "logger: log already opened\n");
return 0;
}
int len = strlen(filename);
log_filename = (char *)malloc(sizeof(char) * len + 1);
strcpy(log_filename, filename);
log_fp = fopen(log_filename, "a");
if (log_fp == NULL)
{
fprintf(stderr, "log_file: %s", log_filename);
perror("can't not open log file");
exit(1);
}
atexit(log_close);
log_opened = 1;
log_extra_info[0] = 0;
FM_LOG_NOTICE("log_open");
return 1;
}
void log_close()
{
if (log_opened)
{
FM_LOG_TRACE("log_close");
fclose(log_fp);
free(log_filename);
log_fp = NULL;
log_filename = NULL;
log_opened = 0;
}
}
static void log_write(int level, const char *file,
const int line, const char *fmt, ...)
{
if (log_opened == 0)
{
fprintf(stderr, "log_open not called yet\n");
exit(1);
}
static char buffer[log_buffer_size];
static char datetime[100];
static char line_str[20];
static time_t now;
now = time(NULL);
strftime(datetime, 99, "%Y-%m-%d %H:%M:%S", localtime(&now));
snprintf(line_str, 19, "%d", line);
va_list ap;
va_start(ap, fmt);
vsnprintf(log_buffer, log_buffer_size, fmt, ap);
va_end(ap);
size_t count = snprintf(buffer, log_buffer_size,
"%s [%s] [%s:%d]%s %s\n",
LOG_LEVEL_NOTE[level], datetime, file, line, log_extra_info, log_buffer);
int log_fd = log_fp->_fileno;
//puts(buffer);
if (flock(log_fd, LOCK_EX) == 0)
{
if (write(log_fd, buffer, count) < 0)
{
perror("write error");
exit(1);
}
flock(log_fd, LOCK_UN);
}
else
{
perror("flock error");
exit(1);
}
}
void log_add_info(const char *info)
{
int len = strlen(log_extra_info);
snprintf(log_extra_info + len, log_buffer_size - len, "\n [%s]", info);
}
#endif