|
@@ -28,6 +28,8 @@
|
|
|
#include <sys/dir.h>
|
|
|
#include <sys/stat.h>
|
|
|
#include <pthread.h>
|
|
|
+#include <sys/types.h>
|
|
|
+#include <regex.h>
|
|
|
#include "ab_map.h"
|
|
|
#include "ab_code.h"
|
|
|
|
|
@@ -39,7 +41,7 @@ static int ablog_keep_hours = 120;
|
|
|
static FILE *_ablog_file = NULL;
|
|
|
|
|
|
static struct pattern_instance ablog_filename =
|
|
|
- {"", 0, 0, 0, MAX_FILEPATH_LENGTH, ""};
|
|
|
+ {"", "", "", {0}, 0, 0, 0, MAX_FILEPATH_LENGTH, ""};
|
|
|
|
|
|
static int _ablog_print = 0;
|
|
|
|
|
@@ -136,6 +138,7 @@ char *code_string(int n)
|
|
|
|
|
|
void clear_coding()
|
|
|
{
|
|
|
+ clear_pattern_instance(&ablog_filename);
|
|
|
clear_mapping();
|
|
|
}
|
|
|
|
|
@@ -219,6 +222,15 @@ time_t _replace_time_pattern(char *buf, int buf_len, time_t st, char CoS)
|
|
|
return expiration_t;
|
|
|
}
|
|
|
|
|
|
+void clear_pattern_instance(struct pattern_instance *pi)
|
|
|
+{
|
|
|
+ if (pi->regex[0] != 0)
|
|
|
+ {
|
|
|
+ regfree(&pi->reg);
|
|
|
+ pi->regex[0] = 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
int instantiated_pattern(struct pattern_instance *pi)
|
|
|
{
|
|
|
time_t vt = vtime();
|
|
@@ -232,6 +244,72 @@ int instantiated_pattern(struct pattern_instance *pi)
|
|
|
replace_string(pi->instance, "[pid]", format_int("%d", getpid()), pi->instance,
|
|
|
pi->instance_buf_len);
|
|
|
|
|
|
+ if (strcmp(pi->last_pattern, pi->pattern) != 0)
|
|
|
+ {
|
|
|
+ char regex[MAX_FILEPATH_LENGTH];
|
|
|
+ strncpy(regex, pi->pattern, MAX_FILEPATH_LENGTH);
|
|
|
+ // 正则表达式通配符
|
|
|
+ replace_string(regex, "\\", "\\\\", regex, MAX_FILEPATH_LENGTH);
|
|
|
+ replace_string(regex, ".", "\\.", regex, MAX_FILEPATH_LENGTH);
|
|
|
+ replace_string(regex, "|", "\\|", regex, MAX_FILEPATH_LENGTH);
|
|
|
+ replace_string(regex, "(", "\\(", regex, MAX_FILEPATH_LENGTH);
|
|
|
+ replace_string(regex, ")", "\\)", regex, MAX_FILEPATH_LENGTH);
|
|
|
+ replace_string(regex, "{", "\\{", regex, MAX_FILEPATH_LENGTH);
|
|
|
+ replace_string(regex, "}", "\\}", regex, MAX_FILEPATH_LENGTH);
|
|
|
+ replace_string(regex, "*", "\\*", regex, MAX_FILEPATH_LENGTH);
|
|
|
+ replace_string(regex, "+", "\\+", regex, MAX_FILEPATH_LENGTH);
|
|
|
+ replace_string(regex, "?", "\\?", regex, MAX_FILEPATH_LENGTH);
|
|
|
+ replace_string(regex, "^", "\\^", regex, MAX_FILEPATH_LENGTH);
|
|
|
+ replace_string(regex, "$", "\\$", regex, MAX_FILEPATH_LENGTH);
|
|
|
+ // 临时转义[]
|
|
|
+ replace_string(regex, "&", "&a", regex, MAX_FILEPATH_LENGTH);
|
|
|
+ replace_string(regex, "[", "&[", regex, MAX_FILEPATH_LENGTH);
|
|
|
+ replace_string(regex, "]", "&]", regex, MAX_FILEPATH_LENGTH);
|
|
|
+ // 文件名支持定义内容转义
|
|
|
+ replace_string(regex, "&[PID&]", "[0-9]*", regex, MAX_FILEPATH_LENGTH);
|
|
|
+ replace_string(regex, "&[pid&]", "[0-9]*", regex, MAX_FILEPATH_LENGTH);
|
|
|
+ replace_string(regex, "&[YYYY&]", "[0-9]{4}", regex, MAX_FILEPATH_LENGTH);
|
|
|
+ replace_string(regex, "&[yyyy&]", "[0-9]{4}", regex, MAX_FILEPATH_LENGTH);
|
|
|
+ replace_string(regex, "&[MM&]", "[0-9]{2}", regex, MAX_FILEPATH_LENGTH);
|
|
|
+ replace_string(regex, "&[mm&]", "[0-9]{2}", regex, MAX_FILEPATH_LENGTH);
|
|
|
+ replace_string(regex, "&[DD&]", "[0-9]{2}", regex, MAX_FILEPATH_LENGTH);
|
|
|
+ replace_string(regex, "&[dd&]", "[0-9]{2}", regex,
|
|
|
+ MAX_FILEPATH_LENGTH);
|
|
|
+ replace_string(regex, "&[HH&]", "[0-9]{2}", regex,
|
|
|
+ MAX_FILEPATH_LENGTH);
|
|
|
+ replace_string(regex, "&[hh&]", "[0-9]{2}", regex,
|
|
|
+ MAX_FILEPATH_LENGTH);
|
|
|
+ replace_string(regex, "&[MI&]", "[0-9]{2}", regex,
|
|
|
+ MAX_FILEPATH_LENGTH);
|
|
|
+ replace_string(regex, "&[mi&]", "[0-9]{2}", regex,
|
|
|
+ MAX_FILEPATH_LENGTH);
|
|
|
+ // []转义
|
|
|
+ replace_string(regex, "&[", "\\[", regex, MAX_FILEPATH_LENGTH);
|
|
|
+ replace_string(regex, "&]", "\\]", regex, MAX_FILEPATH_LENGTH);
|
|
|
+ // 恢复临时转义
|
|
|
+ replace_string(regex, "&a", "&", regex, MAX_FILEPATH_LENGTH);
|
|
|
+ if (pi->regex[0] != 0)
|
|
|
+ {
|
|
|
+ regfree(&pi->reg);
|
|
|
+ pi->regex[0] = 0;
|
|
|
+ }
|
|
|
+ if (regex[0] != 0)
|
|
|
+ {
|
|
|
+ int reti = regcomp(&pi->reg, regex, REG_EXTENDED);
|
|
|
+ if (reti != 0)
|
|
|
+ {
|
|
|
+ char errbuf[256];
|
|
|
+ regerror(reti, &pi->reg, errbuf, sizeof(errbuf));
|
|
|
+ log_println("ABLOG_INIT", __FILE__, __LINE__, "ERROR:%s", errbuf);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ strncpy(pi->regex, regex, MAX_FILEPATH_LENGTH);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ strncpy(pi->last_pattern, pi->pattern, MAX_FILEPATH_LENGTH);
|
|
|
+ }
|
|
|
+
|
|
|
pi->expiration_ct = _replace_time_pattern(pi->instance, pi->instance_buf_len, ct, 'C');
|
|
|
pi->expiration_vt = _replace_time_pattern(pi->instance, pi->instance_buf_len, vt, 'V');
|
|
|
|
|
@@ -242,6 +320,28 @@ int instantiated_pattern(struct pattern_instance *pi)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+int matched_logfile_pattern(struct pattern_instance *pi, char *filepath)
|
|
|
+{
|
|
|
+ if (pi->regex[0] != 0)
|
|
|
+ {
|
|
|
+ int reti = regexec(&pi->reg, filepath, 0, NULL, 0);
|
|
|
+ if (reti == 0)
|
|
|
+ {
|
|
|
+ // log_println("I", __FILE__, __LINE__, "%s match %s", filepath, pi->regex);
|
|
|
+ return 1; // 匹配成功
|
|
|
+ }
|
|
|
+ if (reti == REG_NOMATCH)
|
|
|
+ {
|
|
|
+ // log_println("I", __FILE__, __LINE__, "%s not match %s", filepath, pi->regex);
|
|
|
+ return 0; // 不匹配
|
|
|
+ }
|
|
|
+ char errbuf[256];
|
|
|
+ regerror(reti, &pi->reg, errbuf, sizeof(errbuf));
|
|
|
+ log_println("E", __FILE__, __LINE__, "%s", errbuf);
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
int lock_file(char *filename, int wait)
|
|
|
{
|
|
|
int lockfd = open(filename, O_RDWR | O_CREAT, 0666);
|
|
@@ -312,16 +412,18 @@ int _ablog_lock(char *dir)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-int _ablog_rm_old_files(char *dir, time_t time_before)
|
|
|
+int _ablog_rm_old_files(struct pattern_instance *pi, char *dir, time_t time_before)
|
|
|
{
|
|
|
- if (!_ablog_lock(dir))
|
|
|
- {
|
|
|
- return -1;
|
|
|
- }
|
|
|
+ // if (!_ablog_lock(dir))
|
|
|
+ // {
|
|
|
+ // // log_println("ABLOG_FILE", __FILE__, __LINE__, "lock dir failed: %s", dir);
|
|
|
+ // return -1;
|
|
|
+ // }
|
|
|
|
|
|
DIR *od = opendir(dir);
|
|
|
if (od == NULL)
|
|
|
{
|
|
|
+ // log_println("ABLOG_FILE", __FILE__, __LINE__, "open dir failed: %s", dir);
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
@@ -335,15 +437,18 @@ int _ablog_rm_old_files(char *dir, time_t time_before)
|
|
|
if (ent->d_name[0] != '.')
|
|
|
{
|
|
|
sprintf(file, "%s%s", dir, ent->d_name);
|
|
|
- stat(file, &file_stat);
|
|
|
- // printf("%32s %s ", namelist[i]->d_name, time_string(file_stat.st_mtime));
|
|
|
- if (S_ISREG(file_stat.st_mode) && file_stat.st_mtime < time_before)
|
|
|
+ if (matched_logfile_pattern(pi, file))
|
|
|
{
|
|
|
- remove(file);
|
|
|
- n++;
|
|
|
- log_println("ABLOG_FILE", __FILE__, __LINE__, "remove old log file: %s", file);
|
|
|
+ stat(file, &file_stat);
|
|
|
+ // printf("%32s %s ", namelist[i]->d_name, time_string(file_stat.st_mtime));
|
|
|
+ if (S_ISREG(file_stat.st_mode) && file_stat.st_mtime < time_before)
|
|
|
+ {
|
|
|
+ remove(file);
|
|
|
+ n++;
|
|
|
+ log_println("ABLOG_FILE", __FILE__, __LINE__, "remove old log file: %s", file);
|
|
|
+ }
|
|
|
+ // printf("\n");
|
|
|
}
|
|
|
- // printf("\n");
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -359,7 +464,8 @@ int _ablog_rm_old_files(char *dir, time_t time_before)
|
|
|
|
|
|
int remove_old_log_files(time_t time_before)
|
|
|
{
|
|
|
- if (strlen(ablog_filename.instance) == 0) {
|
|
|
+ if (strlen(ablog_filename.instance) == 0)
|
|
|
+ {
|
|
|
return 0;
|
|
|
}
|
|
|
char buf[MAX_FILEPATH_LENGTH];
|
|
@@ -374,7 +480,7 @@ int remove_old_log_files(time_t time_before)
|
|
|
{
|
|
|
strcpy(buf, "./");
|
|
|
}
|
|
|
- return _ablog_rm_old_files(buf, time_before);
|
|
|
+ return _ablog_rm_old_files(&ablog_filename, buf, time_before);
|
|
|
}
|
|
|
|
|
|
void _ablog_set_log_file()
|
|
@@ -387,7 +493,8 @@ void _ablog_set_log_file()
|
|
|
}
|
|
|
if (strlen(ablog_filename.instance) > 0)
|
|
|
{
|
|
|
- if (mk_parent_dir(ablog_filename.instance) != 0) {
|
|
|
+ if (mk_parent_dir(ablog_filename.instance) != 0)
|
|
|
+ {
|
|
|
_ablog_stdout = 1;
|
|
|
log_println("ABLOG_FILE", __FILE__, __LINE__, "make parent dir error, '%s'",
|
|
|
ablog_filename.instance);
|
|
@@ -478,14 +585,16 @@ int get_log_print_level()
|
|
|
*/
|
|
|
void log_println(const char *func, const char *file, int line, const char *format, ...)
|
|
|
{
|
|
|
- if (ablog_file()) {
|
|
|
+ if (ablog_file())
|
|
|
+ {
|
|
|
va_list vl;
|
|
|
va_start(vl, format);
|
|
|
log_println_vl(1, func, file, line, format, vl);
|
|
|
va_end(vl);
|
|
|
}
|
|
|
|
|
|
- if (ablog_stdout()) {
|
|
|
+ if (ablog_stdout())
|
|
|
+ {
|
|
|
va_list vl;
|
|
|
va_start(vl, format);
|
|
|
log_println_vl(0, func, file, line, format, vl);
|
|
@@ -499,17 +608,18 @@ void log_println_vl(int fileout, const char *func, const char *file, int line, c
|
|
|
gettimeofday(&tv, NULL);
|
|
|
|
|
|
FILE *fout = stdout;
|
|
|
- if (fileout) {
|
|
|
+ if (fileout)
|
|
|
+ {
|
|
|
_ablog_set_log_file();
|
|
|
fout = _ablog_file;
|
|
|
- if (!fout) {
|
|
|
+ if (!fout)
|
|
|
+ {
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
pthread_mutex_lock(&thread_mut);
|
|
|
|
|
|
-
|
|
|
fprintf(fout, "%s.%03ld[%s]:", time_string(tv.tv_sec), (tv.tv_usec / 1000l), func);
|
|
|
vfprintf(fout, format, vl);
|
|
|
fprintf(fout, " (%s:%d)\n", file, line);
|
|
@@ -997,57 +1107,57 @@ char *trimLeft(const char *str, char *rbuf)
|
|
|
return rbuf;
|
|
|
}
|
|
|
|
|
|
-char *trim(const char *str, char *rbuf)
|
|
|
-{
|
|
|
- if (rbuf == 0)
|
|
|
- {
|
|
|
- rbuf = (char *)str;
|
|
|
- }
|
|
|
- trimLeft(str, rbuf);
|
|
|
- trimRight(rbuf, rbuf);
|
|
|
- return rbuf;
|
|
|
-}
|
|
|
-
|
|
|
-long read_mapping_file(int fd)
|
|
|
-{
|
|
|
- ABLOG_Entry(Public, read_mapping_file);
|
|
|
-
|
|
|
- long ret_map_id = new_mapping();
|
|
|
-
|
|
|
- int flen = lseek(fd, 0, SEEK_END);
|
|
|
- char *buf = MALLOC(flen + 1);
|
|
|
- memset(buf, 0, flen + 1);
|
|
|
- lseek(fd, 0, SEEK_SET);
|
|
|
- read(fd, buf, flen);
|
|
|
-
|
|
|
- char *line_buffer = buf;
|
|
|
- while (line_buffer[0])
|
|
|
- {
|
|
|
- char *newline = strstr(line_buffer, "\n");
|
|
|
- if (newline)
|
|
|
- {
|
|
|
- newline[0] = 0;
|
|
|
- }
|
|
|
- trimLeft(line_buffer, 0);
|
|
|
- if (line_buffer[0] != '#' && strlen(line_buffer) > 0)
|
|
|
- {
|
|
|
- char *kv[2];
|
|
|
- split_string(line_buffer, '=', line_buffer, flen + 1, kv, 2);
|
|
|
-
|
|
|
- char *key = trim(kv[0], 0);
|
|
|
- char *value = trim(kv[1], 0);
|
|
|
-
|
|
|
- ABLOG_Printf(Detail, (ABLOG, "[D] %s=%s", key, value));
|
|
|
-
|
|
|
- put_string_mapping(ret_map_id, key, value);
|
|
|
- }
|
|
|
- line_buffer = newline ? newline + 1 : 0;
|
|
|
- }
|
|
|
-
|
|
|
- FREE(buf);
|
|
|
-
|
|
|
- ABLOG_Return_Long(ret_map_id);
|
|
|
-}
|
|
|
+// char *trim(const char *str, char *rbuf)
|
|
|
+// {
|
|
|
+// if (rbuf == 0)
|
|
|
+// {
|
|
|
+// rbuf = (char *)str;
|
|
|
+// }
|
|
|
+// trimLeft(str, rbuf);
|
|
|
+// trimRight(rbuf, rbuf);
|
|
|
+// return rbuf;
|
|
|
+// }
|
|
|
+
|
|
|
+// long read_mapping_file(int fd)
|
|
|
+// {
|
|
|
+// ABLOG_Entry(Public, read_mapping_file);
|
|
|
+
|
|
|
+// long ret_map_id = new_mapping();
|
|
|
+
|
|
|
+// int flen = lseek(fd, 0, SEEK_END);
|
|
|
+// char *buf = MALLOC(flen + 1);
|
|
|
+// memset(buf, 0, flen + 1);
|
|
|
+// lseek(fd, 0, SEEK_SET);
|
|
|
+// read(fd, buf, flen);
|
|
|
+
|
|
|
+// char *line_buffer = buf;
|
|
|
+// while (line_buffer[0])
|
|
|
+// {
|
|
|
+// char *newline = strstr(line_buffer, "\n");
|
|
|
+// if (newline)
|
|
|
+// {
|
|
|
+// newline[0] = 0;
|
|
|
+// }
|
|
|
+// trimLeft(line_buffer, 0);
|
|
|
+// if (line_buffer[0] != '#' && strlen(line_buffer) > 0)
|
|
|
+// {
|
|
|
+// char *kv[2];
|
|
|
+// split_string(line_buffer, '=', line_buffer, flen + 1, kv, 2);
|
|
|
+
|
|
|
+// char *key = trim(kv[0], 0);
|
|
|
+// char *value = trim(kv[1], 0);
|
|
|
+
|
|
|
+// ABLOG_Printf(Detail, (ABLOG, "[D] %s=%s", key, value));
|
|
|
+
|
|
|
+// put_string_mapping(ret_map_id, key, value);
|
|
|
+// }
|
|
|
+// line_buffer = newline ? newline + 1 : 0;
|
|
|
+// }
|
|
|
+
|
|
|
+// FREE(buf);
|
|
|
+
|
|
|
+// ABLOG_Return_Long(ret_map_id);
|
|
|
+// }
|
|
|
|
|
|
int write_mapping_file(int fd, long mid)
|
|
|
{
|
|
@@ -1075,7 +1185,8 @@ int mk_dir(char *dir)
|
|
|
if ((mydir = opendir(dir)) == NULL) // 判断目录
|
|
|
{
|
|
|
int ret = mk_parent_dir(dir);
|
|
|
- if (ret != 0) {
|
|
|
+ if (ret != 0)
|
|
|
+ {
|
|
|
return ret;
|
|
|
}
|
|
|
ret = mkdir(dir, DIR_MODE); // 创建目录
|