123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059 |
- /*
- * This file is part of the zlog Library.
- *
- * Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
- *
- * Licensed under the LGPL v2.1, see the file COPYING in base directory.
- */
- #include "fmacros.h"
- #include <string.h>
- #include <ctype.h>
- #include <syslog.h>
- #include <errno.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <pthread.h>
- #include "rule.h"
- #include "format.h"
- #include "buf.h"
- #include "thread.h"
- #include "level_list.h"
- #include "rotater.h"
- #include "spec.h"
- #include "conf.h"
- #include "zc_defs.h"
- void zlog_rule_profile(zlog_rule_t * a_rule, int flag)
- {
- int i;
- zlog_spec_t *a_spec;
- zc_assert(a_rule,);
- zc_profile(flag, "---rule:[%p][%s%c%d]-[%d,%d][%s,%p,%d:%ld*%d~%s][%d][%d][%s:%s:%p];[%p]---",
- a_rule,
- a_rule->category,
- a_rule->compare_char,
- a_rule->level,
- a_rule->file_perms,
- a_rule->file_open_flags,
- a_rule->file_path,
- a_rule->dynamic_specs,
- a_rule->static_fd,
- a_rule->archive_max_size,
- a_rule->archive_max_count,
- a_rule->archive_path,
- a_rule->pipe_fd,
- a_rule->syslog_facility,
- a_rule->record_name,
- a_rule->record_path,
- a_rule->record_func,
- a_rule->format);
- if (a_rule->dynamic_specs) {
- zc_arraylist_foreach(a_rule->dynamic_specs, i, a_spec) {
- zlog_spec_profile(a_spec, flag);
- }
- }
- return;
- }
- /*******************************************************************************/
- static int zlog_rule_output_static_file_single(zlog_rule_t * a_rule, zlog_thread_t * a_thread)
- {
- struct stat stb;
- int do_file_reload = 0;
- int redo_inode_stat = 0;
- if (zlog_format_gen_msg(a_rule->format, a_thread)) {
- zc_error("zlog_format_gen_msg fail");
- return -1;
- }
- /* check if the output file was changed by an external tool by comparing the inode to our saved off one */
- if (stat(a_rule->file_path, &stb)) {
- if (errno != ENOENT) {
- zc_error("stat fail on [%s], errno[%d]", a_rule->file_path, errno);
- return -1;
- } else {
- do_file_reload = 1;
- redo_inode_stat = 1; /* we'll have to restat the newly created file to get the inode info */
- }
- } else {
- do_file_reload = (stb.st_ino != a_rule->static_ino || stb.st_dev != a_rule->static_dev);
- }
- if (do_file_reload) {
- close(a_rule->static_fd);
- a_rule->static_fd = open(a_rule->file_path,
- O_WRONLY | O_APPEND | O_CREAT | a_rule->file_open_flags,
- a_rule->file_perms);
- if (a_rule->static_fd < 0) {
- zc_error("open file[%s] fail, errno[%d]", a_rule->file_path, errno);
- return -1;
- }
- /* save off the new dev/inode info from the stat call we already did */
- if (redo_inode_stat) {
- if (stat(a_rule->file_path, &stb)) {
- zc_error("stat fail on new file[%s], errno[%d]", a_rule->file_path, errno);
- return -1;
- }
- }
- a_rule->static_dev = stb.st_dev;
- a_rule->static_ino = stb.st_ino;
- }
- if (write(a_rule->static_fd,
- zlog_buf_str(a_thread->msg_buf),
- zlog_buf_len(a_thread->msg_buf)) < 0) {
- zc_error("write fail, errno[%d]", errno);
- return -1;
- }
- /* not so thread safe here, as multiple thread may ++fsync_count at the same time */
- if (a_rule->fsync_period && ++a_rule->fsync_count >= a_rule->fsync_period) {
- a_rule->fsync_count = 0;
- if (fsync(a_rule->static_fd)) {
- zc_error("fsync[%d] fail, errno[%d]", a_rule->static_fd, errno);
- }
- }
- return 0;
- }
- static char * zlog_rule_gen_archive_path(zlog_rule_t *a_rule, zlog_thread_t *a_thread)
- {
- int i;
- zlog_spec_t *a_spec;
- if (!a_rule->archive_specs) return a_rule->archive_path;
- zlog_buf_restart(a_thread->archive_path_buf);
- zc_arraylist_foreach(a_rule->archive_specs, i, a_spec) {
- if (zlog_spec_gen_archive_path(a_spec, a_thread)) {
- zc_error("zlog_spec_gen_path fail");
- return NULL;
- }
- }
- zlog_buf_seal(a_thread->archive_path_buf);
- return zlog_buf_str(a_thread->archive_path_buf);
- }
- static int zlog_rule_output_static_file_rotate(zlog_rule_t * a_rule, zlog_thread_t * a_thread)
- {
- size_t len;
- struct zlog_stat info;
- int fd;
- if (zlog_format_gen_msg(a_rule->format, a_thread)) {
- zc_error("zlog_format_gen_msg fail");
- return -1;
- }
- fd = open(a_rule->file_path,
- a_rule->file_open_flags | O_WRONLY | O_APPEND | O_CREAT, a_rule->file_perms);
- if (fd < 0) {
- zc_error("open file[%s] fail, errno[%d]", a_rule->file_path, errno);
- return -1;
- }
- len = zlog_buf_len(a_thread->msg_buf);
- if (write(fd, zlog_buf_str(a_thread->msg_buf), len) < 0) {
- zc_error("write fail, errno[%d]", errno);
- close(fd);
- return -1;
- }
- if (a_rule->fsync_period && ++a_rule->fsync_count >= a_rule->fsync_period) {
- a_rule->fsync_count = 0;
- if (fsync(fd)) zc_error("fsync[%d] fail, errno[%d]", fd, errno);
- }
- if (close(fd) < 0) {
- zc_error("close fail, maybe cause by write, errno[%d]", errno);
- return -1;
- }
- if (len > a_rule->archive_max_size) {
- zc_debug("one msg's len[%ld] > archive_max_size[%ld], no rotate",
- (long)len, (long)a_rule->archive_max_size);
- return 0;
- }
- if (stat(a_rule->file_path, &info)) {
- zc_warn("stat [%s] fail, errno[%d], maybe in rotating", a_rule->file_path, errno);
- return 0;
- }
- /* file not so big, return */
- if (info.st_size + len < a_rule->archive_max_size) return 0;
- if (zlog_rotater_rotate(zlog_env_conf->rotater,
- a_rule->file_path, len,
- zlog_rule_gen_archive_path(a_rule, a_thread),
- a_rule->archive_max_size, a_rule->archive_max_count)
- ) {
- zc_error("zlog_rotater_rotate fail");
- return -1;
- } /* success or no rotation do nothing */
- return 0;
- }
- /* return path success
- * return NULL fail
- */
- #define zlog_rule_gen_path(a_rule, a_thread) do { \
- int i; \
- zlog_spec_t *a_spec; \
- \
- zlog_buf_restart(a_thread->path_buf); \
- \
- zc_arraylist_foreach(a_rule->dynamic_specs, i, a_spec) { \
- if (zlog_spec_gen_path(a_spec, a_thread)) { \
- zc_error("zlog_spec_gen_path fail"); \
- return -1; \
- } \
- } \
- \
- zlog_buf_seal(a_thread->path_buf); \
- } while(0)
- static int zlog_rule_output_dynamic_file_single(zlog_rule_t * a_rule, zlog_thread_t * a_thread)
- {
- int fd;
- zlog_rule_gen_path(a_rule, a_thread);
- if (zlog_format_gen_msg(a_rule->format, a_thread)) {
- zc_error("zlog_format_output fail");
- return -1;
- }
- fd = open(zlog_buf_str(a_thread->path_buf),
- a_rule->file_open_flags | O_WRONLY | O_APPEND | O_CREAT, a_rule->file_perms);
- if (fd < 0) {
- zc_error("open file[%s] fail, errno[%d]", zlog_buf_str(a_thread->path_buf), errno);
- return -1;
- }
- if (write(fd, zlog_buf_str(a_thread->msg_buf), zlog_buf_len(a_thread->msg_buf)) < 0) {
- zc_error("write fail, errno[%d]", errno);
- close(fd);
- return -1;
- }
- if (a_rule->fsync_period && ++a_rule->fsync_count >= a_rule->fsync_period) {
- a_rule->fsync_count = 0;
- if (fsync(fd)) zc_error("fsync[%d] fail, errno[%d]", fd, errno);
- }
- if (close(fd) < 0) {
- zc_error("close fail, maybe cause by write, errno[%d]", errno);
- return -1;
- }
- return 0;
- }
- static int zlog_rule_output_dynamic_file_rotate(zlog_rule_t * a_rule, zlog_thread_t * a_thread)
- {
- int fd;
- char *path;
- size_t len;
- struct zlog_stat info;
- zlog_rule_gen_path(a_rule, a_thread);
- if (zlog_format_gen_msg(a_rule->format, a_thread)) {
- zc_error("zlog_format_output fail");
- return -1;
- }
- path = zlog_buf_str(a_thread->path_buf);
- fd = open(path, a_rule->file_open_flags | O_WRONLY | O_APPEND | O_CREAT, a_rule->file_perms);
- if (fd < 0) {
- zc_error("open file[%s] fail, errno[%d]", zlog_buf_str(a_thread->path_buf), errno);
- return -1;
- }
- len = zlog_buf_len(a_thread->msg_buf);
- if (write(fd, zlog_buf_str(a_thread->msg_buf), len) < 0) {
- zc_error("write fail, errno[%d]", errno);
- close(fd);
- return -1;
- }
- if (a_rule->fsync_period && ++a_rule->fsync_count >= a_rule->fsync_period) {
- a_rule->fsync_count = 0;
- if (fsync(fd)) zc_error("fsync[%d] fail, errno[%d]", fd, errno);
- }
- if (close(fd) < 0) {
- zc_error("write fail, maybe cause by write, errno[%d]", errno);
- return -1;
- }
- if (len > a_rule->archive_max_size) {
- zc_debug("one msg's len[%ld] > archive_max_size[%ld], no rotate",
- (long)len, (long) a_rule->archive_max_size);
- return 0;
- }
- if (stat(path, &info)) {
- zc_warn("stat [%s] fail, errno[%d], maybe in rotating", path, errno);
- return 0;
- }
- /* file not so big, return */
- if (info.st_size + len < a_rule->archive_max_size) return 0;
- if (zlog_rotater_rotate(zlog_env_conf->rotater,
- path, len,
- zlog_rule_gen_archive_path(a_rule, a_thread),
- a_rule->archive_max_size, a_rule->archive_max_count)
- ) {
- zc_error("zlog_rotater_rotate fail");
- return -1;
- } /* success or no rotation do nothing */
- return 0;
- }
- static int zlog_rule_output_pipe(zlog_rule_t * a_rule, zlog_thread_t * a_thread)
- {
- if (zlog_format_gen_msg(a_rule->format, a_thread)) {
- zc_error("zlog_format_gen_msg fail");
- return -1;
- }
- if (write(a_rule->pipe_fd,
- zlog_buf_str(a_thread->msg_buf),
- zlog_buf_len(a_thread->msg_buf)) < 0) {
- zc_error("write fail, errno[%d]", errno);
- return -1;
- }
- return 0;
- }
- static int zlog_rule_output_syslog(zlog_rule_t * a_rule, zlog_thread_t * a_thread)
- {
- zlog_level_t *a_level;
- if (zlog_format_gen_msg(a_rule->format, a_thread)) {
- zc_error("zlog_format_gen_msg fail");
- return -1;
- }
- /*
- msg = a_thread->msg_buf->start;
- msg_len = a_thread->msg_buf->end - a_thread->msg_buf->start;
- */
- a_level = zlog_level_list_get(zlog_env_conf->levels, a_thread->event->level);
- zlog_buf_seal(a_thread->msg_buf);
- syslog(a_rule->syslog_facility | a_level->syslog_level,
- "%s", zlog_buf_str(a_thread->msg_buf));
- return 0;
- }
- static int zlog_rule_output_static_record(zlog_rule_t * a_rule, zlog_thread_t * a_thread)
- {
- zlog_msg_t msg;
- if (!a_rule->record_func) {
- zc_error("user defined record funcion for [%s] not set, no output",
- a_rule->record_name);
- return -1;
- }
- if (zlog_format_gen_msg(a_rule->format, a_thread)) {
- zc_error("zlog_format_gen_msg fail");
- return -1;
- }
- zlog_buf_seal(a_thread->msg_buf);
- msg.buf = zlog_buf_str(a_thread->msg_buf);
- msg.len = zlog_buf_len(a_thread->msg_buf);
- msg.path = a_rule->record_path;
- if (a_rule->record_func(&msg)) {
- zc_error("a_rule->record fail");
- return -1;
- }
- return 0;
- }
- static int zlog_rule_output_dynamic_record(zlog_rule_t * a_rule, zlog_thread_t * a_thread)
- {
- zlog_msg_t msg;
- if (!a_rule->record_func) {
- zc_error("user defined record funcion for [%s] not set, no output",
- a_rule->record_name);
- return -1;
- }
- zlog_rule_gen_path(a_rule, a_thread);
- if (zlog_format_gen_msg(a_rule->format, a_thread)) {
- zc_error("zlog_format_gen_msg fail");
- return -1;
- }
- zlog_buf_seal(a_thread->msg_buf);
- msg.buf = zlog_buf_str(a_thread->msg_buf);
- msg.len = zlog_buf_len(a_thread->msg_buf);
- msg.path = zlog_buf_str(a_thread->path_buf);
- if (a_rule->record_func(&msg)) {
- zc_error("a_rule->record fail");
- return -1;
- }
- return 0;
- }
- static int zlog_rule_output_stdout(zlog_rule_t * a_rule,
- zlog_thread_t * a_thread)
- {
- if (zlog_format_gen_msg(a_rule->format, a_thread)) {
- zc_error("zlog_format_gen_msg fail");
- return -1;
- }
- if (write(STDOUT_FILENO,
- zlog_buf_str(a_thread->msg_buf), zlog_buf_len(a_thread->msg_buf)) < 0) {
- zc_error("write fail, errno[%d]", errno);
- return -1;
- }
- return 0;
- }
- static int zlog_rule_output_stderr(zlog_rule_t * a_rule,
- zlog_thread_t * a_thread)
- {
- if (zlog_format_gen_msg(a_rule->format, a_thread)) {
- zc_error("zlog_format_gen_msg fail");
- return -1;
- }
- if (write(STDERR_FILENO,
- zlog_buf_str(a_thread->msg_buf), zlog_buf_len(a_thread->msg_buf)) < 0) {
- zc_error("write fail, errno[%d]", errno);
- return -1;
- }
- return 0;
- }
- /*******************************************************************************/
- static int syslog_facility_atoi(char *facility)
- {
- /* guess no unix system will choose -187
- * as its syslog facility, so it is a safe return value
- */
- zc_assert(facility, -187);
- if (STRICMP(facility, ==, "LOG_LOCAL0")) return LOG_LOCAL0;
- if (STRICMP(facility, ==, "LOG_LOCAL1")) return LOG_LOCAL1;
- if (STRICMP(facility, ==, "LOG_LOCAL2")) return LOG_LOCAL2;
- if (STRICMP(facility, ==, "LOG_LOCAL3")) return LOG_LOCAL3;
- if (STRICMP(facility, ==, "LOG_LOCAL4")) return LOG_LOCAL4;
- if (STRICMP(facility, ==, "LOG_LOCAL5")) return LOG_LOCAL5;
- if (STRICMP(facility, ==, "LOG_LOCAL6")) return LOG_LOCAL6;
- if (STRICMP(facility, ==, "LOG_LOCAL7")) return LOG_LOCAL7;
- if (STRICMP(facility, ==, "LOG_USER")) return LOG_USER;
- if (STRICMP(facility, ==, "LOG_AUTHPRIV")) return LOG_AUTHPRIV;
- if (STRICMP(facility, ==, "LOG_CRON")) return LOG_CRON;
- if (STRICMP(facility, ==, "LOG_DAEMON")) return LOG_DAEMON;
- if (STRICMP(facility, ==, "LOG_FTP")) return LOG_FTP;
- if (STRICMP(facility, ==, "LOG_KERN")) return LOG_KERN;
- if (STRICMP(facility, ==, "LOG_LPR")) return LOG_LPR;
- if (STRICMP(facility, ==, "LOG_MAIL")) return LOG_MAIL;
- if (STRICMP(facility, ==, "LOG_NEWS")) return LOG_NEWS;
- if (STRICMP(facility, ==, "LOG_SYSLOG")) return LOG_SYSLOG;
- return LOG_AUTHPRIV;
- zc_error("wrong syslog facility[%s], must in LOG_LOCAL[0-7] or LOG_USER", facility);
- return -187;
- }
- static int zlog_rule_parse_path(char *path_start, /* start with a " */
- char *path_str, size_t path_size, zc_arraylist_t **path_specs,
- int *time_cache_count)
- {
- char *p, *q;
- size_t len;
- zlog_spec_t *a_spec;
- zc_arraylist_t *specs;
- p = path_start + 1;
- q = strrchr(p, '"');
- if (!q) {
- zc_error("matching \" not found in conf line[%s]", path_start);
- return -1;
- }
- len = q - p;
- if (len > path_size - 1) {
- zc_error("file_path too long %ld > %ld", len, path_size - 1);
- return -1;
- }
- memcpy(path_str, p, len);
- /* replace any environment variables like %E(HOME) */
- if (zc_str_replace_env(path_str, path_size)) {
- zc_error("zc_str_replace_env fail");
- return -1;
- }
- if (strchr(path_str, '%') == NULL) {
- /* static, no need create specs */
- return 0;
- }
- specs = zc_arraylist_new((zc_arraylist_del_fn)zlog_spec_del);
- if (!path_specs) {
- zc_error("zc_arraylist_new fail");
- return -1;
- }
- for (p = path_str; *p != '\0'; p = q) {
- a_spec = zlog_spec_new(p, &q, time_cache_count);
- if (!a_spec) {
- zc_error("zlog_spec_new fail");
- goto err;
- }
- if (zc_arraylist_add(specs, a_spec)) {
- zc_error("zc_arraylist_add fail");
- goto err;
- }
- }
- *path_specs = specs;
- return 0;
- err:
- if (specs) zc_arraylist_del(specs);
- if (a_spec) zlog_spec_del(a_spec);
- return -1;
- }
- zlog_rule_t *zlog_rule_new(char *line,
- zc_arraylist_t *levels,
- zlog_format_t * default_format,
- zc_arraylist_t * formats,
- unsigned int file_perms,
- size_t fsync_period,
- int * time_cache_count)
- {
- int rc = 0;
- int nscan = 0;
- int nread = 0;
- zlog_rule_t *a_rule;
- char selector[MAXLEN_CFG_LINE + 1];
- char category[MAXLEN_CFG_LINE + 1];
- char level[MAXLEN_CFG_LINE + 1];
- char *action;
- char output[MAXLEN_CFG_LINE + 1];
- char format_name[MAXLEN_CFG_LINE + 1];
- char file_path[MAXLEN_CFG_LINE + 1];
- char archive_max_size[MAXLEN_CFG_LINE + 1];
- char *file_limit;
- char *p;
- char *q;
- size_t len;
- zc_assert(line, NULL);
- zc_assert(default_format, NULL);
- zc_assert(formats, NULL);
- a_rule = calloc(1, sizeof(zlog_rule_t));
- if (!a_rule) {
- zc_error("calloc fail, errno[%d]", errno);
- return NULL;
- }
- a_rule->file_perms = file_perms;
- a_rule->fsync_period = fsync_period;
- /* line [f.INFO "%H/log/aa.log", 20MB * 12; MyTemplate]
- * selector [f.INFO]
- * *action ["%H/log/aa.log", 20MB * 12; MyTemplate]
- */
- memset(&selector, 0x00, sizeof(selector));
- nscan = sscanf(line, "%s %n", selector, &nread);
- if (nscan != 1) {
- zc_error("sscanf [%s] fail, selector", line);
- goto err;
- }
- action = line + nread;
- /*
- * selector [f.INFO]
- * category [f]
- * level [.INFO]
- */
- memset(category, 0x00, sizeof(category));
- memset(level, 0x00, sizeof(level));
- nscan = sscanf(selector, " %[^.].%s", category, level);
- if (nscan != 2) {
- zc_error("sscanf [%s] fail, category or level is null",
- selector);
- goto err;
- }
- /* check and set category */
- for (p = category; *p != '\0'; p++) {
- if ((!isalnum(*p)) && (*p != '_') && (*p != '-') && (*p != '*') && (*p != '!')) {
- zc_error("category name[%s] character is not in [a-Z][0-9][_!*-]", category);
- goto err;
- }
- }
- /* as one line can't be longer than MAXLEN_CFG_LINE, same as category */
- strcpy(a_rule->category, category);
- /* check and set level */
- switch (level[0]) {
- case '=':
- /* aa.=debug */
- a_rule->compare_char = '=';
- p = level + 1;
- break;
- case '!':
- /* aa.!debug */
- a_rule->compare_char = '!';
- p = level + 1;
- break;
- case '*':
- /* aa.* */
- a_rule->compare_char = '*';
- p = level;
- break;
- default:
- /* aa.debug */
- a_rule->compare_char = '.';
- p = level;
- break;
- }
- a_rule->level = zlog_level_list_atoi(levels, p);
- /* level_bit is a bitmap represents which level can be output
- * 32bytes, [0-255] levels, see level.c
- * which bit field is 1 means allow output and 0 not
- */
- switch (a_rule->compare_char) {
- case '=':
- memset(a_rule->level_bitmap, 0x00, sizeof(a_rule->level_bitmap));
- a_rule->level_bitmap[a_rule->level / 8] |= (1 << (7 - a_rule->level % 8));
- break;
- case '!':
- memset(a_rule->level_bitmap, 0xFF, sizeof(a_rule->level_bitmap));
- a_rule->level_bitmap[a_rule->level / 8] &= ~(1 << (7 - a_rule->level % 8));
- break;
- case '*':
- memset(a_rule->level_bitmap, 0xFF, sizeof(a_rule->level_bitmap));
- break;
- case '.':
- memset(a_rule->level_bitmap, 0x00, sizeof(a_rule->level_bitmap));
- a_rule->level_bitmap[a_rule->level / 8] |= ~(0xFF << (8 - a_rule->level % 8));
- memset(a_rule->level_bitmap + a_rule->level / 8 + 1, 0xFF,
- sizeof(a_rule->level_bitmap) - a_rule->level / 8 - 1);
- break;
- }
- /* action ["%H/log/aa.log", 20MB * 12 ; MyTemplate]
- * output ["%H/log/aa.log", 20MB * 12]
- * format [MyTemplate]
- */
- memset(output, 0x00, sizeof(output));
- memset(format_name, 0x00, sizeof(format_name));
- nscan = sscanf(action, " %[^;];%s", output, format_name);
- if (nscan < 1) {
- zc_error("sscanf [%s] fail", action);
- goto err;
- }
- /* check and get format */
- if (STRCMP(format_name, ==, "")) {
- zc_debug("no format specified, use default");
- a_rule->format = default_format;
- } else {
- int i;
- int find_flag = 0;
- zlog_format_t *a_format;
- zc_arraylist_foreach(formats, i, a_format) {
- if (zlog_format_has_name(a_format, format_name)) {
- a_rule->format = a_format;
- find_flag = 1;
- break;
- }
- }
- if (!find_flag) {
- zc_error("in conf file can't find format[%s], pls check",
- format_name);
- goto err;
- }
- }
- /* output [-"%E(HOME)/log/aa.log" , 20MB*12] [>syslog , LOG_LOCAL0 ]
- * file_path [-"%E(HOME)/log/aa.log" ] [>syslog ]
- * *file_limit [20MB * 12 ~ "aa.#i.log" ] [LOG_LOCAL0]
- */
- memset(file_path, 0x00, sizeof(file_path));
- nscan = sscanf(output, " %[^,],", file_path);
- if (nscan < 1) {
- zc_error("sscanf [%s] fail", action);
- goto err;
- }
- file_limit = strchr(output, ',');
- if (file_limit) {
- file_limit++; /* skip the , */
- while( isspace(*file_limit) ) {
- file_limit++;
- }
- }
- p = NULL;
- switch (file_path[0]) {
- case '-' :
- /* sync file each time write log */
- if (file_path[1] != '"') {
- zc_error(" - must set before a file output");
- goto err;
- }
- /* no need to fsync, as file is opened by O_SYNC, write immediately */
- a_rule->fsync_period = 0;
- p = file_path + 1;
- a_rule->file_open_flags = O_SYNC;
- /* fall through */
- case '"' :
- if (!p) p = file_path;
- rc = zlog_rule_parse_path(p, a_rule->file_path, sizeof(a_rule->file_path),
- &(a_rule->dynamic_specs), time_cache_count);
- if (rc) {
- zc_error("zlog_rule_parse_path fail");
- goto err;
- }
- if (file_limit) {
- memset(archive_max_size, 0x00, sizeof(archive_max_size));
- nscan = sscanf(file_limit, " %[0-9MmKkBb] * %d ~",
- archive_max_size, &(a_rule->archive_max_count));
- if (nscan) {
- a_rule->archive_max_size = zc_parse_byte_size(archive_max_size);
- }
- p = strchr(file_limit, '"');
- if (p) { /* archive file path exist */
- rc = zlog_rule_parse_path(p,
- a_rule->archive_path, sizeof(a_rule->file_path),
- &(a_rule->archive_specs), time_cache_count);
- if (rc) {
- zc_error("zlog_rule_parse_path fail");
- goto err;
- }
- p = strchr(a_rule->archive_path, '#');
- if ( (p == NULL) || ((strchr(p, 'r') == NULL) && (strchr(p, 's') == NULL))) {
- zc_error("archive_path must contain #r or #s");
- goto err;
- }
- }
- }
- /* try to figure out if the log file path is dynamic or static */
- if (a_rule->dynamic_specs) {
- if (a_rule->archive_max_size <= 0) {
- a_rule->output = zlog_rule_output_dynamic_file_single;
- } else {
- a_rule->output = zlog_rule_output_dynamic_file_rotate;
- }
- } else {
- struct stat stb;
- if (a_rule->archive_max_size <= 0) {
- a_rule->output = zlog_rule_output_static_file_single;
- } else {
- /* as rotate, so need to reopen everytime */
- a_rule->output = zlog_rule_output_static_file_rotate;
- }
- a_rule->static_fd = open(a_rule->file_path,
- O_WRONLY | O_APPEND | O_CREAT | a_rule->file_open_flags,
- a_rule->file_perms);
- if (a_rule->static_fd < 0) {
- zc_error("open file[%s] fail, errno[%d]", a_rule->file_path, errno);
- goto err;
- }
- /* save off the inode information for checking for a changed file later on */
- if (fstat(a_rule->static_fd, &stb)) {
- zc_error("stat [%s] fail, errno[%d], failing to open static_fd", a_rule->file_path, errno);
- goto err;
- }
- if (a_rule->archive_max_size > 0) {
- close(a_rule->static_fd);
- a_rule->static_fd = -1;
- }
- a_rule->static_dev = stb.st_dev;
- a_rule->static_ino = stb.st_ino;
- }
- break;
- case '|' :
- a_rule->pipe_fp = popen(output + 1, "w");
- if (!a_rule->pipe_fp) {
- zc_error("popen fail, errno[%d]", errno);
- goto err;
- }
- a_rule->pipe_fd = fileno(a_rule->pipe_fp);
- if (a_rule->pipe_fd < 0 ) {
- zc_error("fileno fail, errno[%d]", errno);
- goto err;
- }
- a_rule->output = zlog_rule_output_pipe;
- break;
- case '>' :
- if (STRNCMP(file_path + 1, ==, "syslog", 6)) {
- a_rule->syslog_facility = syslog_facility_atoi(file_limit);
- if (a_rule->syslog_facility == -187) {
- zc_error("-187 get");
- goto err;
- }
- a_rule->output = zlog_rule_output_syslog;
- openlog(NULL, LOG_NDELAY | LOG_NOWAIT | LOG_PID, LOG_USER);
- } else if (STRNCMP(file_path + 1, ==, "stdout", 6)) {
- a_rule->output = zlog_rule_output_stdout;
- } else if (STRNCMP(file_path + 1, ==, "stderr", 6)) {
- a_rule->output = zlog_rule_output_stderr;
- } else {
- zc_error
- ("[%s]the string after is not syslog, stdout or stderr", output);
- goto err;
- }
- break;
- case '$' :
- sscanf(file_path + 1, "%s", a_rule->record_name);
-
- if (file_limit) { /* record path exists */
- p = strchr(file_limit, '"');
- if (!p) {
- zc_error("record_path not start with \", [%s]", file_limit);
- goto err;
- }
- p++; /* skip 1st " */
- q = strrchr(p, '"');
- if (!q) {
- zc_error("matching \" not found in conf line[%s]", p);
- goto err;
- }
- len = q - p;
- if (len > sizeof(a_rule->record_path) - 1) {
- zc_error("record_path too long %ld > %ld", len, sizeof(a_rule->record_path) - 1);
- goto err;
- }
- memcpy(a_rule->record_path, p, len);
- }
- /* replace any environment variables like %E(HOME) */
- rc = zc_str_replace_env(a_rule->record_path, sizeof(a_rule->record_path));
- if (rc) {
- zc_error("zc_str_replace_env fail");
- goto err;
- }
- /* try to figure out if the log file path is dynamic or static */
- if (strchr(a_rule->record_path, '%') == NULL) {
- a_rule->output = zlog_rule_output_static_record;
- } else {
- zlog_spec_t *a_spec;
- a_rule->output = zlog_rule_output_dynamic_record;
- a_rule->dynamic_specs = zc_arraylist_new((zc_arraylist_del_fn)zlog_spec_del);
- if (!(a_rule->dynamic_specs)) {
- zc_error("zc_arraylist_new fail");
- goto err;
- }
- for (p = a_rule->record_path; *p != '\0'; p = q) {
- a_spec = zlog_spec_new(p, &q, time_cache_count);
- if (!a_spec) {
- zc_error("zlog_spec_new fail");
- goto err;
- }
- rc = zc_arraylist_add(a_rule->dynamic_specs, a_spec);
- if (rc) {
- zlog_spec_del(a_spec);
- zc_error("zc_arraylist_add fail");
- goto err;
- }
- }
- }
- break;
- default :
- zc_error("the 1st char[%c] of file_path[%s] is wrong",
- file_path[0], file_path);
- goto err;
- }
- return a_rule;
- err:
- zlog_rule_del(a_rule);
- return NULL;
- }
- void zlog_rule_del(zlog_rule_t * a_rule)
- {
- zc_assert(a_rule,);
- if (a_rule->dynamic_specs) {
- zc_arraylist_del(a_rule->dynamic_specs);
- a_rule->dynamic_specs = NULL;
- }
- if (a_rule->static_fd > 0) {
- if (close(a_rule->static_fd)) {
- zc_error("close fail, maybe cause by write, errno[%d]", errno);
- }
- }
- if (a_rule->pipe_fp) {
- if (pclose(a_rule->pipe_fp) == -1) {
- zc_error("pclose fail, errno[%d]", errno);
- }
- }
- if (a_rule->archive_specs) {
- zc_arraylist_del(a_rule->archive_specs);
- a_rule->archive_specs = NULL;
- }
- zc_debug("zlog_rule_del[%p]", a_rule);
- free(a_rule);
- return;
- }
- /*******************************************************************************/
- int zlog_rule_output(zlog_rule_t * a_rule, zlog_thread_t * a_thread)
- {
- switch (a_rule->compare_char) {
- case '*' :
- return a_rule->output(a_rule, a_thread);
- break;
- case '.' :
- if (a_thread->event->level >= a_rule->level) {
- return a_rule->output(a_rule, a_thread);
- } else {
- return 0;
- }
- break;
- case '=' :
- if (a_thread->event->level == a_rule->level) {
- return a_rule->output(a_rule, a_thread);
- } else {
- return 0;
- }
- break;
- case '!' :
- if (a_thread->event->level != a_rule->level) {
- return a_rule->output(a_rule, a_thread);
- } else {
- return 0;
- }
- break;
- }
- return 0;
- }
- /*******************************************************************************/
- int zlog_rule_is_wastebin(zlog_rule_t * a_rule)
- {
- zc_assert(a_rule, -1);
-
- if (STRCMP(a_rule->category, ==, "!")) {
- return 1;
- }
- return 0;
- }
- /*******************************************************************************/
- int zlog_rule_match_category(zlog_rule_t * a_rule, char *category)
- {
- zc_assert(a_rule, -1);
- zc_assert(category, -1);
- if (STRCMP(a_rule->category, ==, "*")) {
- /* '*' match anything, so go on */
- return 1;
- } else if (STRCMP(a_rule->category, ==, category)) {
- /* accurate compare */
- return 1;
- } else {
- /* aa_ match aa_xx & aa, but not match aa1_xx */
- size_t len;
- len = strlen(a_rule->category);
- if (a_rule->category[len - 1] == '_') {
- if (strlen(category) == len - 1) {
- len--;
- }
- if (STRNCMP(a_rule->category, ==, category, len)) {
- return 1;
- }
- }
- }
- return 0;
- }
- /*******************************************************************************/
- int zlog_rule_set_record(zlog_rule_t * a_rule, zc_hashtable_t *records)
- {
- zlog_record_t *a_record;
- if (a_rule->output != zlog_rule_output_static_record
- && a_rule->output != zlog_rule_output_dynamic_record) {
- return 0; /* fliter, may go through not record rule */
- }
- a_record = zc_hashtable_get(records, a_rule->record_name);
- if (a_record) {
- a_rule->record_func = a_record->output;
- }
- return 0;
- }
|