一个简单的缓冲区日志系统实现

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <time.h>

#include <pthread.h>

#include <stdarg.h>

#include <arpa/inet.h>

#define LOG_BUFFER_SIZE (10 * 1024)

#define LOG_LINE_SIZE 256

// 定义日志优先级

typedef enum {

LOG_EMERG, // 0: system is unusable

LOG_ALERT, // 1: action must be taken immediately

LOG_CRIT, // 2: critical conditions

LOG_ERR, // 3: error conditions

LOG_WARNING, // 4: warning conditions

LOG_NOTICE, // 5: normal but significant condition

LOG_INFO, // 6: informational

LOG_DEBUG // 7: debug-level messages

} LogLevel;

// 日志条目结构

typedef struct {

LogLevel level;

char module[LOG_LINE_SIZE];

char message[LOG_LINE_SIZE];

struct in_addr src_ip;

struct in_addr dst_ip;

unsigned short src_port;

unsigned short dst_port;

unsigned char protocol;

} LogEntry;

// 日志模块配置

typedef struct {

int dp_debug_cli;

int dp_debug_ha;

int dp_debug_lookup;

int dp_debug_mcast;

int dp_debug_route;

int dp_debug_session;

} LogConfig;

// 全局日志缓冲区

LogEntry log_buffer[LOG_BUFFER_SIZE];

int log_index = 0;

pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER;

// 模块日志配置

LogConfig log_config = {1, 1, 1, 1, 1, 1}; // 默认打开所有模块的日志

// 报文五元组过滤条件

typedef struct {

struct in_addr src_ip;

struct in_addr dst_ip;

unsigned short src_port;

unsigned short dst_port;

unsigned char protocol;

int enabled;

} FilterConfig;

FilterConfig filter_config = { {0}, {0}, 0, 0, 0, 0 }; // 默认关闭五元组过滤

// 添加日志条目

void add_log(LogLevel level, const char* module, struct in_addr src_ip, struct in_addr dst_ip,

unsigned short src_port, unsigned short dst_port, unsigned char protocol, const char* format, ...) {

pthread_mutex_lock(&log_mutex);

// 检查缓冲区是否已满

if (log_index >= LOG_BUFFER_SIZE) {

pthread_mutex_unlock(&log_mutex);

return;

}

// 检查模块是否启用日志

if ((strcmp(module, "cli") == 0 && !log_config.dp_debug_cli) ||

(strcmp(module, "ha") == 0 && !log_config.dp_debug_ha) ||

(strcmp(module, "lookup") == 0 && !log_config.dp_debug_lookup) ||

(strcmp(module, "mcast") == 0 && !log_config.dp_debug_mcast) ||

(strcmp(module, "route") == 0 && !log_config.dp_debug_route) ||

(strcmp(module, "session") == 0 && !log_config.dp_debug_session)) {

pthread_mutex_unlock(&log_mutex);

return;

}

// 检查报文五元组过滤条件

if (filter_config.enabled) {

if ((filter_config.src_ip.s_addr && filter_config.src_ip.s_addr != src_ip.s_addr) ||

(filter_config.dst_ip.s_addr && filter_config.dst_ip.s_addr != dst_ip.s_addr) ||

(filter_config.src_port && filter_config.src_port != src_port) ||

(filter_config.dst_port && filter_config.dst_port != dst_port) ||

(filter_config.protocol && filter_config.protocol != protocol)) {

pthread_mutex_unlock(&log_mutex);

return;

}

}

va_list args;

va_start(args, format);

time_t now;

time(&now);

struct tm *local = localtime(&now);

char timestamp[20];

strftime(timestamp, 20, "%Y-%m-%d %H:%M:%S", local);

LogEntry* entry = &log_buffer[log_index % LOG_BUFFER_SIZE];

entry->level = level;

snprintf(entry->module, LOG_LINE_SIZE, "%s", module);

snprintf(entry->message, LOG_LINE_SIZE, "[%s] %s: ", timestamp, module);

vsnprintf(entry->message + strlen(entry->message), LOG_LINE_SIZE - strlen(entry->message), format, args);

entry->src_ip = src_ip;

entry->dst_ip = dst_ip;

entry->src_port = src_port;

entry->dst_port = dst_port;

entry->protocol = protocol;

log_index++;

va_end(args);

pthread_mutex_unlock(&log_mutex);

}

// 打印日志缓冲区

