完善日志系统,修复读取配置文件时的内存泄漏,初步添加熔断机制与指数退避机制

This commit is contained in:
2025-10-11 16:57:27 +08:00
parent f518bf5064
commit 331c6b9f89
14 changed files with 104 additions and 43 deletions

View File

@ -4,7 +4,7 @@ project (Onebot_back C)
add_executable(Start_Onebot_back main.c tem/ctl.c) add_executable(Start_Onebot_back main.c tem/ctl.c)
add_executable(Run_pluginmanager run_pluginmanager/run_pluginmanager.c) add_executable(Run_pluginmanager run_pluginmanager/run_pluginmanager.c)
add_library(Network SHARED network/network.c network/swap.c network/cJSON.c network/http_rel.c) add_library(Network SHARED network/network.c network/swap.c network/cJSON.c network/http/http_rel.c network/erroprocess/erroprocess.c)
add_library(Swmem SHARED network/swap.c) add_library(Swmem SHARED network/swap.c)
add_library(Interpre SHARED interpreter/interpreter.c tools/pkgmanager/pkginstall.c) add_library(Interpre SHARED interpreter/interpreter.c tools/pkgmanager/pkginstall.c)
add_library(Log SHARED tools/log/log.c) add_library(Log SHARED tools/log/log.c)

View File

