-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlog.hpp
More file actions
116 lines (100 loc) · 3.06 KB
/
log.hpp
File metadata and controls
116 lines (100 loc) · 3.06 KB
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
/**
* @file log.hpp
* @brief Simple file-based logger. Writes timestamped entries to logs/server.log.
* Log levels: DEBUG(0), NORMAL(1), WARNING(2), ERROR(3), FATAL(4).
*
* CSCI 599: Network Systems for Cloud Computing
* University of Southern California
*/
#ifndef __LOG_HPP__
#define __LOG_HPP__
// 日志是有日志级别的
// 不同的级别代表不同的响应方式
#define DEBUG 0
#define NORMAL 1 // 正常的
#define WARNING 2 // 警告
#define ERROR 3 // 错误
#define FATAL 4 // 致命的
#include <assert.h>
#include <chrono>
#include <iostream>
#include <stdarg.h>
#include <stdio.h>
#include <string>
#include <time.h>
// 完整的日志功能
// 至少:日志等级、时间、内容、支持用户自定义
const char* gLevelMap[] = {
"DEBUG",
"NORMAL",
"WARNING",
"ERROR",
"FATAL"
};
#define __REQUEST_LOG__ "./logs/requests.log"
#define __LOGBEGIN__ 1
#define __LOGEND__ 0
// Global log path — set once at startup via SetLogPath() before any logging.
static std::string g_log_path = "./logs/server.log";
void SetLogPath(const std::string& path) {
g_log_path = path;
}
void InitLogFile(int option) {
FILE* fp = fopen(g_log_path.c_str(), "a");
FILE* fp_r = fopen(__REQUEST_LOG__, "a");
if (option == __LOGBEGIN__) {
auto start_time = std::chrono::system_clock::now();
std::time_t start_time_t = std::chrono::system_clock::to_time_t(start_time);
std::string prompt = "Process started at: ";
std::string timeLine = std::ctime(&start_time_t);
std::string logLine = prompt + timeLine;
fprintf(fp, "%s\n", logLine.c_str());
fprintf(fp_r, "%s\n", logLine.c_str());
} else if (option == __LOGEND__) {
fprintf(fp, "\n\n");
fprintf(fp_r, "\n\n");
} else
assert(false);
fflush(fp);
fflush(fp_r);
fclose(fp);
fclose(fp_r);
}
void logMessage(int level, const char* format, ...) {
#ifdef __DEBUG_SHOW
if (level == DEBUG)
return;
#else
// va_list ap; //va_list -> char*
// va_start(ap, format);
// while()
// int x = va_arg(ap, int);
// va_end(ap);
char stdBuffer[1024]; // 标准部分
time_t timestamp = time(nullptr);
// struct tm *tmlocaltime = localtime(×tamp);
// ...
snprintf(stdBuffer, sizeof stdBuffer, "[%s] [%ld] ", gLevelMap[level], timestamp);
char logBuffer[1024]; // 自定义部分
va_list args;
va_start(args, format); // 初始化一下
// vprintf(format, args); //格式化到stdout中
vsnprintf(logBuffer, sizeof logBuffer, format, args); // 可以直接格式化到字符串中
// 这样v开头的函数有4个,要用的话可以man一下
// printf("%s", logBuffer);
va_end(args);
#endif
FILE* fp = fopen(g_log_path.c_str(), "a");
fprintf(stdout, "%s%s\n", stdBuffer, logBuffer);
fflush(stdout);
fprintf(fp, "%s%s\n", stdBuffer, logBuffer);
fflush(fp);
fclose(fp);
}
void logRequest(const char* request) {
FILE* fp = fopen(__REQUEST_LOG__, "a");
fprintf(fp, "%s", request);
fflush(fp);
fclose(fp);
}
#endif