chore: add core server infrastructure with config, logging, and server modules
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
#include "logging.h"
|
||||
#include "../platform/memory.h"
|
||||
#include <string.h>
|
||||
|
||||
logger_t *g_logger = NULL;
|
||||
|
||||
struct logger {
|
||||
FILE *file;
|
||||
FILE *access_file;
|
||||
log_level_t level;
|
||||
mutex_t mutex;
|
||||
char file_path[PATH_MAX];
|
||||
size_t max_size;
|
||||
int rotate_count;
|
||||
};
|
||||
|
||||
static const char *level_names[] = {
|
||||
"TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"
|
||||
};
|
||||
|
||||
logger_t *logger_create(const char *file_path, log_level_t level) {
|
||||
logger_t *log = calloc(1, sizeof(logger_t));
|
||||
if (!log) return NULL;
|
||||
|
||||
log->level = level;
|
||||
log->max_size = 100 * 1024 * 1024;
|
||||
log->rotate_count = 10;
|
||||
|
||||
if (pal_mutex_init(&log->mutex) != NWEDAV_OK) {
|
||||
free(log);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (file_path && file_path[0]) {
|
||||
strncpy(log->file_path, file_path, sizeof(log->file_path) - 1);
|
||||
log->file = fopen(file_path, "a");
|
||||
}
|
||||
|
||||
if (!log->file) {
|
||||
log->file = stderr;
|
||||
}
|
||||
|
||||
return log;
|
||||
}
|
||||
|
||||
void logger_destroy(logger_t *log) {
|
||||
if (!log) return;
|
||||
|
||||
pal_mutex_lock(&log->mutex);
|
||||
if (log->file && log->file != stderr && log->file != stdout) {
|
||||
fclose(log->file);
|
||||
}
|
||||
if (log->access_file && log->access_file != stderr && log->access_file != stdout) {
|
||||
fclose(log->access_file);
|
||||
}
|
||||
pal_mutex_unlock(&log->mutex);
|
||||
pal_mutex_destroy(&log->mutex);
|
||||
free(log);
|
||||
}
|
||||
|
||||
void logger_set_level(logger_t *log, log_level_t level) {
|
||||
if (log) {
|
||||
log->level = level;
|
||||
}
|
||||
}
|
||||
|
||||
void logger_log(logger_t *log, log_level_t level, const char *file, int line, const char *fmt, ...) {
|
||||
if (!log || level < log->level) return;
|
||||
|
||||
pal_mutex_lock(&log->mutex);
|
||||
|
||||
time_t now = time(NULL);
|
||||
struct tm *tm = localtime(&now);
|
||||
char timestamp[32];
|
||||
strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", tm);
|
||||
|
||||
const char *basename = file;
|
||||
const char *p = strrchr(file, '/');
|
||||
if (p) basename = p + 1;
|
||||
#ifdef _WIN32
|
||||
p = strrchr(basename, '\\');
|
||||
if (p) basename = p + 1;
|
||||
#endif
|
||||
|
||||
fprintf(log->file, "[%s] [%s] [%s:%d] ",
|
||||
timestamp, level_names[level], basename, line);
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vfprintf(log->file, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
fprintf(log->file, "\n");
|
||||
fflush(log->file);
|
||||
|
||||
pal_mutex_unlock(&log->mutex);
|
||||
}
|
||||
|
||||
void logger_access(logger_t *log, const char *client_ip, const char *method,
|
||||
const char *uri, int status, size_t bytes, const char *user_agent) {
|
||||
if (!log) return;
|
||||
|
||||
FILE *out = log->access_file ? log->access_file : log->file;
|
||||
|
||||
pal_mutex_lock(&log->mutex);
|
||||
|
||||
time_t now = time(NULL);
|
||||
struct tm *tm = localtime(&now);
|
||||
char timestamp[64];
|
||||
strftime(timestamp, sizeof(timestamp), "%d/%b/%Y:%H:%M:%S %z", tm);
|
||||
|
||||
fprintf(out, "%s - - [%s] \"%s %s HTTP/1.1\" %d %zu \"-\" \"%s\"\n",
|
||||
client_ip ? client_ip : "-",
|
||||
timestamp,
|
||||
method ? method : "-",
|
||||
uri ? uri : "-",
|
||||
status,
|
||||
bytes,
|
||||
user_agent ? user_agent : "-");
|
||||
|
||||
fflush(out);
|
||||
pal_mutex_unlock(&log->mutex);
|
||||
}
|
||||
Reference in New Issue
Block a user