@ -9,12 +9,24 @@
#include "interpreter.h" #include "interpreter.h"
#include "tools/pkgmanager/pkginstall.h" #include "tools/pkgmanager/pkginstall.h"
int inter_in_log(const char *log,log_manager *manager)
{
if(strlen(log)>1024)
return -1;
logs* logss = (logs*)malloc(sizeof(logs));
memcpy(logss->log,log,strlen(log));
manager->in_log(logss,manager);
return 0;
}
int init_interpreter(Cmd *cmd_dic,ctx *self,int fifo[2]) int init_interpreter(Cmd *cmd_dic,ctx *self,int fifo[2],log_manager *log_manager)
{ {
printf("SYS:prepare env\n"); printf("SYS:prepare env\n");
inter_in_log("SYS:prepare env\n",log_manager);
printf("SYS:env ready\n"); printf("SYS:env ready\n");
inter_in_log("SYS:env ready\n",log_manager);
printf("SYS:loading cmd_dic\n"); printf("SYS:loading cmd_dic\n");
inter_in_log("SYS:loading cmd_dic\n",log_manager);
sprintf(cmd_dic[0].name, "pkginstall"); sprintf(cmd_dic[0].name, "pkginstall");
cmd_dic[0].cmd = INSTALL; cmd_dic[0].cmd = INSTALL;
@ -25,6 +37,7 @@ int init_interpreter(Cmd *cmd_dic,ctx *self,int fifo[2])
cmd_dic[2].cmd = QUIT; cmd_dic[2].cmd = QUIT;
printf("SYS:cmd_dir load complite\n"); printf("SYS:cmd_dir load complite\n");
inter_in_log("SYS:cmd_dir load complite\n",log_manager);
for(int i =0;i<10;i++) for(int i =0;i<10;i++)
{ {
@ -32,8 +45,9 @@ int init_interpreter(Cmd *cmd_dic,ctx *self,int fifo[2])
} }
self->arg = NULL; self->arg = NULL;
printf("SYS:Creating ctl fifo\n"); printf("SYS:Creating ctl fifo\n");
inter_in_log("SYS:Creating ctl fifo\n",log_manager);
memcpy(self->fifofd,fifo,2*sizeof(int)); memcpy(self->fifofd,fifo,2*sizeof(int));
self->log_manager = log_manager;
} }
int get_args(ctx *self) int get_args(ctx *self)
@ -57,6 +71,7 @@ int get_args(ctx *self)
arg->next = (args*)malloc(sizeof(args)); arg->next = (args*)malloc(sizeof(args));
if(arg->next == NULL){ if(arg->next == NULL){
perror("ERROR:fail to get mem"); perror("ERROR:fail to get mem");
inter_in_log("ERROR:fail to get mem\n",self->log_manager);
return -1; return -1;
} }
arg = arg->next; arg = arg->next;
@ -131,25 +146,31 @@ int exce(const int command,ctx *all_ctx)
{ {
case BAD_INPUT: case BAD_INPUT:
printf("SYS:bad input,try again\n"); printf("SYS:bad input,try again\n");
inter_in_log("SYS:bad input,try again\n",all_ctx->log_manager);
return BAD_INPUT; return BAD_INPUT;
case INSTALL: case INSTALL:
if(all_ctx->arg == NULL){ if(all_ctx->arg == NULL){
printf("SYS:Missing args\n"); printf("SYS:Missing args\n");
inter_in_log("SYS:Missng args\n",all_ctx->log_manager);
return 1; return 1;
} }
printf("SYS:init pkgmanager\n"); printf("SYS:init pkgmanager\n");
inter_in_log("SYS:init pkgmanager\n",all_ctx->log_manager);
pkger *manager = init_pkginstaller(); pkger *manager = init_pkginstaller();
printf("SYS:installing\n"); printf("SYS:installing\n");
inter_in_log("SYS:installing\n",all_ctx->log_manager);
manager->packup(manager); manager->packup(manager);
return 1; return 1;
case RUN: case RUN:
printf("SYS:runing\n"); printf("SYS:runing\n");
inter_in_log("SYS:running\n",all_ctx->log_manager);
return 1; return 1;
case QUIT: case QUIT:
printf("SYS:shuting down\n"); printf("SYS:shuting down\n");
inter_in_log("SYS:shuting down\n",all_ctx->log_manager);
all_ctx->statue = -1; all_ctx->statue = -1;
write(all_ctx->fifofd[1],"q",1); write(all_ctx->fifofd[1],"q",1);
return 1; return 1;

View File

@ -6,6 +6,8 @@
#define SIG_MOD 0 #define SIG_MOD 0
#define FILE_MOD 1 #define FILE_MOD 1
#include "tools/log/log.h"
typedef struct typedef struct
{ {
char name[256]; char name[256];
@ -38,11 +40,12 @@ typedef struct ctx
char command[MAX_BUF];//当前行缓存 char command[MAX_BUF];//当前行缓存
int statue;//当前状态 int statue;//当前状态
int fifofd[2]; int fifofd[2];
log_manager *log_manager;
}ctx;//上下文管理 }ctx;//上下文管理
int interpret(int mod, ctx *all_ctx,Cmd *cmd_dic); int interpret(int mod, ctx *all_ctx,Cmd *cmd_dic);
int init_interpreter(Cmd *cmd_dic,ctx *self,int fifo[2]); int init_interpreter(Cmd *cmd_dic,ctx *self,int fifo[2],log_manager *log_manager);
#define ARG_LENGTH 256 #define ARG_LENGTH 256

View File

@ -37,6 +37,7 @@ int main()
init_loger(logsmanager); init_loger(logsmanager);
Ctl *teml = init_tem(logsmanager); Ctl *teml = init_tem(logsmanager);
teml->config = server;
//初始化终端对象 //初始化终端对象
int fifo[2]; int fifo[2];
if(pipe(fifo)==-1) if(pipe(fifo)==-1)

View File

@ -6,6 +6,11 @@ int give_upjobs(indiector *self)
{ {
if(self == NULL) if(self == NULL)
{ {
return -1;
} }
}
int init_indector(indiector *self)
{
} }

View File

@ -1,5 +1,10 @@
#ifndef ERROPROCESS #ifndef ERROPROCESS
#define EROPROCESS #define ERROPROCESS
#define BASE_INDIECTOR 2
#define MAX_index 5
#define CIR_TIME 20
typedef struct jobs typedef struct jobs
{ {
struct jobs* next; struct jobs* next;
@ -13,8 +18,7 @@ typedef struct indiector
int retreat_index;//退避指数 int retreat_index;//退避指数
jobs *head_job; jobs *head_job;
jobs *rear_job; jobs *rear_job;
int (*give_upjobs)(struct indiector *);
}indiector; }indiector;
int give_upjobs(indiector *self);
#endif #endif

View File

@ -2,14 +2,16 @@
#include "network.h" #include "network.h"
#include "swap.h" #include "swap.h"
#include "http_rel.h" #include "http/http_rel.h"
#include "cJSON.h" #include "cJSON.h"
#include "tools/log/log.h" #include "tools/log/log.h"
#include "tools/quit/quit.h" #include "tools/quit/quit.h"
#include "erroprocess/erroprocess.h"
#include <semaphore.h> #include <semaphore.h>
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <fcntl.h>
#include <string.h> #include <string.h>
#include <stddef.h> #include <stddef.h>
#include <errno.h> #include <errno.h>
@ -75,9 +77,10 @@ int rbt_parse_json(const char *json_text, rbt_msg *out)
return 0; // 成功 return 0; // 成功
} }
int init_network(int port) int init_http_network(int port)
{ {
int fd = socket(AF_INET, SOCK_STREAM, 0); int fd = socket(AF_INET, SOCK_STREAM, 0);
fcntl(fd, F_GETFL);
struct sockaddr_in addr = {0}; struct sockaddr_in addr = {0};
addr.sin_family = AF_INET; // 和 socket() 一致 addr.sin_family = AF_INET; // 和 socket() 一致
addr.sin_port = htons(port); // 端口号必须网络字节序 addr.sin_port = htons(port); // 端口号必须网络字节序
@ -92,7 +95,7 @@ ssize_t read_req(int fd, void *buf)
// TODO 修改读取任务函数 // TODO 修改读取任务函数
ssize_t n = read(fd, buf, MAX_MESSAGE_BUF); ssize_t n = read(fd, buf, MAX_MESSAGE_BUF);
if (n == 0) /* 写端已关闭,管道永不会再有数据 */ if (n == 0) /* 写端已关闭,管道永不会再有数据 */
return -1; return 0;
return (n > 0) ? n : -1; return (n > 0) ? n : -1;
} }
@ -163,7 +166,7 @@ void *pth_module(void *args_p)
for(;;){ for(;;){
//线程池中,单个线程模型 //线程池中,单个线程模型
char req[64*1024]; char req[64];
//从管道中读取请求,并解析,无内容时休眠 //从管道中读取请求,并解析,无内容时休眠
int n = read_req(pmd->fifo_fd[0],req); int n = read_req(pmd->fifo_fd[0],req);
//管道关闭时退出; //管道关闭时退出;
@ -219,43 +222,48 @@ int server_run(int port,int fifo_fd,netm *self)
ev.data.fd = fifo_fd; ev.data.fd = fifo_fd;
epoll_ctl(epfd, EPOLL_CTL_ADD, fifo_fd, &ev); epoll_ctl(epfd, EPOLL_CTL_ADD, fifo_fd, &ev);
char iss_buf[256]; char iss_buf[256];
self->http_fd = init_network(port); self->http_fd = init_http_network(port);
ev.data.fd = self->http_fd; ev.data.fd = self->http_fd;
epoll_ctl(epfd, EPOLL_CTL_ADD, self->http_fd, &ev); epoll_ctl(epfd, EPOLL_CTL_ADD, self->http_fd, &ev);
struct epoll_event events; struct epoll_event events[10];
self->epoll_fd = epfd; self->epoll_fd = epfd;
for(;;) for(;;)
{ {
/*工作循环-----------------------------*/ /*工作循环-----------------------------*/
int nf = epoll_wait(epfd,&events,1,-1); int nf = epoll_wait(epfd,events,10,-1);
printf("%d\n",nf);
if (nf == -1) { if (nf == -1) {
perror("epoll_wait"); perror("epoll_wait");
break; break;
} }
if(events.data.fd ==self->http_fd) for(int i = 0; i<nf;i++){
{
int nt_fd = accept4(self->http_fd,NULL,NULL,SOCK_NONBLOCK | SOCK_CLOEXEC);
if(nt_fd == -1)
continue;
sprintf(iss_buf,"s/%d/e",nt_fd);
self->iss_work(self,iss_buf);
}
if(events.data.fd == fifo_fd)
{
char command;
while(read(fifo_fd,&command,1)==1)
{
switch(command){
case 'q':
//退出逻辑
quit_server(self);
return 1;
break;
case 'u':
//插件更新逻辑
break; if(events[i].data.fd ==self->http_fd)
{
int nt_fd = accept4(self->http_fd,NULL,NULL,SOCK_NONBLOCK | SOCK_CLOEXEC);
printf("%d\n",nt_fd);
if(nt_fd == -1)
continue;
sprintf(iss_buf,"s/%d/e",nt_fd);
self->iss_work(self,iss_buf);
}
if(events[i].data.fd == fifo_fd)
{
char command;
while(read(fifo_fd,&command,1)==1)
{
switch(command){
case 'q':
//退出逻辑
quit_server(self);
return 1;
break;
case 'u':
//插件更新逻辑
break;
}
} }
} }
} }
@ -283,5 +291,6 @@ int init_networkmanager(netm *self,int *fifo,log_manager *logmanager,int port)
self->last_alc = 0; self->last_alc = 0;
//初始化参数 //初始化参数
self->logmanager = logmanager; self->logmanager = logmanager;
self->err_indictor = (indiector*)malloc(sizeof(indiector));
self->port = port; self->port = port;
} }

View File

@ -4,7 +4,8 @@
#define MAX_POOL 10 #define MAX_POOL 10
#define MAX_MESSAGE_BUF 10240 #define MAX_MESSAGE_BUF 10240
#include <pthread.h> #include <pthread.h>
#include<tools/log/log.h> #include "tools/log/log.h"
#include "erroprocess/erroprocess.h"
#include <stdatomic.h> #include <stdatomic.h>
//单个线程模型 //单个线程模型
typedef struct pthread_module typedef struct pthread_module
@ -29,6 +30,7 @@ typedef struct network_manager
pth_m pool[MAX_POOL]; pth_m pool[MAX_POOL];
int fifo_fd[2]; int fifo_fd[2];
log_manager *logmanager; log_manager *logmanager;
indiector *err_indictor;
int last_alc; int last_alc;
int port; int port;
int epoll_fd; int epoll_fd;

View File

@ -235,7 +235,7 @@ int teml(Ctl *self,int fifo[2])
char input[MAX_BUF] = {'\0'}; char input[MAX_BUF] = {'\0'};
ctx *command = (ctx*)malloc(sizeof(ctx)); ctx *command = (ctx*)malloc(sizeof(ctx));
Cmd cmd_dir[10]; Cmd cmd_dir[10];
init_interpreter(cmd_dir,command,fifo);//初始化解释器 init_interpreter(cmd_dir,command,fifo,self->logmanager);//初始化解释器
//创建线程用于定期清理日志 //创建线程用于定期清理日志
pthread_create(&self->logwathcher,NULL,self->logmanager->clear_log,self->logmanager); pthread_create(&self->logwathcher,NULL,self->logmanager->clear_log,self->logmanager);
command->statue = 0; command->statue = 0;
@ -248,6 +248,9 @@ int teml(Ctl *self,int fifo[2])
perror("sys error"); perror("sys error");
//将用户输入入队 //将用户输入入队
infifo(self,input); infifo(self,input);
logs *log = (logs*)malloc(sizeof(logs));
memcpy(log->log,input,sizeof(input));
self->logmanager->in_log(log,self->logmanager);
memcpy(command->command,input,sizeof(input)); memcpy(command->command,input,sizeof(input));
interpret(SIG_MOD,command,cmd_dir); interpret(SIG_MOD,command,cmd_dir);
const char fexp[256] = {'\0'}; const char fexp[256] = {'\0'};

View File

@ -2,6 +2,7 @@
#define CTL #define CTL
#include <pthread.h> #include <pthread.h>
#include "tools/toml/toml.h"
#include "tools/log/log.h" #include "tools/log/log.h"
#include "interpreter/interpreter.h" #include "interpreter/interpreter.h"
@ -19,6 +20,7 @@ typedef struct Ctl
pthread_t logwathcher; pthread_t logwathcher;
log_manager *logmanager; log_manager *logmanager;
ctx *command;//解释器上下文 ctx *command;//解释器上下文
toml_table_t *config;
}Ctl; }Ctl;
Ctl *init_tem(log_manager *logmanager); Ctl *init_tem(log_manager *logmanager);

View File

@ -6,6 +6,8 @@
#include <unistd.h> #include <unistd.h>
#include <time.h> #include <time.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h>
#include <string.h>
int in_log(logs *log,log_manager *self) int in_log(logs *log,log_manager *self)
{ {
@ -81,15 +83,21 @@ int cleanup(log_manager *self)
if(self->log ==NULL) if(self->log ==NULL)
return 1; return 1;
logs *tobeclean,*loc; logs *tobeclean,*loc;
sem_wait(&self->log_sem); sem_wait(&self->log_sem);//获取信号量
loc = self->log; loc = self->log;
self->log = NULL; self->log = NULL;
self->count = 0; self->count = 0;//摘取log链
sem_post(&self->log_sem); sem_post(&self->log_sem);
//释放信号量
while(loc->next !=NULL) while(loc->next !=NULL)
{ {
tobeclean = loc; tobeclean = loc;
loc = loc->next; loc = loc->next;
int fd = open("log.txt",O_CREAT | O_WRONLY | O_APPEND, 0777);
if(fd == -1)
perror("file:");
write(fd,loc->log,strlen(loc->log));
close(fd);
free(tobeclean); free(tobeclean);
} }
free(loc); free(loc);

View File

@ -9,6 +9,7 @@
#include <sys/epoll.h> #include <sys/epoll.h>
#include "quit.h" #include "quit.h"
#include "tem/ctl.h" #include "tem/ctl.h"
#include "tools/toml/toml.h"
int quit_server(netm *self) int quit_server(netm *self)
{ {
@ -33,6 +34,7 @@ int quit_server(netm *self)
self->fifo_fd[0] = -1; self->fifo_fd[0] = -1;
} }
//关闭管道监听 //关闭管道监听
} }
void quit_all(int status,void *self_p) void quit_all(int status,void *self_p)
@ -63,6 +65,7 @@ void quit_all(int status,void *self_p)
free(arg); free(arg);
} }
} }
toml_free(resouce->tem->config);
free(resouce->tem->command); free(resouce->tem->command);
} }
//释放终端资源 //释放终端资源