secgateway/Platform/user/ulog/log-sched/log_remote.c

386 lines
13 KiB
C
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <syslog.h>
#include "log_remote.h"
#include "log_common.h"
#include "ulog_in.h"
#include "rpc_conn.h"
#define LOG_CONF_REMOTE_FILE_NAME "log-remote.conf"
#define RESET_SEEK(fp) fseek(fp, 0, SEEK_SET)
#define LOG_CONF_KEY_REMOTE_LEVEL "remote.level"
typedef enum {
LOG_REMOTE_OP_ADD = 0,
LOG_REMOTE_OP_DEL,
LOG_REMOTE_MAX
} log_op_t;
typedef int (*op_func)(const log_remote_host_t *conf);
static int add_remote_host(const log_remote_host_t *conf);
static int del_remote_host(const log_remote_host_t *conf);
static op_func remote_funcs[] = {
add_remote_host,
del_remote_host
};
static int match_remote_config(const char *line, const void *src)
{
char text_level[MAX_LINE_SZ + 1], old_redirect[MAX_LINE_SZ + 1];
int n;
ULOG_DEBUG(g_log, "The line:%s will be matched", line);
n = sscanf(line, "%1024s"REDIRECT_SEPERATE"%1024s", text_level, old_redirect);
if (n == 2) {
// 匹配到
// 是否相同配置判读
ULOG_DEBUG(g_log, "%s will compare with %s", old_redirect, (const char *)src);
if (strcmp(old_redirect, src) == 0) {
return 0;
}
} else if (n == EOF) {
// 错误发生
ULOG_ERR(g_log, "Parsing remote line is failure:%s", strerror(errno));
return -1;
} else {
// 未能识别行
ULOG_DEBUG(g_log, "The line:%s can't be parsed", line);
}
return 1;
}
static int remote_conf_content(FILE *fp, const u8 level, const char *filter_mod,
int (*match_cb)(const char *line, const void *src),
int (*final_cb)(FILE *fp, const u8 level, const char *filter_mod, void *arg),
void *arg)
{
int ret = -1;
FILE *bak_fp = NULL;
char path[MAX_PATH_SZ];
char *line = NULL;
snprintf(path, sizeof(path), BAK_FILE, LOG_CONF_REMOTE_FILE_NAME);
bak_fp = fopen(path, "r");
if (bak_fp == NULL) {
if (errno == ENOENT) {
goto FINAL_PHASE;
} else {
ULOG_ERR(g_log, "Opening remote backup file:%s is failure:%s", path, strerror(errno));
return -1;
}
}
ssize_t n, n1;
while ((n = getline(&line, &n, bak_fp)) != -1) {
int match = match_cb(line, arg);
if (match == -1) {
ULOG_ERR(g_log, "Configuration which is matched is failure");
} else if (match == 0) {
ULOG_DEBUG(g_log, "Be matched");
continue;
} else {
ULOG_DEBUG(g_log, "Not be matched");
}
ULOG_DEBUG(g_log, "Recover old line:%s to file:%s", line, path);
n1 = fwrite(line, 1, n, fp);
if (n != n1) {
ULOG_ERR(g_log, "Recovering old line:%s to file is failure:%s", line, strerror(errno));
goto END;
}
}
FINAL_PHASE:
if (final_cb != NULL) {
if (final_cb(fp, level, filter_mod, arg) != 0) {
ULOG_ERR(g_log, "Executing final callback is failure");
goto END;
}
}
ret = 0;
END:
if (line != NULL) {
free(line);
}
if (bak_fp != NULL) {
fclose(bak_fp);
}
return ret;
}
static int remote_conf_level_content(FILE *fp, const u8 level)
{
int ret = -1;
FILE *bak_fp = NULL;
char path[MAX_PATH_SZ];
if (snprintf(path, sizeof(path), BAK_FILE, LOG_CONF_REMOTE_FILE_NAME) < 0) {
ULOG_DEBUG(g_log, "[remote-level]:Buildbackup path(%s) is failure", BAK_FILE, LOG_CONF_REMOTE_FILE_NAME);
return -1;
}
bak_fp = fopen(path, "r");
if (bak_fp == NULL) {
ULOG_ERR(g_log, "Opening remote backup file:%s is failure:%s", path, strerror(errno));
return -1;
}
char *line = NULL;
ssize_t n, n1;
ssize_t n3;
char text_level[MAX_LINE_SZ], old_redirect[MAX_LINE_SZ];
char rewrite_line[MAX_LINE_SZ];
while ((n1 = getline(&line, &n, bak_fp)) != -1) {
n3 = sscanf(line, "%1024s"REDIRECT_SEPERATE"%1024s", text_level, old_redirect);
if (n3 == 2) {
// 匹配到
// 改变该行日志级别
memset(rewrite_line, 0, sizeof(rewrite_line));
if (log_level_to_str(level, rewrite_line, sizeof(rewrite_line)) != 0) {
ULOG_ERR(g_log, "Log level converts str is failure");
goto END;
}
strcat(rewrite_line, REDIRECT_SEPERATE);
strcat(rewrite_line, old_redirect);
strcat(rewrite_line, "\n");
n3 = strlen(rewrite_line);
} else if (n == EOF) {
// 错误发生
ULOG_ERR(g_log, "Parsing remote line is failure:%s", strerror(errno));
goto END;
} else {
// 未能识别行
ULOG_DEBUG(g_log, "The line:%s can't be parsed", line);
}
ULOG_DEBUG(g_log, "Recover old line:%s to file:%s", rewrite_line, path);
n1 = fwrite(rewrite_line, 1, n3, fp);
if (n3 != n1) {
ULOG_ERR(g_log, "Recovering old line:%s to file is failure:%s", rewrite_line, strerror(errno));
goto END;
}
}
ret = 0;
END:
if (line != NULL) {
free(line);
}
if (bak_fp != NULL) {
fclose(bak_fp);
}
return ret;
}
static int add_remote_conf_content(FILE *fp, const u8 level, const char *filter_mod, void *arg)
{
return remote_conf_content(fp, level, filter_mod, match_remote_config, write_conf_content, arg);
}
static int del_remote_conf_content(FILE *fp, const u8 level, const char *filter_mod, void *arg)
{
return remote_conf_content(fp, level, filter_mod, match_remote_config, NULL, arg);
}
static int modify_remote_conf_log_level(FILE *fp, const u8 level, const char *filter_mod, void *arg)
{
return remote_conf_level_content(fp, level);
}
static int get_log_level()
{
char value[MAX_LINE_SZ];
if (get_log_file_conf(LOG_CONF_KEY_REMOTE_LEVEL, value, sizeof(value)) == 0) {
return atoi(value);
}
return LOG_INFO;
}
static int add_remote_host(const log_remote_host_t *conf)
{
ULOG_INFO(g_log, "Adding remote log server[%s:%u], rfc is %s", conf->host, conf->port, rfc_tbl[conf->rfc].fmt);
char prefix[2] = {0};
if (conf->rfc == LOG_RFC_5424) {
strcat(prefix, "@");
};
char redirect[MAX_LINE_SZ];
if (snprintf(redirect, sizeof(redirect), "%s@%s:%u;%s",
prefix, conf->host, conf->port, rfc_tbl[conf->rfc].fmt) < 0) {
ULOG_ERR(g_log, "Setting remote redirect[%s:%u;%s] is faulure", conf->host, conf->port, rfc_tbl[conf->rfc].fmt);
return -1;
}
int level = get_log_level();
if (level == -1) {
ULOG_ERR(g_log, "Getting log level is failure");
return -1;
}
if (log_conf(level, LOG_CONF_PATH, LOG_CONF_REMOTE_FILE_NAME, NULL,
add_remote_conf_content, (void *)redirect) != 0) {
ULOG_ERR(g_log, "Adding remote server[%s:%u;%s] is faulure", conf->host, conf->port, rfc_tbl[conf->rfc].fmt);
return -1;
}
return 0;
}
static int del_remote_host(const log_remote_host_t *conf)
{
int ret = -1;
char prefix[1] = "";
ULOG_INFO(g_log, "Deleting remote log server[%s:%u], rfc is %s", conf->host, conf->port, rfc_tbl[conf->rfc].fmt);
if (conf->rfc == LOG_RFC_5424) {
strcat(prefix, "@");
};
char redirect[MAX_LINE_SZ];
if (snprintf(redirect, sizeof(redirect), "%s@%s:%u;%s",
prefix, conf->host, conf->port, rfc_tbl[conf->rfc].fmt) < 0) {
ULOG_ERR(g_log, "Setting remote redirect[%s:%u;%s] is faulure", conf->host, conf->port, rfc_tbl[conf->rfc].fmt);
return ret;
}
int level = get_log_level();
if (level == -1) {
ULOG_ERR(g_log, "Getting log level is failure");
return ret;
}
ret = log_conf(level, LOG_CONF_PATH, LOG_CONF_REMOTE_FILE_NAME, NULL,
del_remote_conf_content, (void *)redirect);
if (ret != 0) {
ULOG_ERR(g_log, "Adding remote server[%s:%u;%s] is faulure", conf->host, conf->port, rfc_tbl[conf->rfc].fmt);
return ret;
}
return ret;
}
static int config_log_remote_host(const log_op_t op, const log_remote_host_t *conf)
{
if ((sizeof(rfc_tbl) / sizeof(rfc_key_fmt)) < conf->rfc) {
ULOG_WARNING(g_log, "Unknown rfc format key:%u", conf->rfc);
return -1;
}
if (op >= LOG_REMOTE_MAX) {
ULOG_WARNING(g_log, "Unknown operation type:%u", op);
return -1;
}
return remote_funcs[op](conf);
}
static int config_log_remote_level(const log_remote_level_t *level)
{
char str_level[4] = {0};
if (snprintf(str_level, sizeof(str_level), "%u", level->level) < 0) {
ULOG_ERR(g_log, "Building level value:%u to string is failure", level->level);
return -1;
}
if (write_log_file_conf(LOG_CONF_KEY_REMOTE_LEVEL, str_level) != 0) {
ULOG_ERR(g_log, "Writeing key-value[%s-%s] to config file is failure", LOG_CONF_KEY_REMOTE_LEVEL, str_level);
return -1;
}
//判断是否有rsyslog的remote配置如果有才写入
char path[MAX_PATH_SZ];
if (snprintf(path, sizeof(path), BAK_FILE, LOG_CONF_REMOTE_FILE_NAME) < 0) {
ULOG_ERR(g_log, "Build backup path(%s) is failure", BAK_FILE, LOG_CONF_REMOTE_FILE_NAME);
return -1;
}
if(access(path, F_OK) != 0) {
ULOG_ERR(g_log, "Backup file:%s is not exist:%s", path, strerror(errno));
return 1;
} else {
if (log_conf(level->level, LOG_CONF_PATH, LOG_CONF_REMOTE_FILE_NAME, NULL,
modify_remote_conf_log_level, NULL) != 0) {
ULOG_ERR(g_log, "Modifing log level:%u of remote server is faulure", level->level);
return -1;
}
}
return 0;
}
static void rpc_conf_log_remote(const log_op_t op, rpc_conn *conn, pointer input, int input_len, pointer data)
{
char str_err[1024];
if (input == NULL) {
strncpy(str_err, "Remote log configure can't be null", sizeof(str_err));
ULOG_WARNING(g_log, str_err);
goto FAIL;
}
u32 need_len = sizeof(log_remote_host_t);
if (input_len < need_len) {
ULOG_WARNING(g_log,
"The input paramter of rpc log remote host is needed length of %u, but the actual length is %u",
need_len, input_len);
return;
}
if (config_log_remote_host(op, (const log_remote_host_t *)input) != 0) {
ULOG_ERR(g_log, "Configuring remote of log is faiure");
rpc_return_error(conn, RET_ERR, "Configuring remote of log is faiure");
return;
}
rpc_return_null(conn);
FAIL:
rpc_return_error(conn, RET_ERR, str_err);
}
static int __rpc_conf_log_remote(pointer input, const void *arg, char *str_err, int str_len)
{
log_op_t op;
memcpy(&op, arg, sizeof(op));
int ret = config_log_remote_host(op, (const log_remote_host_t *)input);
if (ret < 0) {
strncpy(str_err, "Configuring remote of log is faiure", str_len);
}
return ret;
}
void rpc_conf_log_add_remote(rpc_conn *conn, pointer input, int input_len, pointer data)
{
//rpc_conf_log_remote(LOG_REMOTE_OP_ADD, conn, input, input_len, data);
log_op_t op = LOG_REMOTE_OP_ADD;
rpc_conf_proc(conn, input, input_len, sizeof(log_remote_host_t), __rpc_conf_log_remote, (void *)&op);
}
void rpc_conf_log_del_remote(rpc_conn *conn, pointer input, int input_len, pointer data)
{
//rpc_conf_log_remote(LOG_REMOTE_OP_DEL, conn, input, input_len, data);
log_op_t op = LOG_REMOTE_OP_DEL;
rpc_conf_proc(conn, input, input_len, sizeof(log_remote_host_t), __rpc_conf_log_remote, (void *)&op);
}
static int __rpc_conf_log_remote_level(pointer input, const void *arg, char *str_err, int str_len)
{
int ret = config_log_remote_level((const log_remote_level_t *)input);
if (ret < 0) {
strncpy(str_err, "Configuring remote level of log is faiure", str_len);
}
return ret;
}
void rpc_conf_log_remote_level(rpc_conn *conn, pointer input, int input_len, pointer data)
{
rpc_conf_proc(conn, input, input_len, sizeof(log_remote_level_t), __rpc_conf_log_remote_level, NULL);
}