void print_logs(const char* module_filter, LogLevel level_filter) {

pthread_mutex_lock(&log_mutex);

for (int i = 0; i < log_index && i < LOG_BUFFER_SIZE; i++) {

LogEntry* entry = &log_buffer[i];

if ((module_filter == NULL || strcmp(entry->module, module_filter) == 0) &&

entry->level <= level_filter) {

printf("Level %d: %s\n", entry->level, entry->message);

}

}

pthread_mutex_unlock(&log_mutex);

}

// 清空日志缓冲区

void clear_logs() {

pthread_mutex_lock(&log_mutex);

log_index = 0;

pthread_mutex_unlock(&log_mutex);

}

// 设置模块日志配置

void set_log_config(const char* module, int enabled) {

pthread_mutex_lock(&log_mutex);

if (strcmp(module, "cli") == 0) {

log_config.dp_debug_cli = enabled;

} else if (strcmp(module, "ha") == 0) {

log_config.dp_debug_ha = enabled;

} else if (strcmp(module, "lookup") == 0) {

log_config.dp_debug_lookup = enabled;

} else if (strcmp(module, "mcast") == 0) {

log_config.dp_debug_mcast = enabled;

} else if (strcmp(module, "route") == 0) {

log_config.dp_debug_route = enabled;

} else if (strcmp(module, "session") == 0) {

log_config.dp_debug_session = enabled;

}

pthread_mutex_unlock(&log_mutex);

}

// 设置五元组过滤配置

void set_filter_config(struct in_addr src_ip, struct in_addr dst_ip,

unsigned short src_port, unsigned short dst_port,

unsigned char protocol, int enabled) {

pthread_mutex_lock(&log_mutex);

filter_config.src_ip = src_ip;

filter_config.dst_ip = dst_ip;

filter_config.src_port = src_port;

filter_config.dst_port = dst_port;

filter_config.protocol = protocol;

filter_config.enabled = enabled;

pthread_mutex_unlock(&log_mutex);

}

// 简单的CLI处理函数

void process_cli_command(const char* command) {

if (strncmp(command, "enable ", 7) == 0) {

const char* module = command + 7;

set_log_config(module, 1);

printf("%s logging enabled.\n", module);

} else if (strncmp(command, "disable ", 8) == 0) {

const char* module = command + 8;

set_log_config(module, 0);

printf("%s logging disabled.\n", module);

} else if (strncmp(command, "print ", 6) == 0) {

const char* args = command + 6;

char module[20];

int level;

if (sscanf(args, "%s %d", module, &level) == 2) {

print_logs(module, level);

} else {

printf("Invalid print command format. Use: print <module> <level>\n");

}

} else if (strcmp(command, "clear") == 0) {

clear_logs();

printf("Log buffer cleared.\n");

} else if (strncmp(command, "filter ", 7) == 0) {

const char* args = command + 7;

char src_ip_str[INET_ADDRSTRLEN], dst_ip_str[INET_ADDRSTRLEN];

unsigned short src_port, dst_port;

unsigned char protocol;

int enabled;

if (sscanf(args, "%s %s %hu %hu %hhu %d", src_ip_str, dst_ip_str, &src_port, &dst_port, &protocol, &enabled) == 6) {

struct in_addr src_ip, dst_ip;

inet_pton(AF_INET, src_ip_str, &src_ip);

inet_pton(AF_INET, dst_ip_str, &dst_ip);

set_filter_config(src_ip, dst_ip, src_port, dst_port, protocol, enabled);

printf("Filter set to src_ip=%s, dst_ip=%s, src_port=%hu, dst_port=%hu, protocol=%hhu, enabled=%d\n",

src_ip_str, dst_ip_str, src_port, dst_port, protocol, enabled);

} else {

printf("Invalid filter command format. Use: filter <src_ip> <dst_ip> <src_port><dst_port><protocol>\n");

} else {

printf("Unknown command.\n");

}

}

// 会话模块示例

void session_start(int session_id) {

add_log(LOG_INFO, "session", "Session started with ID %d", session_id);

}

void session_end(int session_id) {

add_log(LOG_INFO, "session", "Session ended with ID %d", session_id);

}

int main() {

// 添加一些日志示例

add_log(LOG_INFO, "session", "Session started with ID %d", 12345);

add_log(LOG_ERR, "protocol", "Protocol error: %s", "Invalid header");

add_log(LOG_DEBUG, "ddos", "DDoS detection algorithm initialized");

// 会话模块日志示例

session_start(1001);

session_end(1001);

// 模拟CLI输入

process_cli_command("disable session");

session_start(1002); // This log should not appear

process_cli_command("print session 6");

process_cli_command("enable session");

session_start(1003); // This log should appear

process_cli_command("print session 6");

// 清空日志缓冲区

process_cli_command("clear");

process_cli_command("print session 6");

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值