用cmake来组织
parent
f8439d8dc9
commit
5676995840
@ -0,0 +1,13 @@
|
|||||||
|
include_directories("${OpenCV_INCLUDE_DIRS}")
|
||||||
|
set(DEHAZE01_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||||
|
set(DEHAZE01_INCLUDE_DIR ${DEHAZE01_INCLUDE_DIR} PARENT_SCOPE)
|
||||||
|
add_library( # Sets the name of the library.
|
||||||
|
LIB_DEHAZE01
|
||||||
|
SHARED
|
||||||
|
dehazing.cpp
|
||||||
|
Transmission.cpp
|
||||||
|
guidedfilter.cpp
|
||||||
|
functions.cpp
|
||||||
|
)
|
||||||
|
install (TARGETS LIB_DEHAZE01 DESTINATION lib)
|
||||||
|
install (FILES dehazing.h DESTINATION include)
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
版权所有 (C), 2001-2014,
|
||||||
|
******************************************************************************
|
||||||
|
文 件 名 : log_manger.h
|
||||||
|
版 本 号 : 初稿
|
||||||
|
作 者 : fensjoy
|
||||||
|
生成日期 : 2013年6月5日 星期三
|
||||||
|
最近修改 :
|
||||||
|
功能描述 : log_manger.cpp 的头文件
|
||||||
|
函数列表 :
|
||||||
|
修改历史 :
|
||||||
|
1.日 期 : 2013年6月5日 星期三
|
||||||
|
作 者 : fensjoy
|
||||||
|
修改内容 : 创建文件
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef __LOG_MANGER_H__
|
||||||
|
#define ___LOG_MANGER_H__
|
||||||
|
#include <iostream>
|
||||||
|
#include "zlog.h"
|
||||||
|
#define PRO_NAME "#[db]: "
|
||||||
|
#define LOG_CONFIG "zlog.conf"
|
||||||
|
#define LOG_PATH "./"
|
||||||
|
#define LOG_CAT "my_cat" //注意这里要与配置文件中保持一致,否则无法输出
|
||||||
|
|
||||||
|
//extern zlog_category_t * logHandler_m;
|
||||||
|
zlog_category_t * Init_zlog();
|
||||||
|
zlog_category_t * getZlogHandler();
|
||||||
|
zlog_category_t *log_c = Init_zlog();
|
||||||
|
#define log_fatal(arg...) zlog_fatal(log_c,##arg)
|
||||||
|
#define log_notice(arg...) zlog_notice(log_c,##arg)
|
||||||
|
#define log_info(arg...) zlog_info(log_c,##arg)
|
||||||
|
#define log_debug(arg...) zlog_debug(log_c,##arg)
|
||||||
|
#define log_warn(arg...) zlog_warn(log_c,##arg)
|
||||||
|
#define log_error(arg...) zlog_error(log_c,##arg)
|
||||||
|
#endif /* __LOG_MANGER_H__ */
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
.*
|
||||||
|
!.gitignore
|
||||||
|
|
||||||
|
*.o
|
||||||
|
*.lo
|
||||||
|
*.la
|
||||||
|
*.gcda
|
||||||
|
*.gcno
|
||||||
|
aclocal.m4
|
||||||
|
autom4te.cache
|
||||||
|
build
|
||||||
|
compile
|
||||||
|
config.guess
|
||||||
|
config.h
|
||||||
|
config.h.in
|
||||||
|
config.h.in~
|
||||||
|
config.log
|
||||||
|
config.status
|
||||||
|
config.sub
|
||||||
|
configure
|
||||||
|
depcomp
|
||||||
|
.deps
|
||||||
|
install-sh
|
||||||
|
.libs
|
||||||
|
libtool
|
||||||
|
libzlog.so*
|
||||||
|
libzlog.a*
|
||||||
|
ltmain.sh
|
||||||
|
Makefile
|
||||||
|
Makefile.in
|
||||||
|
missing
|
||||||
|
stamp-h1
|
||||||
|
tags
|
||||||
|
TAGS
|
||||||
|
zlog-chk-conf
|
||||||
|
zlog-*.tar.gz
|
||||||
|
zlog.pc
|
||||||
|
callgrind*
|
||||||
|
err.log
|
||||||
|
test_*
|
||||||
|
!test_*.c
|
||||||
|
!test_*.conf
|
||||||
|
!test_*.h
|
||||||
|
doc/*.lyx~
|
||||||
|
doc/*.pdf
|
||||||
|
doc/obj.think
|
||||||
|
doc/zlog.3
|
||||||
|
doc/zlogtest.xls
|
||||||
|
doc/*.haux
|
||||||
|
doc/*.html
|
||||||
|
doc/*.htoc
|
||||||
|
doc/*.tex
|
||||||
|
test/press*
|
||||||
|
test/*.png
|
||||||
|
release.h
|
||||||
|
*.dylib
|
||||||
@ -0,0 +1 @@
|
|||||||
|
README.md
|
||||||
@ -0,0 +1,121 @@
|
|||||||
|
0. What is zlog?
|
||||||
|
-------------
|
||||||
|
|
||||||
|
zlog is a reliable, high-performance, thread safe, flexible, clear-model, pure C logging library.
|
||||||
|
|
||||||
|
Actually, in the C world there was NO good logging library for applications like logback in java or log4cxx in c++. Using printf can work, but can not be redirected or reformatted easily. syslog is slow and is designed for system use.
|
||||||
|
So I wrote zlog.
|
||||||
|
It is faster, safer and more powerful than log4c. So it can be widely used.
|
||||||
|
|
||||||
|
1. Install
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Downloads: https://github.com/HardySimpson/zlog/releases
|
||||||
|
|
||||||
|
$ tar -zxvf zlog-latest-stable.tar.gz
|
||||||
|
$ cd zlog-latest-stable/
|
||||||
|
$ make
|
||||||
|
$ sudo make install
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
$ make PREFIX=/usr/local/
|
||||||
|
$ sudo make PREFIX=/usr/local/ install
|
||||||
|
|
||||||
|
PREFIX indicates the installation destination for zlog. After installation, refresh your dynamic linker to make sure your program can find zlog library.
|
||||||
|
|
||||||
|
$ sudo vi /etc/ld.so.conf
|
||||||
|
/usr/local/lib
|
||||||
|
$ sudo ldconfig
|
||||||
|
|
||||||
|
Before running a real program, make sure libzlog.so is in the directory where the system's dynamic lib loader can find it. The command metioned above are for linux. Other systems will need a similar set of actions.
|
||||||
|
|
||||||
|
|
||||||
|
2. Introduce configure file
|
||||||
|
-------------
|
||||||
|
|
||||||
|
There are 3 important concepts in zlog: categories, formats and rules.
|
||||||
|
|
||||||
|
Categories specify different kinds of log entries. In the zlog source code, category is a (zlog_cateogory_t *) variable. In your program, different categories for the log entries will distinguish them from each other.
|
||||||
|
|
||||||
|
Formats describe log patterns, such as: with or without time stamp, source file, source line.
|
||||||
|
|
||||||
|
Rules consist of category, level, output file (or other channel) and format. In brief, if the category string in a rule in the configuration file equals the name of a category variable in the source, then they match. Still there is complex match range of category. Rule decouples variable conditions. For example, log4j must specify a level for each logger(or inherit from father logger). That's not convenient when each grade of logger has its own level for output(child logger output at the level of debug, when father logger output at the level of error)
|
||||||
|
|
||||||
|
Now create a configuration file. The function zlog_init takes the files path as its only argument.
|
||||||
|
$ cat /etc/zlog.conf
|
||||||
|
|
||||||
|
[formats]
|
||||||
|
simple = "%m%n"
|
||||||
|
[rules]
|
||||||
|
my_cat.DEBUG >stdout; simple
|
||||||
|
|
||||||
|
In the configuration file log messages in the category "my_cat" and a level of DEBUG or higher are output to standard output, with the format of simple(%m - usermessage %n - newline). If you want to direct out to a file and limit the files maximum size, use this configuration
|
||||||
|
|
||||||
|
my_cat.DEBUG "/var/log/aa.log", 1M; simple
|
||||||
|
|
||||||
|
3. Using zlog API in C source file
|
||||||
|
-------------
|
||||||
|
$ vi test_hello.c
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "zlog.h"
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
zlog_category_t *c;
|
||||||
|
|
||||||
|
rc = zlog_init("/etc/zlog.conf");
|
||||||
|
if (rc) {
|
||||||
|
printf("init failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = zlog_get_category("my_cat");
|
||||||
|
if (!c) {
|
||||||
|
printf("get cat fail\n");
|
||||||
|
zlog_fini();
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
zlog_info(c, "hello, zlog");
|
||||||
|
|
||||||
|
zlog_fini();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
4. Compile, and run it!
|
||||||
|
-------------
|
||||||
|
$ cc -c -o test_hello.o test_hello.c -I/usr/local/include
|
||||||
|
$ cc -o test_hello test_hello.o -L/usr/local/lib -lzlog -lpthread
|
||||||
|
$ ./test_hello
|
||||||
|
hello, zlog
|
||||||
|
|
||||||
|
5. Advanced Usage
|
||||||
|
-------------
|
||||||
|
* syslog model, better than log4j model
|
||||||
|
* log format customization
|
||||||
|
* multiple output destinations including static file path, dynamic file path, stdout, stderr, syslog, user-defined ouput
|
||||||
|
* runtime manually or automatically refresh configure(safely)
|
||||||
|
* high-performance, 250'000 logs/second on my laptop, about 1000 times faster than syslog(3) with rsyslogd
|
||||||
|
* user-defined log level
|
||||||
|
* thread-safe and process-safe log file rotation
|
||||||
|
* microsecond accuracy
|
||||||
|
* dzlog, a default category log API for easy use
|
||||||
|
* MDC, a log4j style key-value map
|
||||||
|
* self debuggable, can output zlog's self debug&error log at runtime
|
||||||
|
* No external dependencies, just based on a POSIX system and a C99 compliant vsnprintf.
|
||||||
|
|
||||||
|
6.Links:
|
||||||
|
-------------
|
||||||
|
* Homepage: http://hardysimpson.github.com/zlog
|
||||||
|
* Downloads: https://github.com/HardySimpson/zlog/releases
|
||||||
|
* Author's Email: HardySimpson1984@gmail.com
|
||||||
|
* auto tools version: https://github.com/bmanojlovic/zlog
|
||||||
|
* cmake verion: https://github.com/lisongmin/zlog
|
||||||
|
* windows version: https://github.com/lopsd07/WinZlog
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,114 @@
|
|||||||
|
0. What is zlog?
|
||||||
|
|
||||||
|
zlog is a reliable, high-performance, thread safe, flexible, clear-model, pure C logging library.
|
||||||
|
|
||||||
|
Actually, in the C world there was NO good logging library for applications like logback in java or log4cxx in c++. Using printf can work, but can not be redirected or reformatted easily. syslog is slow and is designed for system use.
|
||||||
|
So I wrote zlog.
|
||||||
|
It is faster, safer and more powerful than log4c. So it can be widely used.
|
||||||
|
|
||||||
|
1. Install
|
||||||
|
|
||||||
|
Downloads: https://github.com/HardySimpson/zlog/releases
|
||||||
|
|
||||||
|
$ tar -zxvf zlog-latest-stable.tar.gz
|
||||||
|
$ cd zlog-latest-stable/
|
||||||
|
$ make
|
||||||
|
$ sudo make install
|
||||||
|
or
|
||||||
|
$ make PREFIX=/usr/local/
|
||||||
|
$ sudo make PREFIX=/usr/local/ install
|
||||||
|
|
||||||
|
PREFIX indicates the installation destination for zlog. After installation, refresh your dynamic linker to make sure your program can find zlog library.
|
||||||
|
|
||||||
|
$ sudo vi /etc/ld.so.conf
|
||||||
|
/usr/local/lib
|
||||||
|
$ sudo ldconfig
|
||||||
|
|
||||||
|
Before running a real program, make sure libzlog.so is in the directory where the system's dynamic lib loader can find it. The command metioned above are for linux. Other systems will need a similar set of actions.
|
||||||
|
|
||||||
|
|
||||||
|
2. Introduce configure file
|
||||||
|
|
||||||
|
There are 3 important concepts in zlog: categories, formats and rules.
|
||||||
|
|
||||||
|
Categories specify different kinds of log entries. In the zlog source code, category is a (zlog_cateogory_t *) variable. In your program, different categories for the log entries will distinguish them from each other.
|
||||||
|
|
||||||
|
Formats describe log patterns, such as: with or without time stamp, source file, source line.
|
||||||
|
|
||||||
|
Rules consist of category, level, output file (or other channel) and format. In brief, if the category string in a rule in the configuration file equals the name of a category variable in the source, then they match. Still there is complex match range of category. Rule decouples variable conditions. For example, log4j must specify a level for each logger(or inherit from father logger). That's not convenient when each grade of logger has its own level for output(child logger output at the level of debug, when father logger output at the level of error)
|
||||||
|
|
||||||
|
Now create a configuration file. The function zlog_init takes the files path as its only argument.
|
||||||
|
$ cat /etc/zlog.conf
|
||||||
|
|
||||||
|
[formats]
|
||||||
|
simple = "%m%n"
|
||||||
|
[rules]
|
||||||
|
my_cat.DEBUG >stdout; simple
|
||||||
|
|
||||||
|
In the configuration file log messages in the category "my_cat" and a level of DEBUG or higher are output to standard output, with the format of simple(%m - usermessage %n - newline). If you want to direct out to a file and limit the files maximum size, use this configuration
|
||||||
|
|
||||||
|
my_cat.DEBUG "/var/log/aa.log", 1M; simple
|
||||||
|
|
||||||
|
3. Using zlog API in C source file
|
||||||
|
$ vi test_hello.c
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "zlog.h"
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
zlog_category_t *c;
|
||||||
|
|
||||||
|
rc = zlog_init("/etc/zlog.conf");
|
||||||
|
if (rc) {
|
||||||
|
printf("init failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = zlog_get_category("my_cat");
|
||||||
|
if (!c) {
|
||||||
|
printf("get cat fail\n");
|
||||||
|
zlog_fini();
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
zlog_info(c, "hello, zlog");
|
||||||
|
|
||||||
|
zlog_fini();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
4. Complie, and run it!s
|
||||||
|
|
||||||
|
$ cc -c -o test_hello.o test_hello.c -I/usr/local/include
|
||||||
|
$ cc -o test_hello test_hello.o -L/usr/local/lib -lzlog -lpthread
|
||||||
|
$ ./test_hello
|
||||||
|
hello, zlog
|
||||||
|
|
||||||
|
5. Advanced Usage
|
||||||
|
* syslog model, better than log4j model
|
||||||
|
* log format customization
|
||||||
|
* multiple output destinations including static file path, dynamic file path, stdout, stderr, syslog, user-defined ouput
|
||||||
|
* runtime manually or automatically refresh configure(safely)
|
||||||
|
* high-performance, 250'000 logs/second on my laptop, about 1000 times faster than syslog(3) with rsyslogd
|
||||||
|
* user-defined log level
|
||||||
|
* thread-safe and process-safe log file rotation
|
||||||
|
* microsecond accuracy
|
||||||
|
* dzlog, a default category log API for easy use
|
||||||
|
* MDC, a log4j style key-value map
|
||||||
|
* self debuggable, can output zlog's self debug&error log at runtime
|
||||||
|
* No external dependencies, just based on a POSIX system and a C99 compliant vsnprintf.
|
||||||
|
|
||||||
|
|
||||||
|
6. Links:
|
||||||
|
|
||||||
|
Homepage: http://hardysimpson.github.com/zlog
|
||||||
|
Downloads: https://github.com/HardySimpson/zlog/releases
|
||||||
|
Author's Email: HardySimpson1984@gmail.com
|
||||||
|
|
||||||
|
auto tools version: https://github.com/bmanojlovic/zlog
|
||||||
|
cmake verion: https://github.com/lisongmin/zlog
|
||||||
|
windows version: https://github.com/lopsd07/WinZlog
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,27 @@
|
|||||||
|
doc = \
|
||||||
|
UsersGuide-EN.pdf \
|
||||||
|
UsersGuide-CN.pdf \
|
||||||
|
UsersGuide-EN.tex \
|
||||||
|
UsersGuide-CN.tex \
|
||||||
|
UsersGuide-EN.html \
|
||||||
|
UsersGuide-CN.html \
|
||||||
|
GettingStart-EN.txt \
|
||||||
|
GettingStart-CN.txt
|
||||||
|
|
||||||
|
all : $(doc)
|
||||||
|
|
||||||
|
UsersGuide-EN.pdf : UsersGuide-EN.lyx
|
||||||
|
lyx -f -e pdf2 $^
|
||||||
|
|
||||||
|
UsersGuide-CN.pdf : UsersGuide-CN.lyx
|
||||||
|
lyx -f -e pdf4 $^
|
||||||
|
|
||||||
|
%.tex : %.lyx
|
||||||
|
lyx -f -e pdflatex $<
|
||||||
|
|
||||||
|
%.html : %.tex
|
||||||
|
hevea book.hva -s $<
|
||||||
|
hevea book.hva -s $<
|
||||||
|
|
||||||
|
clean :
|
||||||
|
-rm -f *.pdf *.haux *.html *.htoc *.tex *.lyx~
|
||||||
@ -0,0 +1,92 @@
|
|||||||
|
-------------------------------------------------
|
||||||
|
using makefile.linux for test, libzlog compile in O2
|
||||||
|
-------------------------------------------------
|
||||||
|
[direct write, no logging library] - The Sky!
|
||||||
|
$ time ./test_press_write 1 10 100000
|
||||||
|
real 0m1.872s
|
||||||
|
user 0m0.140s
|
||||||
|
sys 0m3.290s
|
||||||
|
|
||||||
|
$ time ./test_press_write2 1 10 100000
|
||||||
|
real 0m0.909s
|
||||||
|
user 0m0.080s
|
||||||
|
sys 0m1.710s
|
||||||
|
-------------------------------------------------
|
||||||
|
v1.1.1 (fwrite is not atomic, so backup to write)
|
||||||
|
$ time ./test_press_zlog 1 10 100000
|
||||||
|
real 0m2.334s
|
||||||
|
user 0m1.780s
|
||||||
|
sys 0m2.710s
|
||||||
|
|
||||||
|
$ time ./test_press_zlog2 1 10 100000
|
||||||
|
real 0m2.134s
|
||||||
|
user 0m1.840s
|
||||||
|
sys 0m1.990s
|
||||||
|
-------------------------------------------------
|
||||||
|
v1.1.0
|
||||||
|
$ time ./test_press_zlog 1 10 100000
|
||||||
|
real 0m1.107s
|
||||||
|
user 0m1.500s
|
||||||
|
sys 0m0.340s
|
||||||
|
|
||||||
|
$ time ./test_press_zlog2 1 10 100000
|
||||||
|
real 0m0.898s
|
||||||
|
user 0m1.480s
|
||||||
|
sys 0m0.150s
|
||||||
|
-------------------------------------------------
|
||||||
|
v1.0.7
|
||||||
|
$ time ./test_press_zlog 1 10 100000
|
||||||
|
real 0m1.783s
|
||||||
|
user 0m3.000s
|
||||||
|
sys 0m0.300s
|
||||||
|
|
||||||
|
$ time ./test_press_zlog2 1 10 100000
|
||||||
|
real 0m1.621s
|
||||||
|
user 0m2.980s
|
||||||
|
sys 0m0.120s
|
||||||
|
-------------------------------------------------
|
||||||
|
v1.0.6
|
||||||
|
$ time ./test_press_zlog 1 10 100000
|
||||||
|
real 0m1.814s
|
||||||
|
user 0m3.060s
|
||||||
|
sys 0m0.270s
|
||||||
|
|
||||||
|
$ time ./test_press_zlog2 1 10 100000
|
||||||
|
real 0m1.605s
|
||||||
|
user 0m2.990s
|
||||||
|
sys 0m0.140s
|
||||||
|
-------------------------------------------------
|
||||||
|
v1.0.5
|
||||||
|
$ time ./test_press_zlog 1 10 100000
|
||||||
|
real 0m2.779s
|
||||||
|
user 0m4.170s
|
||||||
|
sys 0m0.560s
|
||||||
|
|
||||||
|
$ time ./test_press_zlog2 1 10 100000
|
||||||
|
real 0m2.713s
|
||||||
|
user 0m4.410s
|
||||||
|
sys 0m0.900s
|
||||||
|
-------------------------------------------------
|
||||||
|
v1.0.3
|
||||||
|
$ time ./test_press_zlog 1 10 100000
|
||||||
|
|
||||||
|
real 0m6.349s
|
||||||
|
user 0m6.300s
|
||||||
|
sys 0m5.950s
|
||||||
|
|
||||||
|
$ time ./test_press_zlog2 1 10 100000
|
||||||
|
real 0m6.377s
|
||||||
|
user 0m6.240s
|
||||||
|
sys 0m6.090s
|
||||||
|
-------------------------------------------------
|
||||||
|
v1.0.0
|
||||||
|
$ time ./test_press_zlog 1 10 100000
|
||||||
|
real 0m6.364s
|
||||||
|
user 0m6.040s
|
||||||
|
sys 0m6.270s
|
||||||
|
|
||||||
|
$ time ./test_press_zlog2 1 10 100000
|
||||||
|
real 0m6.361s
|
||||||
|
user 0m6.150s
|
||||||
|
sys 0m6.020s
|
||||||
|
-------------------------------------------------
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
[global]
|
||||||
|
strict init = true
|
||||||
|
reload conf period = 10M
|
||||||
|
|
||||||
|
buffer min = 1024
|
||||||
|
buffer max = 2MB
|
||||||
|
|
||||||
|
#rotate lock file = /tmp/zlog.lock
|
||||||
|
rotate lock file = self
|
||||||
|
default format = "%d(%F %T.%l) %-6V (%c:%F:%L) - %m%n"
|
||||||
|
|
||||||
|
file perms = 600
|
||||||
|
fsync period = 1K
|
||||||
|
|
||||||
|
[levels]
|
||||||
|
TRACE = 10
|
||||||
|
CRIT = 130, LOG_CRIT
|
||||||
|
|
||||||
|
[formats]
|
||||||
|
simple = "%m%n"
|
||||||
|
normal = "%d(%F %T.%l) %m%n"
|
||||||
|
|
||||||
|
[rules]
|
||||||
|
default.* >stdout; simple
|
||||||
|
|
||||||
|
*.* -"%12.2E(HOME)/log/%c.log", \
|
||||||
|
1MB * 12 ~ "%E(HOME)/log/%c.%D(%F) #2r #3s.log"; \
|
||||||
|
simple
|
||||||
|
|
||||||
|
my_.INFO >stderr;
|
||||||
|
my_cat.!ERROR "aa.log"
|
||||||
|
my_dog.=DEBUG >syslog, LOG_LOCAL0; simple
|
||||||
|
my_dog.=DEBUG | /usr/bin/cronolog /www/logs/example_%Y%m%d.log ; normal
|
||||||
|
my_mice.* $record_func , "record_path%c"; normal
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
# Top level makefile, the real shit is at src/makefile
|
||||||
|
|
||||||
|
TARGETS=noopt 32bit
|
||||||
|
|
||||||
|
all:
|
||||||
|
cd src && $(MAKE) $@
|
||||||
|
|
||||||
|
install:
|
||||||
|
cd src && $(MAKE) $@
|
||||||
|
|
||||||
|
$(TARGETS):
|
||||||
|
cd src && $(MAKE) $@
|
||||||
|
|
||||||
|
doc:
|
||||||
|
cd doc && $(MAKE)
|
||||||
|
|
||||||
|
test:
|
||||||
|
cd test && $(MAKE)
|
||||||
|
|
||||||
|
TAGS:
|
||||||
|
find . -type f -name "*.[ch]" | xargs etags -
|
||||||
|
|
||||||
|
clean:
|
||||||
|
cd src && $(MAKE) $@
|
||||||
|
cd test && $(MAKE) $@
|
||||||
|
cd doc && $(MAKE) $@
|
||||||
|
rm -f TAGS
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
|
||||||
|
dummy:
|
||||||
|
|
||||||
|
.PHONY: doc install test TAGS
|
||||||
@ -0,0 +1,649 @@
|
|||||||
|
/*
|
||||||
|
* 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 <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "zc_defs.h"
|
||||||
|
#include "buf.h"
|
||||||
|
/*******************************************************************************/
|
||||||
|
/* Author's Note
|
||||||
|
* This buf.c is base on C99, that is, if buffer size is not enough,
|
||||||
|
* the return value of vsnprintf(3) is a number tell how many character should
|
||||||
|
* be output. vsnprintf in glibc 2.1 conforms to C99 , but glibc 2.0 doesn't.
|
||||||
|
* see manpage of vsnprintf(3) on you platform for more detail.
|
||||||
|
|
||||||
|
* So, what should you do if you want to using zlog on the platform that doesn't
|
||||||
|
* conform C99? My Answer is, crack zlog with a portable C99-vsnprintf, like this
|
||||||
|
* http://sourceforge.net/projects/ctrio/
|
||||||
|
* http://www.jhweiss.de/software/snprintf.html
|
||||||
|
* If you can see this note, you can fix it yourself? Aren't you? ^_^
|
||||||
|
|
||||||
|
* Oh, I put the snprintf in C99 standard here,
|
||||||
|
* vsnprintf is the same on return value.
|
||||||
|
|
||||||
|
7.19.6.5 The snprintf function
|
||||||
|
|
||||||
|
Synopsis
|
||||||
|
|
||||||
|
[#1]
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
int snprintf(char * restrict s, size_t n,
|
||||||
|
const char * restrict format, ...);
|
||||||
|
|
||||||
|
Description
|
||||||
|
|
||||||
|
[#2] The snprintf function is equivalent to fprintf, except
|
||||||
|
that the output is written into an array (specified by
|
||||||
|
argument s) rather than to a stream. If n is zero, nothing
|
||||||
|
is written, and s may be a null pointer. Otherwise, output
|
||||||
|
characters beyond the n-1st are discarded rather than being
|
||||||
|
written to the array, and a null character is written at the
|
||||||
|
end of the characters actually written into the array. If
|
||||||
|
copying takes place between objects that overlap, the
|
||||||
|
behavior is undefined.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
|
||||||
|
[#3] The snprintf function returns the number of characters
|
||||||
|
that would have been written had n been sufficiently large,
|
||||||
|
not counting the terminating null character, or a negative
|
||||||
|
value if an encoding error occurred. Thus, the null-
|
||||||
|
terminated output has been completely written if and only if
|
||||||
|
the returned value is nonnegative and less than n.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
void zlog_buf_profile(zlog_buf_t * a_buf, int flag)
|
||||||
|
{
|
||||||
|
//zc_assert(a_buf,);
|
||||||
|
zc_profile(flag, "---buf[%p][%ld-%ld][%ld][%s][%p:%ld]---",
|
||||||
|
a_buf,
|
||||||
|
a_buf->size_min, a_buf->size_max,
|
||||||
|
a_buf->size_real,
|
||||||
|
a_buf->truncate_str,
|
||||||
|
a_buf->start, a_buf->tail - a_buf->start);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*******************************************************************************/
|
||||||
|
void zlog_buf_del(zlog_buf_t * a_buf)
|
||||||
|
{
|
||||||
|
//zc_assert(a_buf,);
|
||||||
|
if (a_buf->start) free(a_buf->start);
|
||||||
|
zc_debug("zlog_buf_del[%p]", a_buf);
|
||||||
|
free(a_buf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
zlog_buf_t *zlog_buf_new(size_t buf_size_min, size_t buf_size_max, const char *truncate_str)
|
||||||
|
{
|
||||||
|
zlog_buf_t *a_buf;
|
||||||
|
|
||||||
|
if (buf_size_min == 0) {
|
||||||
|
zc_error("buf_size_min == 0, not allowed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf_size_max != 0 && buf_size_max < buf_size_min) {
|
||||||
|
zc_error("buf_size_max[%lu] < buf_size_min[%lu] && buf_size_max != 0",
|
||||||
|
(unsigned long)buf_size_max, (unsigned long)buf_size_min);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_buf = calloc(1, sizeof(*a_buf));
|
||||||
|
if (!a_buf) {
|
||||||
|
zc_error("calloc fail, errno[%d]", errno);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (truncate_str) {
|
||||||
|
if (strlen(truncate_str) > sizeof(a_buf->truncate_str) - 1) {
|
||||||
|
zc_error("truncate_str[%s] overflow", truncate_str);
|
||||||
|
goto err;
|
||||||
|
} else {
|
||||||
|
strcpy(a_buf->truncate_str, truncate_str);
|
||||||
|
}
|
||||||
|
a_buf->truncate_str_len = strlen(truncate_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
a_buf->size_min = buf_size_min;
|
||||||
|
a_buf->size_max = buf_size_max;
|
||||||
|
a_buf->size_real = a_buf->size_min;
|
||||||
|
|
||||||
|
a_buf->start = calloc(1, a_buf->size_real);
|
||||||
|
if (!a_buf->start) {
|
||||||
|
zc_error("calloc fail, errno[%d]", errno);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_buf->tail = a_buf->start;
|
||||||
|
a_buf->end_plus_1 = a_buf->start + a_buf->size_real;
|
||||||
|
a_buf->end = a_buf->end_plus_1 - 1;
|
||||||
|
|
||||||
|
//zlog_buf_profile(a_buf, ZC_DEBUG);
|
||||||
|
return a_buf;
|
||||||
|
|
||||||
|
err:
|
||||||
|
zlog_buf_del(a_buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
static void zlog_buf_truncate(zlog_buf_t * a_buf)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if ((a_buf->truncate_str)[0] == '\0') return;
|
||||||
|
p = (a_buf->tail - a_buf->truncate_str_len);
|
||||||
|
if (p < a_buf->start) p = a_buf->start;
|
||||||
|
len = a_buf->tail - p;
|
||||||
|
memcpy(p, a_buf->truncate_str, len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/* return 0: success
|
||||||
|
* return <0: fail, set size_real to -1;
|
||||||
|
* return >0: by conf limit, can't extend size
|
||||||
|
* increment must > 0
|
||||||
|
*/
|
||||||
|
static int zlog_buf_resize(zlog_buf_t * a_buf, size_t increment)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
size_t new_size = 0;
|
||||||
|
size_t len = 0;
|
||||||
|
char *p = NULL;
|
||||||
|
|
||||||
|
if (a_buf->size_max != 0 && a_buf->size_real >= a_buf->size_max) {
|
||||||
|
zc_error("a_buf->size_real[%ld] >= a_buf->size_max[%ld]",
|
||||||
|
a_buf->size_real, a_buf->size_max);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a_buf->size_max == 0) {
|
||||||
|
/* unlimit */
|
||||||
|
new_size = a_buf->size_real + 1.5 * increment;
|
||||||
|
} else {
|
||||||
|
/* limited */
|
||||||
|
if (a_buf->size_real + increment <= a_buf->size_max) {
|
||||||
|
new_size = a_buf->size_real + increment;
|
||||||
|
} else {
|
||||||
|
new_size = a_buf->size_max;
|
||||||
|
rc = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
len = a_buf->tail - a_buf->start;
|
||||||
|
p = realloc(a_buf->start, new_size);
|
||||||
|
if (!p) {
|
||||||
|
zc_error("realloc fail, errno[%d]", errno);
|
||||||
|
free(a_buf->start);
|
||||||
|
a_buf->start = NULL;
|
||||||
|
a_buf->tail = NULL;
|
||||||
|
a_buf->end = NULL;
|
||||||
|
a_buf->end_plus_1 = NULL;
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
a_buf->start = p;
|
||||||
|
a_buf->tail = p + len;
|
||||||
|
a_buf->size_real = new_size;
|
||||||
|
a_buf->end_plus_1 = a_buf->start + new_size;
|
||||||
|
a_buf->end = a_buf->end_plus_1 - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int zlog_buf_vprintf(zlog_buf_t * a_buf, const char *format, va_list args)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
size_t size_left;
|
||||||
|
int nwrite;
|
||||||
|
|
||||||
|
if (!a_buf->start) {
|
||||||
|
zc_error("pre-use of zlog_buf_resize fail, so can't convert");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_copy(ap, args);
|
||||||
|
size_left = a_buf->end_plus_1 - a_buf->tail;
|
||||||
|
nwrite = vsnprintf(a_buf->tail, size_left, format, ap);
|
||||||
|
if (nwrite >= 0 && nwrite < size_left) {
|
||||||
|
a_buf->tail += nwrite;
|
||||||
|
//*(a_buf->tail) = '\0';
|
||||||
|
return 0;
|
||||||
|
} else if (nwrite < 0) {
|
||||||
|
zc_error("vsnprintf fail, errno[%d]", errno);
|
||||||
|
zc_error("nwrite[%d], size_left[%ld], format[%s]", nwrite, size_left, format);
|
||||||
|
return -1;
|
||||||
|
} else if (nwrite >= size_left) {
|
||||||
|
int rc;
|
||||||
|
//zc_debug("nwrite[%d]>=size_left[%ld],format[%s],resize", nwrite, size_left, format);
|
||||||
|
rc = zlog_buf_resize(a_buf, nwrite - size_left + 1);
|
||||||
|
if (rc > 0) {
|
||||||
|
zc_error("conf limit to %ld, can't extend, so truncate", a_buf->size_max);
|
||||||
|
va_copy(ap, args);
|
||||||
|
size_left = a_buf->end_plus_1 - a_buf->tail;
|
||||||
|
vsnprintf(a_buf->tail, size_left, format, ap);
|
||||||
|
a_buf->tail += size_left - 1;
|
||||||
|
//*(a_buf->tail) = '\0';
|
||||||
|
zlog_buf_truncate(a_buf);
|
||||||
|
return 1;
|
||||||
|
} else if (rc < 0) {
|
||||||
|
zc_error("zlog_buf_resize fail");
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
//zc_debug("zlog_buf_resize succ, to[%ld]", a_buf->size_real);
|
||||||
|
|
||||||
|
va_copy(ap, args);
|
||||||
|
size_left = a_buf->end_plus_1 - a_buf->tail;
|
||||||
|
nwrite = vsnprintf(a_buf->tail, size_left, format, ap);
|
||||||
|
if (nwrite < 0) {
|
||||||
|
zc_error("vsnprintf fail, errno[%d]", errno);
|
||||||
|
zc_error("nwrite[%d], size_left[%ld], format[%s]", nwrite, size_left, format);
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
a_buf->tail += nwrite;
|
||||||
|
//*(a_buf->tail) = '\0';
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/* if width > num_len, 0 padding, else output num */
|
||||||
|
int zlog_buf_printf_dec32(zlog_buf_t * a_buf, uint32_t ui32, int width)
|
||||||
|
{
|
||||||
|
unsigned char *p;
|
||||||
|
char *q;
|
||||||
|
unsigned char tmp[ZLOG_INT32_LEN + 1];
|
||||||
|
size_t num_len, zero_len, out_len;
|
||||||
|
|
||||||
|
if (!a_buf->start) {
|
||||||
|
zc_error("pre-use of zlog_buf_resize fail, so can't convert");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = tmp + ZLOG_INT32_LEN;
|
||||||
|
do {
|
||||||
|
*--p = (unsigned char) (ui32 % 10 + '0');
|
||||||
|
} while (ui32 /= 10);
|
||||||
|
|
||||||
|
/* zero or space padding */
|
||||||
|
num_len = (tmp + ZLOG_INT32_LEN) - p;
|
||||||
|
|
||||||
|
if (width > num_len) {
|
||||||
|
zero_len = width - num_len;
|
||||||
|
out_len = width;
|
||||||
|
} else {
|
||||||
|
zero_len = 0;
|
||||||
|
out_len = num_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((q = a_buf->tail + out_len) > a_buf->end) {
|
||||||
|
int rc;
|
||||||
|
//zc_debug("size_left not enough, resize");
|
||||||
|
rc = zlog_buf_resize(a_buf, out_len - (a_buf->end - a_buf->tail));
|
||||||
|
if (rc > 0) {
|
||||||
|
size_t len_left;
|
||||||
|
zc_error("conf limit to %ld, can't extend, so output", a_buf->size_max);
|
||||||
|
len_left = a_buf->end - a_buf->tail;
|
||||||
|
if (len_left <= zero_len) {
|
||||||
|
zero_len = len_left;
|
||||||
|
num_len = 0;
|
||||||
|
} else if (len_left > zero_len) {
|
||||||
|
/* zero_len not changed */
|
||||||
|
num_len = len_left - zero_len;
|
||||||
|
}
|
||||||
|
if (zero_len) memset(a_buf->tail, '0', zero_len);
|
||||||
|
memcpy(a_buf->tail + zero_len, p, num_len);
|
||||||
|
a_buf->tail += len_left;
|
||||||
|
//*(a_buf->tail) = '\0';
|
||||||
|
zlog_buf_truncate(a_buf);
|
||||||
|
return 1;
|
||||||
|
} else if (rc < 0) {
|
||||||
|
zc_error("zlog_buf_resize fail");
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
//zc_debug("zlog_buf_resize succ, to[%ld]", a_buf->size_real);
|
||||||
|
q = a_buf->tail + out_len; /* re-calculate p*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zero_len) memset(a_buf->tail, '0', zero_len);
|
||||||
|
memcpy(a_buf->tail + zero_len, p, num_len);
|
||||||
|
a_buf->tail = q;
|
||||||
|
//*(a_buf->tail) = '\0';
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*******************************************************************************/
|
||||||
|
int zlog_buf_printf_dec64(zlog_buf_t * a_buf, uint64_t ui64, int width)
|
||||||
|
{
|
||||||
|
unsigned char *p;
|
||||||
|
char *q;
|
||||||
|
unsigned char tmp[ZLOG_INT64_LEN + 1];
|
||||||
|
size_t num_len, zero_len, out_len;
|
||||||
|
uint32_t ui32;
|
||||||
|
|
||||||
|
if (!a_buf->start) {
|
||||||
|
zc_error("pre-use of zlog_buf_resize fail, so can't convert");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = tmp + ZLOG_INT64_LEN;
|
||||||
|
if (ui64 <= ZLOG_MAX_UINT32_VALUE) {
|
||||||
|
/*
|
||||||
|
* To divide 64-bit numbers and to find remainders
|
||||||
|
* on the x86 platform gcc and icc call the libc functions
|
||||||
|
* [u]divdi3() and [u]moddi3(), they call another function
|
||||||
|
* in its turn. On FreeBSD it is the qdivrem() function,
|
||||||
|
* its source code is about 170 lines of the code.
|
||||||
|
* The glibc counterpart is about 150 lines of the code.
|
||||||
|
*
|
||||||
|
* For 32-bit numbers and some divisors gcc and icc use
|
||||||
|
* a inlined multiplication and shifts. For example,
|
||||||
|
* unsigned "i32 / 10" is compiled to
|
||||||
|
*
|
||||||
|
* (i32 * 0xCCCCCCCD) >> 35
|
||||||
|
*/
|
||||||
|
|
||||||
|
ui32 = (uint32_t) ui64;
|
||||||
|
|
||||||
|
do {
|
||||||
|
*--p = (unsigned char) (ui32 % 10 + '0');
|
||||||
|
} while (ui32 /= 10);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
do {
|
||||||
|
*--p = (unsigned char) (ui64 % 10 + '0');
|
||||||
|
} while (ui64 /= 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* zero or space padding */
|
||||||
|
num_len = (tmp + ZLOG_INT64_LEN) - p;
|
||||||
|
|
||||||
|
if (width > num_len) {
|
||||||
|
zero_len = width - num_len;
|
||||||
|
out_len = width;
|
||||||
|
} else {
|
||||||
|
zero_len = 0;
|
||||||
|
out_len = num_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((q = a_buf->tail + out_len) > a_buf->end) {
|
||||||
|
int rc;
|
||||||
|
//zc_debug("size_left not enough, resize");
|
||||||
|
rc = zlog_buf_resize(a_buf, out_len - (a_buf->end - a_buf->tail));
|
||||||
|
if (rc > 0) {
|
||||||
|
size_t len_left;
|
||||||
|
zc_error("conf limit to %ld, can't extend, so output", a_buf->size_max);
|
||||||
|
len_left = a_buf->end - a_buf->tail;
|
||||||
|
if (len_left <= zero_len) {
|
||||||
|
zero_len = len_left;
|
||||||
|
num_len = 0;
|
||||||
|
} else if (len_left > zero_len) {
|
||||||
|
/* zero_len not changed */
|
||||||
|
num_len = len_left - zero_len;
|
||||||
|
}
|
||||||
|
if (zero_len) memset(a_buf->tail, '0', zero_len);
|
||||||
|
memcpy(a_buf->tail + zero_len, p, num_len);
|
||||||
|
a_buf->tail += len_left;
|
||||||
|
//*(a_buf->tail) = '\0';
|
||||||
|
zlog_buf_truncate(a_buf);
|
||||||
|
return 1;
|
||||||
|
} else if (rc < 0) {
|
||||||
|
zc_error("zlog_buf_resize fail");
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
//zc_debug("zlog_buf_resize succ, to[%ld]", a_buf->size_real);
|
||||||
|
q = a_buf->tail + out_len; /* re-calculate p*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zero_len) memset(a_buf->tail, '0', zero_len);
|
||||||
|
memcpy(a_buf->tail + zero_len, p, num_len);
|
||||||
|
a_buf->tail = q;
|
||||||
|
//*(a_buf->tail) = '\0';
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*******************************************************************************/
|
||||||
|
int zlog_buf_printf_hex(zlog_buf_t * a_buf, uint32_t ui32, int width)
|
||||||
|
{
|
||||||
|
unsigned char *p;
|
||||||
|
char *q;
|
||||||
|
unsigned char tmp[ZLOG_INT32_LEN + 1];
|
||||||
|
size_t num_len, zero_len, out_len;
|
||||||
|
static unsigned char hex[] = "0123456789abcdef";
|
||||||
|
//static unsigned char HEX[] = "0123456789ABCDEF";
|
||||||
|
|
||||||
|
if (!a_buf->start) {
|
||||||
|
zc_error("pre-use of zlog_buf_resize fail, so can't convert");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
p = tmp + ZLOG_INT32_LEN;
|
||||||
|
do {
|
||||||
|
/* the "(uint32_t)" cast disables the BCC's warning */
|
||||||
|
*--p = hex[(uint32_t) (ui32 & 0xf)];
|
||||||
|
} while (ui32 >>= 4);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
} else { /* is_hex == 2 */
|
||||||
|
|
||||||
|
do {
|
||||||
|
/* the "(uint32_t)" cast disables the BCC's warning */
|
||||||
|
*--p = HEX[(uint32_t) (ui64 & 0xf)];
|
||||||
|
|
||||||
|
} while (ui64 >>= 4);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* zero or space padding */
|
||||||
|
num_len = (tmp + ZLOG_INT32_LEN) - p;
|
||||||
|
|
||||||
|
if (width > num_len) {
|
||||||
|
zero_len = width - num_len;
|
||||||
|
out_len = width;
|
||||||
|
} else {
|
||||||
|
zero_len = 0;
|
||||||
|
out_len = num_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((q = a_buf->tail + out_len) > a_buf->end) {
|
||||||
|
int rc;
|
||||||
|
//zc_debug("size_left not enough, resize");
|
||||||
|
rc = zlog_buf_resize(a_buf, out_len - (a_buf->end - a_buf->tail));
|
||||||
|
if (rc > 0) {
|
||||||
|
size_t len_left;
|
||||||
|
zc_error("conf limit to %ld, can't extend, so output", a_buf->size_max);
|
||||||
|
len_left = a_buf->end - a_buf->tail;
|
||||||
|
if (len_left <= zero_len) {
|
||||||
|
zero_len = len_left;
|
||||||
|
num_len = 0;
|
||||||
|
} else if (len_left > zero_len) {
|
||||||
|
/* zero_len not changed */
|
||||||
|
num_len = len_left - zero_len;
|
||||||
|
}
|
||||||
|
if (zero_len) memset(a_buf->tail, '0', zero_len);
|
||||||
|
memcpy(a_buf->tail + zero_len, p, num_len);
|
||||||
|
a_buf->tail += len_left;
|
||||||
|
//*(a_buf->tail) = '\0';
|
||||||
|
zlog_buf_truncate(a_buf);
|
||||||
|
return 1;
|
||||||
|
} else if (rc < 0) {
|
||||||
|
zc_error("zlog_buf_resize fail");
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
//zc_debug("zlog_buf_resize succ, to[%ld]", a_buf->size_real);
|
||||||
|
q = a_buf->tail + out_len; /* re-calculate p*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zero_len) memset(a_buf->tail, '0', zero_len);
|
||||||
|
memcpy(a_buf->tail + zero_len, p, num_len);
|
||||||
|
a_buf->tail = q;
|
||||||
|
//*(a_buf->tail) = '\0';
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
int zlog_buf_append(zlog_buf_t * a_buf, const char *str, size_t str_len)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
#if 0
|
||||||
|
if (str_len <= 0 || str == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!a_buf->start) {
|
||||||
|
zc_error("pre-use of zlog_buf_resize fail, so can't convert");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((p = a_buf->tail + str_len) > a_buf->end) {
|
||||||
|
int rc;
|
||||||
|
//zc_debug("size_left not enough, resize");
|
||||||
|
rc = zlog_buf_resize(a_buf, str_len - (a_buf->end - a_buf->tail));
|
||||||
|
if (rc > 0) {
|
||||||
|
size_t len_left;
|
||||||
|
zc_error("conf limit to %ld, can't extend, so output",
|
||||||
|
a_buf->size_max);
|
||||||
|
len_left = a_buf->end - a_buf->tail;
|
||||||
|
memcpy(a_buf->tail, str, len_left);
|
||||||
|
a_buf->tail += len_left;
|
||||||
|
//*(a_buf->tail) = '\0';
|
||||||
|
zlog_buf_truncate(a_buf);
|
||||||
|
return 1;
|
||||||
|
} else if (rc < 0) {
|
||||||
|
zc_error("zlog_buf_resize fail");
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
//zc_debug("zlog_buf_resize succ, to[%ld]", a_buf->size_real);
|
||||||
|
p = a_buf->tail + str_len; /* re-calculate p*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(a_buf->tail, str, str_len);
|
||||||
|
a_buf->tail = p;
|
||||||
|
// *(a_buf->tail) = '\0';
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
int zlog_buf_adjust_append(zlog_buf_t * a_buf, const char *str, size_t str_len,
|
||||||
|
int left_adjust, int zero_pad, size_t in_width, size_t out_width)
|
||||||
|
{
|
||||||
|
size_t append_len = 0;
|
||||||
|
size_t source_len = 0;
|
||||||
|
size_t space_len = 0;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (str_len <= 0 || str == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!a_buf->start) {
|
||||||
|
zc_error("pre-use of zlog_buf_resize fail, so can't convert");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate how many character will be got from str */
|
||||||
|
if (out_width == 0 || str_len < out_width) {
|
||||||
|
source_len = str_len;
|
||||||
|
} else {
|
||||||
|
source_len = out_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate how many character will be output */
|
||||||
|
if (in_width == 0 || source_len >= in_width ) {
|
||||||
|
append_len = source_len;
|
||||||
|
space_len = 0;
|
||||||
|
} else {
|
||||||
|
append_len = in_width;
|
||||||
|
space_len = in_width - source_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* |-----append_len-----------| */
|
||||||
|
/* |-source_len---|-space_len-| left_adjust */
|
||||||
|
/* |-space_len---|-source_len-| right_adjust */
|
||||||
|
/* |-(size_real-1)---| size not enough */
|
||||||
|
|
||||||
|
if (append_len > a_buf->end - a_buf->tail) {
|
||||||
|
int rc = 0;
|
||||||
|
//zc_debug("size_left not enough, resize");
|
||||||
|
rc = zlog_buf_resize(a_buf, append_len - (a_buf->end -a_buf->tail));
|
||||||
|
if (rc > 0) {
|
||||||
|
zc_error("conf limit to %ld, can't extend, so output", a_buf->size_max);
|
||||||
|
append_len = (a_buf->end - a_buf->tail);
|
||||||
|
if (left_adjust) {
|
||||||
|
if (source_len < append_len) {
|
||||||
|
space_len = append_len - source_len;
|
||||||
|
} else {
|
||||||
|
source_len = append_len;
|
||||||
|
space_len = 0;
|
||||||
|
}
|
||||||
|
if (space_len) memset(a_buf->tail + source_len, ' ', space_len);
|
||||||
|
memcpy(a_buf->tail, str, source_len);
|
||||||
|
} else {
|
||||||
|
if (space_len < append_len) {
|
||||||
|
source_len = append_len - space_len;
|
||||||
|
} else {
|
||||||
|
space_len = append_len;
|
||||||
|
source_len = 0;
|
||||||
|
}
|
||||||
|
if (space_len) {
|
||||||
|
if (zero_pad) {
|
||||||
|
memset(a_buf->tail, '0', space_len);
|
||||||
|
} else {
|
||||||
|
memset(a_buf->tail, ' ', space_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
memcpy(a_buf->tail + space_len, str, source_len);
|
||||||
|
}
|
||||||
|
a_buf->tail += append_len;
|
||||||
|
//*(a_buf->tail) = '\0';
|
||||||
|
zlog_buf_truncate(a_buf);
|
||||||
|
return 1;
|
||||||
|
} else if (rc < 0) {
|
||||||
|
zc_error("zlog_buf_resize fail");
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
//zc_debug("zlog_buf_resize succ, to[%ld]", a_buf->size_real);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (left_adjust) {
|
||||||
|
if (space_len) memset(a_buf->tail + source_len, ' ', space_len);
|
||||||
|
memcpy(a_buf->tail, str, source_len);
|
||||||
|
} else {
|
||||||
|
if (space_len) {
|
||||||
|
if (zero_pad) {
|
||||||
|
memset(a_buf->tail, '0', space_len);
|
||||||
|
} else {
|
||||||
|
memset(a_buf->tail, ' ', space_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
memcpy(a_buf->tail + space_len, str, source_len);
|
||||||
|
}
|
||||||
|
a_buf->tail += append_len;
|
||||||
|
//*(a_buf->tail) = '\0';
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*******************************************************************************/
|
||||||
|
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __zlog_buf_h
|
||||||
|
#define __zlog_buf_h
|
||||||
|
|
||||||
|
/* buf, is a dynamic expand buffer for one single log,
|
||||||
|
* as one single log will interlace if use multiple write() to file.
|
||||||
|
* and buf is always keep in a thread, to make each thread has its
|
||||||
|
* own buffer to avoid lock.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef struct zlog_buf_s {
|
||||||
|
char *start;
|
||||||
|
char *tail;
|
||||||
|
char *end;
|
||||||
|
char *end_plus_1;
|
||||||
|
|
||||||
|
size_t size_min;
|
||||||
|
size_t size_max;
|
||||||
|
size_t size_real;
|
||||||
|
|
||||||
|
char truncate_str[MAXLEN_PATH + 1];
|
||||||
|
size_t truncate_str_len;
|
||||||
|
} zlog_buf_t;
|
||||||
|
|
||||||
|
|
||||||
|
zlog_buf_t *zlog_buf_new(size_t min, size_t max, const char *truncate_str);
|
||||||
|
void zlog_buf_del(zlog_buf_t * a_buf);
|
||||||
|
void zlog_buf_profile(zlog_buf_t * a_buf, int flag);
|
||||||
|
|
||||||
|
int zlog_buf_vprintf(zlog_buf_t * a_buf, const char *format, va_list args);
|
||||||
|
int zlog_buf_append(zlog_buf_t * a_buf, const char *str, size_t str_len);
|
||||||
|
int zlog_buf_adjust_append(zlog_buf_t * a_buf, const char *str, size_t str_len,
|
||||||
|
int left_adjust, int zero_pad, size_t in_width, size_t out_width);
|
||||||
|
int zlog_buf_printf_dec32(zlog_buf_t * a_buf, uint32_t ui32, int width);
|
||||||
|
int zlog_buf_printf_dec64(zlog_buf_t * a_buf, uint64_t ui64, int width);
|
||||||
|
int zlog_buf_printf_hex(zlog_buf_t * a_buf, uint32_t ui32, int width);
|
||||||
|
|
||||||
|
#define zlog_buf_restart(a_buf) do { \
|
||||||
|
a_buf->tail = a_buf->start; \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define zlog_buf_len(a_buf) (a_buf->tail - a_buf->start)
|
||||||
|
#define zlog_buf_str(a_buf) (a_buf->start)
|
||||||
|
#define zlog_buf_seal(a_buf) do {*(a_buf)->tail = '\0';} while (0)
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,233 @@
|
|||||||
|
/*
|
||||||
|
* 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 <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "category.h"
|
||||||
|
#include "rule.h"
|
||||||
|
#include "zc_defs.h"
|
||||||
|
|
||||||
|
void zlog_category_profile(zlog_category_t *a_category, int flag)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
zlog_rule_t *a_rule;
|
||||||
|
|
||||||
|
zc_assert(a_category,);
|
||||||
|
zc_profile(flag, "--category[%p][%s][%p]--",
|
||||||
|
a_category,
|
||||||
|
a_category->name,
|
||||||
|
a_category->fit_rules);
|
||||||
|
if (a_category->fit_rules) {
|
||||||
|
zc_arraylist_foreach(a_category->fit_rules, i, a_rule) {
|
||||||
|
zlog_rule_profile(a_rule, flag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
void zlog_category_del(zlog_category_t * a_category)
|
||||||
|
{
|
||||||
|
zc_assert(a_category,);
|
||||||
|
if (a_category->fit_rules) zc_arraylist_del(a_category->fit_rules);
|
||||||
|
zc_debug("zlog_category_del[%p]", a_category);
|
||||||
|
free(a_category);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* overlap one rule's level bitmap to cateogry,
|
||||||
|
* so category can judge whether a log level will be output by itself
|
||||||
|
* It is safe when configure is reloaded, when rule will be released an recreated
|
||||||
|
*/
|
||||||
|
static void zlog_cateogry_overlap_bitmap(zlog_category_t * a_category, zlog_rule_t *a_rule)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < sizeof(a_rule->level_bitmap); i++) {
|
||||||
|
a_category->level_bitmap[i] |= a_rule->level_bitmap[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zlog_category_obtain_rules(zlog_category_t * a_category, zc_arraylist_t * rules)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int count = 0;
|
||||||
|
int fit = 0;
|
||||||
|
zlog_rule_t *a_rule;
|
||||||
|
zlog_rule_t *wastebin_rule = NULL;
|
||||||
|
|
||||||
|
/* before set, clean last fit rules first */
|
||||||
|
if (a_category->fit_rules) zc_arraylist_del(a_category->fit_rules);
|
||||||
|
|
||||||
|
memset(a_category->level_bitmap, 0x00, sizeof(a_category->level_bitmap));
|
||||||
|
|
||||||
|
a_category->fit_rules = zc_arraylist_new(NULL);
|
||||||
|
if (!(a_category->fit_rules)) {
|
||||||
|
zc_error("zc_arraylist_new fail");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get match rules from all rules */
|
||||||
|
zc_arraylist_foreach(rules, i, a_rule) {
|
||||||
|
fit = zlog_rule_match_category(a_rule, a_category->name);
|
||||||
|
if (fit) {
|
||||||
|
if (zc_arraylist_add(a_category->fit_rules, a_rule)) {
|
||||||
|
zc_error("zc_arrylist_add fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
zlog_cateogry_overlap_bitmap(a_category, a_rule);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zlog_rule_is_wastebin(a_rule)) {
|
||||||
|
wastebin_rule = a_rule;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count == 0) {
|
||||||
|
if (wastebin_rule) {
|
||||||
|
zc_debug("category[%s], no match rules, use wastebin_rule", a_category->name);
|
||||||
|
if (zc_arraylist_add(a_category->fit_rules, wastebin_rule)) {
|
||||||
|
zc_error("zc_arrylist_add fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
zlog_cateogry_overlap_bitmap(a_category, wastebin_rule);
|
||||||
|
count++;
|
||||||
|
} else {
|
||||||
|
zc_debug("category[%s], no match rules & no wastebin_rule", a_category->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
err:
|
||||||
|
zc_arraylist_del(a_category->fit_rules);
|
||||||
|
a_category->fit_rules = NULL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
zlog_category_t *zlog_category_new(const char *name, zc_arraylist_t * rules)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
zlog_category_t *a_category;
|
||||||
|
|
||||||
|
zc_assert(name, NULL);
|
||||||
|
zc_assert(rules, NULL);
|
||||||
|
|
||||||
|
len = strlen(name);
|
||||||
|
if (len > sizeof(a_category->name) - 1) {
|
||||||
|
zc_error("name[%s] too long", name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
a_category = calloc(1, sizeof(zlog_category_t));
|
||||||
|
if (!a_category) {
|
||||||
|
zc_error("calloc fail, errno[%d]", errno);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
strcpy(a_category->name, name);
|
||||||
|
a_category->name_len = len;
|
||||||
|
if (zlog_category_obtain_rules(a_category, rules)) {
|
||||||
|
zc_error("zlog_category_fit_rules fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
zlog_category_profile(a_category, ZC_DEBUG);
|
||||||
|
return a_category;
|
||||||
|
err:
|
||||||
|
zlog_category_del(a_category);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/*******************************************************************************/
|
||||||
|
/* update success: fit_rules 1, fit_rules_backup 1 */
|
||||||
|
/* update fail: fit_rules 0, fit_rules_backup 1 */
|
||||||
|
int zlog_category_update_rules(zlog_category_t * a_category, zc_arraylist_t * new_rules)
|
||||||
|
{
|
||||||
|
zc_assert(a_category, -1);
|
||||||
|
zc_assert(new_rules, -1);
|
||||||
|
|
||||||
|
/* 1st, mv fit_rules fit_rules_backup */
|
||||||
|
if (a_category->fit_rules_backup) zc_arraylist_del(a_category->fit_rules_backup);
|
||||||
|
a_category->fit_rules_backup = a_category->fit_rules;
|
||||||
|
a_category->fit_rules = NULL;
|
||||||
|
|
||||||
|
memcpy(a_category->level_bitmap_backup, a_category->level_bitmap,
|
||||||
|
sizeof(a_category->level_bitmap));
|
||||||
|
|
||||||
|
/* 2nd, obtain new_rules to fit_rules */
|
||||||
|
if (zlog_category_obtain_rules(a_category, new_rules)) {
|
||||||
|
zc_error("zlog_category_obtain_rules fail");
|
||||||
|
a_category->fit_rules = NULL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* keep the fit_rules_backup not change, return */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* commit fail: fit_rules_backup != 0 */
|
||||||
|
/* commit success: fit_rules 1, fit_rules_backup 0 */
|
||||||
|
void zlog_category_commit_rules(zlog_category_t * a_category)
|
||||||
|
{
|
||||||
|
zc_assert(a_category,);
|
||||||
|
if (!a_category->fit_rules_backup) {
|
||||||
|
zc_warn("a_category->fit_rules_backup is NULL, never update before");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
zc_arraylist_del(a_category->fit_rules_backup);
|
||||||
|
a_category->fit_rules_backup = NULL;
|
||||||
|
memset(a_category->level_bitmap_backup, 0x00,
|
||||||
|
sizeof(a_category->level_bitmap_backup));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* rollback fail: fit_rules_backup != 0 */
|
||||||
|
/* rollback success: fit_rules 1, fit_rules_backup 0 */
|
||||||
|
/* so whether update succes or not, make things back to old */
|
||||||
|
void zlog_category_rollback_rules(zlog_category_t * a_category)
|
||||||
|
{
|
||||||
|
zc_assert(a_category,);
|
||||||
|
if (!a_category->fit_rules_backup) {
|
||||||
|
zc_warn("a_category->fit_rules_backup in NULL, never update before");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a_category->fit_rules) {
|
||||||
|
/* update success, rm new and backup */
|
||||||
|
zc_arraylist_del(a_category->fit_rules);
|
||||||
|
a_category->fit_rules = a_category->fit_rules_backup;
|
||||||
|
a_category->fit_rules_backup = NULL;
|
||||||
|
} else {
|
||||||
|
/* update fail, just backup */
|
||||||
|
a_category->fit_rules = a_category->fit_rules_backup;
|
||||||
|
a_category->fit_rules_backup = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(a_category->level_bitmap, a_category->level_bitmap_backup,
|
||||||
|
sizeof(a_category->level_bitmap));
|
||||||
|
memset(a_category->level_bitmap_backup, 0x00,
|
||||||
|
sizeof(a_category->level_bitmap_backup));
|
||||||
|
|
||||||
|
return; /* always success */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
|
||||||
|
int zlog_category_output(zlog_category_t * a_category, zlog_thread_t * a_thread)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int rc = 0;
|
||||||
|
zlog_rule_t *a_rule;
|
||||||
|
|
||||||
|
/* go through all match rules to output */
|
||||||
|
zc_arraylist_foreach(a_category->fit_rules, i, a_rule) {
|
||||||
|
rc = zlog_rule_output(a_rule, a_thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __zlog_category_h
|
||||||
|
#define __zlog_category_h
|
||||||
|
|
||||||
|
#include "zc_defs.h"
|
||||||
|
#include "thread.h"
|
||||||
|
|
||||||
|
typedef struct zlog_category_s {
|
||||||
|
char name[MAXLEN_PATH + 1];
|
||||||
|
size_t name_len;
|
||||||
|
unsigned char level_bitmap[32];
|
||||||
|
unsigned char level_bitmap_backup[32];
|
||||||
|
zc_arraylist_t *fit_rules;
|
||||||
|
zc_arraylist_t *fit_rules_backup;
|
||||||
|
} zlog_category_t;
|
||||||
|
|
||||||
|
zlog_category_t *zlog_category_new(const char *name, zc_arraylist_t * rules);
|
||||||
|
void zlog_category_del(zlog_category_t * a_category);
|
||||||
|
void zlog_category_profile(zlog_category_t *a_category, int flag);
|
||||||
|
|
||||||
|
int zlog_category_update_rules(zlog_category_t * a_category, zc_arraylist_t * new_rules);
|
||||||
|
void zlog_category_commit_rules(zlog_category_t * a_category);
|
||||||
|
void zlog_category_rollback_rules(zlog_category_t * a_category);
|
||||||
|
|
||||||
|
int zlog_category_output(zlog_category_t * a_category, zlog_thread_t * a_thread);
|
||||||
|
|
||||||
|
#define zlog_category_needless_level(a_category, lv) \
|
||||||
|
a_category && !((a_category->level_bitmap[lv/8] >> (7 - lv % 8)) & 0x01)
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,129 @@
|
|||||||
|
/*
|
||||||
|
* 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 <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "zc_defs.h"
|
||||||
|
#include "category_table.h"
|
||||||
|
|
||||||
|
void zlog_category_table_profile(zc_hashtable_t * categories, int flag)
|
||||||
|
{
|
||||||
|
zc_hashtable_entry_t *a_entry;
|
||||||
|
zlog_category_t *a_category;
|
||||||
|
|
||||||
|
zc_assert(categories,);
|
||||||
|
zc_profile(flag, "-category_table[%p]-", categories);
|
||||||
|
zc_hashtable_foreach(categories, a_entry) {
|
||||||
|
a_category = (zlog_category_t *) a_entry->value;
|
||||||
|
zlog_category_profile(a_category, flag);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
|
||||||
|
void zlog_category_table_del(zc_hashtable_t * categories)
|
||||||
|
{
|
||||||
|
zc_assert(categories,);
|
||||||
|
zc_hashtable_del(categories);
|
||||||
|
zc_debug("zlog_category_table_del[%p]", categories);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
zc_hashtable_t *zlog_category_table_new(void)
|
||||||
|
{
|
||||||
|
zc_hashtable_t *categories;
|
||||||
|
|
||||||
|
categories = zc_hashtable_new(20,
|
||||||
|
(zc_hashtable_hash_fn) zc_hashtable_str_hash,
|
||||||
|
(zc_hashtable_equal_fn) zc_hashtable_str_equal,
|
||||||
|
NULL, (zc_hashtable_del_fn) zlog_category_del);
|
||||||
|
if (!categories) {
|
||||||
|
zc_error("zc_hashtable_new fail");
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
zlog_category_table_profile(categories, ZC_DEBUG);
|
||||||
|
return categories;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*******************************************************************************/
|
||||||
|
int zlog_category_table_update_rules(zc_hashtable_t * categories, zc_arraylist_t * new_rules)
|
||||||
|
{
|
||||||
|
zc_hashtable_entry_t *a_entry;
|
||||||
|
zlog_category_t *a_category;
|
||||||
|
|
||||||
|
zc_assert(categories, -1);
|
||||||
|
zc_hashtable_foreach(categories, a_entry) {
|
||||||
|
a_category = (zlog_category_t *) a_entry->value;
|
||||||
|
if (zlog_category_update_rules(a_category, new_rules)) {
|
||||||
|
zc_error("zlog_category_update_rules fail, try rollback");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void zlog_category_table_commit_rules(zc_hashtable_t * categories)
|
||||||
|
{
|
||||||
|
zc_hashtable_entry_t *a_entry;
|
||||||
|
zlog_category_t *a_category;
|
||||||
|
|
||||||
|
zc_assert(categories,);
|
||||||
|
zc_hashtable_foreach(categories, a_entry) {
|
||||||
|
a_category = (zlog_category_t *) a_entry->value;
|
||||||
|
zlog_category_commit_rules(a_category);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void zlog_category_table_rollback_rules(zc_hashtable_t * categories)
|
||||||
|
{
|
||||||
|
zc_hashtable_entry_t *a_entry;
|
||||||
|
zlog_category_t *a_category;
|
||||||
|
|
||||||
|
zc_assert(categories,);
|
||||||
|
zc_hashtable_foreach(categories, a_entry) {
|
||||||
|
a_category = (zlog_category_t *) a_entry->value;
|
||||||
|
zlog_category_rollback_rules(a_category);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
zlog_category_t *zlog_category_table_fetch_category(zc_hashtable_t * categories,
|
||||||
|
const char *category_name, zc_arraylist_t * rules)
|
||||||
|
{
|
||||||
|
zlog_category_t *a_category;
|
||||||
|
|
||||||
|
zc_assert(categories, NULL);
|
||||||
|
|
||||||
|
/* 1st find category in global category map */
|
||||||
|
a_category = zc_hashtable_get(categories, category_name);
|
||||||
|
if (a_category) return a_category;
|
||||||
|
|
||||||
|
/* else not found, create one */
|
||||||
|
a_category = zlog_category_new(category_name, rules);
|
||||||
|
if (!a_category) {
|
||||||
|
zc_error("zc_category_new fail");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(zc_hashtable_put(categories, a_category->name, a_category)) {
|
||||||
|
zc_error("zc_hashtable_put fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return a_category;
|
||||||
|
err:
|
||||||
|
zlog_category_del(a_category);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __zlog_category_table_h
|
||||||
|
#define __zlog_category_table_h
|
||||||
|
|
||||||
|
#include "zc_defs.h"
|
||||||
|
#include "category.h"
|
||||||
|
|
||||||
|
zc_hashtable_t *zlog_category_table_new(void);
|
||||||
|
void zlog_category_table_del(zc_hashtable_t * categories);
|
||||||
|
void zlog_category_table_profile(zc_hashtable_t * categories, int flag);
|
||||||
|
|
||||||
|
/* if none, create new and return */
|
||||||
|
zlog_category_t *zlog_category_table_fetch_category(
|
||||||
|
zc_hashtable_t * categories,
|
||||||
|
const char *category_name, zc_arraylist_t * rules);
|
||||||
|
|
||||||
|
int zlog_category_table_update_rules(zc_hashtable_t * categories, zc_arraylist_t * new_rules);
|
||||||
|
void zlog_category_table_commit_rules(zc_hashtable_t * categories);
|
||||||
|
void zlog_category_table_rollback_rules(zc_hashtable_t * categories);
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,555 @@
|
|||||||
|
/*
|
||||||
|
* 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 <ctype.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include "conf.h"
|
||||||
|
#include "rule.h"
|
||||||
|
#include "format.h"
|
||||||
|
#include "level_list.h"
|
||||||
|
#include "rotater.h"
|
||||||
|
#include "zc_defs.h"
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
#define ZLOG_CONF_DEFAULT_FORMAT "default = \"%D %V [%p:%F:%L] %m%n\""
|
||||||
|
#define ZLOG_CONF_DEFAULT_RULE "*.* >stdout"
|
||||||
|
#define ZLOG_CONF_DEFAULT_BUF_SIZE_MIN 1024
|
||||||
|
#define ZLOG_CONF_DEFAULT_BUF_SIZE_MAX (2 * 1024 * 1024)
|
||||||
|
#define ZLOG_CONF_DEFAULT_FILE_PERMS 0600
|
||||||
|
#define ZLOG_CONF_DEFAULT_RELOAD_CONF_PERIOD 0
|
||||||
|
#define ZLOG_CONF_DEFAULT_FSYNC_PERIOD 0
|
||||||
|
#define ZLOG_CONF_BACKUP_ROTATE_LOCK_FILE "/tmp/zlog.lock"
|
||||||
|
/*******************************************************************************/
|
||||||
|
|
||||||
|
void zlog_conf_profile(zlog_conf_t * a_conf, int flag)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
zlog_rule_t *a_rule;
|
||||||
|
zlog_format_t *a_format;
|
||||||
|
|
||||||
|
zc_assert(a_conf,);
|
||||||
|
zc_profile(flag, "-conf[%p]-", a_conf);
|
||||||
|
zc_profile(flag, "--global--");
|
||||||
|
zc_profile(flag, "---file[%s],mtime[%s]---", a_conf->file, a_conf->mtime);
|
||||||
|
zc_profile(flag, "---in-memory conf[%s]---", a_conf->cfg_ptr);
|
||||||
|
zc_profile(flag, "---strict init[%d]---", a_conf->strict_init);
|
||||||
|
zc_profile(flag, "---buffer min[%ld]---", a_conf->buf_size_min);
|
||||||
|
zc_profile(flag, "---buffer max[%ld]---", a_conf->buf_size_max);
|
||||||
|
if (a_conf->default_format) {
|
||||||
|
zc_profile(flag, "---default_format---");
|
||||||
|
zlog_format_profile(a_conf->default_format, flag);
|
||||||
|
}
|
||||||
|
zc_profile(flag, "---file perms[0%o]---", a_conf->file_perms);
|
||||||
|
zc_profile(flag, "---reload conf period[%ld]---", a_conf->reload_conf_period);
|
||||||
|
zc_profile(flag, "---fsync period[%ld]---", a_conf->fsync_period);
|
||||||
|
|
||||||
|
zc_profile(flag, "---rotate lock file[%s]---", a_conf->rotate_lock_file);
|
||||||
|
if (a_conf->rotater) zlog_rotater_profile(a_conf->rotater, flag);
|
||||||
|
|
||||||
|
if (a_conf->levels) zlog_level_list_profile(a_conf->levels, flag);
|
||||||
|
|
||||||
|
if (a_conf->formats) {
|
||||||
|
zc_profile(flag, "--format list[%p]--", a_conf->formats);
|
||||||
|
zc_arraylist_foreach(a_conf->formats, i, a_format) {
|
||||||
|
zlog_format_profile(a_format, flag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a_conf->rules) {
|
||||||
|
zc_profile(flag, "--rule_list[%p]--", a_conf->rules);
|
||||||
|
zc_arraylist_foreach(a_conf->rules, i, a_rule) {
|
||||||
|
zlog_rule_profile(a_rule, flag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*******************************************************************************/
|
||||||
|
void zlog_conf_del(zlog_conf_t * a_conf)
|
||||||
|
{
|
||||||
|
zc_assert(a_conf,);
|
||||||
|
if (a_conf->rotater) zlog_rotater_del(a_conf->rotater);
|
||||||
|
if (a_conf->levels) zlog_level_list_del(a_conf->levels);
|
||||||
|
if (a_conf->default_format) zlog_format_del(a_conf->default_format);
|
||||||
|
if (a_conf->formats) zc_arraylist_del(a_conf->formats);
|
||||||
|
if (a_conf->rules) zc_arraylist_del(a_conf->rules);
|
||||||
|
free(a_conf);
|
||||||
|
zc_debug("zlog_conf_del[%p]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zlog_conf_build_without_file(zlog_conf_t * a_conf);
|
||||||
|
static int zlog_conf_build_with_file(zlog_conf_t * a_conf);
|
||||||
|
static int zlog_conf_build_with_in_memory(zlog_conf_t * a_conf);
|
||||||
|
|
||||||
|
enum{
|
||||||
|
NO_CFG,
|
||||||
|
FILE_CFG,
|
||||||
|
IN_MEMORY_CFG
|
||||||
|
};
|
||||||
|
|
||||||
|
zlog_conf_t *zlog_conf_new(const char *config)
|
||||||
|
{
|
||||||
|
int nwrite = 0;
|
||||||
|
int cfg_source = 0;
|
||||||
|
zlog_conf_t *a_conf = NULL;
|
||||||
|
|
||||||
|
a_conf = calloc(1, sizeof(zlog_conf_t));
|
||||||
|
if (!a_conf) {
|
||||||
|
zc_error("calloc fail, errno[%d]", errno);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find content of pointer. If it starts with '[' then content are configurations.
|
||||||
|
if (config && config[0] != '\0' && config[0] != '[') {
|
||||||
|
nwrite = snprintf(a_conf->file, sizeof(a_conf->file), "%s", config);
|
||||||
|
cfg_source = FILE_CFG;
|
||||||
|
} else if (getenv("ZLOG_CONF_PATH") != NULL) {
|
||||||
|
nwrite = snprintf(a_conf->file, sizeof(a_conf->file), "%s", getenv("ZLOG_CONF_PATH"));
|
||||||
|
cfg_source = FILE_CFG;
|
||||||
|
} else if (config[0]=='[') {
|
||||||
|
memset(a_conf->file, 0x00, sizeof(a_conf->file));
|
||||||
|
nwrite = snprintf(a_conf->cfg_ptr, sizeof(a_conf->cfg_ptr), "%s", config);
|
||||||
|
cfg_source = IN_MEMORY_CFG;
|
||||||
|
if (nwrite < 0 || nwrite >= sizeof(a_conf->file)) {
|
||||||
|
zc_error("not enough space for configurations, nwrite=[%d], errno[%d]", nwrite, errno);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
memset(a_conf->file, 0x00, sizeof(a_conf->file));
|
||||||
|
cfg_source = NO_CFG;
|
||||||
|
}
|
||||||
|
if (nwrite < 0 || nwrite >= sizeof(a_conf->file) && cfg_source == FILE_CFG) {
|
||||||
|
zc_error("not enough space for path name, nwrite=[%d], errno[%d]", nwrite, errno);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set default configuration start */
|
||||||
|
a_conf->strict_init = 1;
|
||||||
|
a_conf->buf_size_min = ZLOG_CONF_DEFAULT_BUF_SIZE_MIN;
|
||||||
|
a_conf->buf_size_max = ZLOG_CONF_DEFAULT_BUF_SIZE_MAX;
|
||||||
|
if (cfg_source == FILE_CFG) {
|
||||||
|
/* configure file as default lock file */
|
||||||
|
strcpy(a_conf->rotate_lock_file, a_conf->file);
|
||||||
|
} else {
|
||||||
|
strcpy(a_conf->rotate_lock_file, ZLOG_CONF_BACKUP_ROTATE_LOCK_FILE);
|
||||||
|
}
|
||||||
|
strcpy(a_conf->default_format_line, ZLOG_CONF_DEFAULT_FORMAT);
|
||||||
|
a_conf->file_perms = ZLOG_CONF_DEFAULT_FILE_PERMS;
|
||||||
|
a_conf->reload_conf_period = ZLOG_CONF_DEFAULT_RELOAD_CONF_PERIOD;
|
||||||
|
a_conf->fsync_period = ZLOG_CONF_DEFAULT_FSYNC_PERIOD;
|
||||||
|
/* set default configuration end */
|
||||||
|
|
||||||
|
a_conf->levels = zlog_level_list_new();
|
||||||
|
if (!a_conf->levels) {
|
||||||
|
zc_error("zlog_level_list_new fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_conf->formats = zc_arraylist_new((zc_arraylist_del_fn) zlog_format_del);
|
||||||
|
if (!a_conf->formats) {
|
||||||
|
zc_error("zc_arraylist_new fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_conf->rules = zc_arraylist_new((zc_arraylist_del_fn) zlog_rule_del);
|
||||||
|
if (!a_conf->rules) {
|
||||||
|
zc_error("init rule_list fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfg_source == FILE_CFG) {
|
||||||
|
if (zlog_conf_build_with_file(a_conf)) {
|
||||||
|
zc_error("zlog_conf_build_with_file fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
} else if (cfg_source == IN_MEMORY_CFG) {
|
||||||
|
if(zlog_conf_build_with_in_memory(a_conf)){
|
||||||
|
zc_error("zlog_conf_build_with_in_memory fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (zlog_conf_build_without_file(a_conf)) {
|
||||||
|
zc_error("zlog_conf_build_without_file fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zlog_conf_profile(a_conf, ZC_DEBUG);
|
||||||
|
return a_conf;
|
||||||
|
err:
|
||||||
|
zlog_conf_del(a_conf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/*******************************************************************************/
|
||||||
|
static int zlog_conf_build_without_file(zlog_conf_t * a_conf)
|
||||||
|
{
|
||||||
|
zlog_rule_t *default_rule;
|
||||||
|
|
||||||
|
a_conf->default_format = zlog_format_new(a_conf->default_format_line, &(a_conf->time_cache_count));
|
||||||
|
if (!a_conf->default_format) {
|
||||||
|
zc_error("zlog_format_new fail");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_conf->rotater = zlog_rotater_new(a_conf->rotate_lock_file);
|
||||||
|
if (!a_conf->rotater) {
|
||||||
|
zc_error("zlog_rotater_new fail");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
default_rule = zlog_rule_new(
|
||||||
|
ZLOG_CONF_DEFAULT_RULE,
|
||||||
|
a_conf->levels,
|
||||||
|
a_conf->default_format,
|
||||||
|
a_conf->formats,
|
||||||
|
a_conf->file_perms,
|
||||||
|
a_conf->fsync_period,
|
||||||
|
&(a_conf->time_cache_count));
|
||||||
|
if (!default_rule) {
|
||||||
|
zc_error("zlog_rule_new fail");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add default rule */
|
||||||
|
if (zc_arraylist_add(a_conf->rules, default_rule)) {
|
||||||
|
zlog_rule_del(default_rule);
|
||||||
|
zc_error("zc_arraylist_add fail");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*******************************************************************************/
|
||||||
|
static int zlog_conf_parse_line(zlog_conf_t * a_conf, char *line, int *section);
|
||||||
|
|
||||||
|
static int zlog_conf_build_with_file(zlog_conf_t * a_conf)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
struct zlog_stat a_stat;
|
||||||
|
struct tm local_time;
|
||||||
|
FILE *fp = NULL;
|
||||||
|
|
||||||
|
char line[MAXLEN_CFG_LINE + 1];
|
||||||
|
size_t line_len;
|
||||||
|
char *pline = NULL;
|
||||||
|
char *p = NULL;
|
||||||
|
int line_no = 0;
|
||||||
|
int i = 0;
|
||||||
|
int in_quotation = 0;
|
||||||
|
|
||||||
|
int section = 0;
|
||||||
|
/* [global:1] [levels:2] [formats:3] [rules:4] */
|
||||||
|
|
||||||
|
if (lstat(a_conf->file, &a_stat)) {
|
||||||
|
zc_error("lstat conf file[%s] fail, errno[%d]", a_conf->file,
|
||||||
|
errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
localtime_r(&(a_stat.st_mtime), &local_time);
|
||||||
|
strftime(a_conf->mtime, sizeof(a_conf->mtime), "%F %T", &local_time);
|
||||||
|
|
||||||
|
if ((fp = fopen(a_conf->file, "r")) == NULL) {
|
||||||
|
zc_error("open configure file[%s] fail", a_conf->file);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now process the file.
|
||||||
|
*/
|
||||||
|
pline = line;
|
||||||
|
memset(&line, 0x00, sizeof(line));
|
||||||
|
while (fgets((char *)pline, sizeof(line) - (pline - line), fp) != NULL) {
|
||||||
|
++line_no;
|
||||||
|
line_len = strlen(pline);
|
||||||
|
if (0 == line_len) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pline[line_len - 1] == '\n') {
|
||||||
|
pline[line_len - 1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check for end-of-section, comments, strip off trailing
|
||||||
|
* spaces and newline character.
|
||||||
|
*/
|
||||||
|
p = pline;
|
||||||
|
while (*p && isspace((int)*p))
|
||||||
|
++p;
|
||||||
|
if (*p == '\0' || *p == '#')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (i = 0; p[i] != '\0'; ++i) {
|
||||||
|
pline[i] = p[i];
|
||||||
|
}
|
||||||
|
pline[i] = '\0';
|
||||||
|
|
||||||
|
for (p = pline + strlen(pline) - 1; isspace((int)*p); --p)
|
||||||
|
/*EMPTY*/;
|
||||||
|
|
||||||
|
if (*p == '\\') {
|
||||||
|
if ((p - line) > MAXLEN_CFG_LINE - 30) {
|
||||||
|
/* Oops the buffer is full - what now? */
|
||||||
|
pline = line;
|
||||||
|
} else {
|
||||||
|
for (p--; isspace((int)*p); --p)
|
||||||
|
/*EMPTY*/;
|
||||||
|
p++;
|
||||||
|
*p = 0;
|
||||||
|
pline = p;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
pline = line;
|
||||||
|
|
||||||
|
*++p = '\0';
|
||||||
|
|
||||||
|
/* clean the tail comments start from # and not in quotation */
|
||||||
|
in_quotation = 0;
|
||||||
|
for (p = line; *p != '\0'; p++) {
|
||||||
|
if (*p == '"') {
|
||||||
|
in_quotation ^= 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*p == '#' && !in_quotation) {
|
||||||
|
*p = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we now have the complete line,
|
||||||
|
* and are positioned at the first non-whitespace
|
||||||
|
* character. So let's process it
|
||||||
|
*/
|
||||||
|
rc = zlog_conf_parse_line(a_conf, line, §ion);
|
||||||
|
if (rc < 0) {
|
||||||
|
zc_error("parse configure file[%s]line_no[%ld] fail", a_conf->file, line_no);
|
||||||
|
zc_error("line[%s]", line);
|
||||||
|
goto exit;
|
||||||
|
} else if (rc > 0) {
|
||||||
|
zc_warn("parse configure file[%s]line_no[%ld] fail", a_conf->file, line_no);
|
||||||
|
zc_warn("line[%s]", line);
|
||||||
|
zc_warn("as strict init is set to false, ignore and go on");
|
||||||
|
rc = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
fclose(fp);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
/**********************************************************************/
|
||||||
|
static int zlog_conf_build_with_in_memory(zlog_conf_t * a_conf)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
char line[MAXLEN_CFG_LINE + 1];
|
||||||
|
char *pline = NULL;
|
||||||
|
int section = 0;
|
||||||
|
pline = line;
|
||||||
|
memset(&line, 0x00, sizeof(line));
|
||||||
|
pline = strtok((char *)a_conf->cfg_ptr, "\n");
|
||||||
|
|
||||||
|
while (pline != NULL) {
|
||||||
|
rc = zlog_conf_parse_line(a_conf, pline, §ion);
|
||||||
|
if (rc < 0) {
|
||||||
|
zc_error("parse in-memory configurations[%s] line [%s] fail", a_conf->cfg_ptr, pline);
|
||||||
|
break;
|
||||||
|
} else if (rc > 0) {
|
||||||
|
zc_error("parse in-memory configurations[%s] line [%s] fail", a_conf->cfg_ptr, pline);
|
||||||
|
zc_warn("as strict init is set to false, ignore and go on");
|
||||||
|
rc = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pline = strtok(NULL, "\n");
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
/* section [global:1] [levels:2] [formats:3] [rules:4] */
|
||||||
|
static int zlog_conf_parse_line(zlog_conf_t * a_conf, char *line, int *section)
|
||||||
|
{
|
||||||
|
int nscan;
|
||||||
|
int nread;
|
||||||
|
char name[MAXLEN_CFG_LINE + 1];
|
||||||
|
char word_1[MAXLEN_CFG_LINE + 1];
|
||||||
|
char word_2[MAXLEN_CFG_LINE + 1];
|
||||||
|
char word_3[MAXLEN_CFG_LINE + 1];
|
||||||
|
char value[MAXLEN_CFG_LINE + 1];
|
||||||
|
zlog_format_t *a_format = NULL;
|
||||||
|
zlog_rule_t *a_rule = NULL;
|
||||||
|
|
||||||
|
if (strlen(line) > MAXLEN_CFG_LINE) {
|
||||||
|
zc_error ("line_len[%ld] > MAXLEN_CFG_LINE[%ld], may cause overflow",
|
||||||
|
strlen(line), MAXLEN_CFG_LINE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get and set outer section flag, so it is a closure? haha */
|
||||||
|
if (line[0] == '[') {
|
||||||
|
int last_section = *section;
|
||||||
|
nscan = sscanf(line, "[ %[^] \t]", name);
|
||||||
|
if (STRCMP(name, ==, "global")) {
|
||||||
|
*section = 1;
|
||||||
|
} else if (STRCMP(name, ==, "levels")) {
|
||||||
|
*section = 2;
|
||||||
|
} else if (STRCMP(name, ==, "formats")) {
|
||||||
|
*section = 3;
|
||||||
|
} else if (STRCMP(name, ==, "rules")) {
|
||||||
|
*section = 4;
|
||||||
|
} else {
|
||||||
|
zc_error("wrong section name[%s]", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* check the sequence of section, must increase */
|
||||||
|
if (last_section >= *section) {
|
||||||
|
zc_error("wrong sequence of section, must follow global->levels->formats->rules");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*section == 4) {
|
||||||
|
if (a_conf->reload_conf_period != 0
|
||||||
|
&& a_conf->fsync_period >= a_conf->reload_conf_period) {
|
||||||
|
/* as all rule will be rebuilt when conf is reload,
|
||||||
|
* so fsync_period > reload_conf_period will never
|
||||||
|
* cause rule to fsync it's file.
|
||||||
|
* fsync_period will be meaningless and down speed,
|
||||||
|
* so make it zero.
|
||||||
|
*/
|
||||||
|
zc_warn("fsync_period[%ld] >= reload_conf_period[%ld],"
|
||||||
|
"set fsync_period to zero");
|
||||||
|
a_conf->fsync_period = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now build rotater and default_format
|
||||||
|
* from the unchanging global setting,
|
||||||
|
* for zlog_rule_new() */
|
||||||
|
a_conf->rotater = zlog_rotater_new(a_conf->rotate_lock_file);
|
||||||
|
if (!a_conf->rotater) {
|
||||||
|
zc_error("zlog_rotater_new fail");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_conf->default_format = zlog_format_new(a_conf->default_format_line,
|
||||||
|
&(a_conf->time_cache_count));
|
||||||
|
if (!a_conf->default_format) {
|
||||||
|
zc_error("zlog_format_new fail");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* process detail */
|
||||||
|
switch (*section) {
|
||||||
|
case 1:
|
||||||
|
memset(name, 0x00, sizeof(name));
|
||||||
|
memset(value, 0x00, sizeof(value));
|
||||||
|
nscan = sscanf(line, " %[^=]= %s ", name, value);
|
||||||
|
if (nscan != 2) {
|
||||||
|
zc_error("sscanf [%s] fail, name or value is null", line);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(word_1, 0x00, sizeof(word_1));
|
||||||
|
memset(word_2, 0x00, sizeof(word_2));
|
||||||
|
memset(word_3, 0x00, sizeof(word_3));
|
||||||
|
nread = 0;
|
||||||
|
nscan = sscanf(name, "%s%n%s%s", word_1, &nread, word_2, word_3);
|
||||||
|
|
||||||
|
if (STRCMP(word_1, ==, "strict") && STRCMP(word_2, ==, "init")) {
|
||||||
|
/* if environment variable ZLOG_STRICT_INIT is set
|
||||||
|
* then always make it strict
|
||||||
|
*/
|
||||||
|
if (STRICMP(value, ==, "false") && !getenv("ZLOG_STRICT_INIT")) {
|
||||||
|
a_conf->strict_init = 0;
|
||||||
|
} else {
|
||||||
|
a_conf->strict_init = 1;
|
||||||
|
}
|
||||||
|
} else if (STRCMP(word_1, ==, "buffer") && STRCMP(word_2, ==, "min")) {
|
||||||
|
a_conf->buf_size_min = zc_parse_byte_size(value);
|
||||||
|
} else if (STRCMP(word_1, ==, "buffer") && STRCMP(word_2, ==, "max")) {
|
||||||
|
a_conf->buf_size_max = zc_parse_byte_size(value);
|
||||||
|
} else if (STRCMP(word_1, ==, "file") && STRCMP(word_2, ==, "perms")) {
|
||||||
|
sscanf(value, "%o", &(a_conf->file_perms));
|
||||||
|
} else if (STRCMP(word_1, ==, "rotate") &&
|
||||||
|
STRCMP(word_2, ==, "lock") && STRCMP(word_3, ==, "file")) {
|
||||||
|
/* may overwrite the inner default value, or last value */
|
||||||
|
if (STRCMP(value, ==, "self")) {
|
||||||
|
strcpy(a_conf->rotate_lock_file, a_conf->file);
|
||||||
|
} else {
|
||||||
|
strcpy(a_conf->rotate_lock_file, value);
|
||||||
|
}
|
||||||
|
} else if (STRCMP(word_1, ==, "default") && STRCMP(word_2, ==, "format")) {
|
||||||
|
/* so the input now is [format = "xxyy"], fit format's style */
|
||||||
|
strcpy(a_conf->default_format_line, line + nread);
|
||||||
|
} else if (STRCMP(word_1, ==, "reload") &&
|
||||||
|
STRCMP(word_2, ==, "conf") && STRCMP(word_3, ==, "period")) {
|
||||||
|
a_conf->reload_conf_period = zc_parse_byte_size(value);
|
||||||
|
} else if (STRCMP(word_1, ==, "fsync") && STRCMP(word_2, ==, "period")) {
|
||||||
|
a_conf->fsync_period = zc_parse_byte_size(value);
|
||||||
|
} else {
|
||||||
|
zc_error("name[%s] is not any one of global options", name);
|
||||||
|
if (a_conf->strict_init) return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (zlog_level_list_set(a_conf->levels, line)) {
|
||||||
|
zc_error("zlog_level_list_set fail");
|
||||||
|
if (a_conf->strict_init) return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
a_format = zlog_format_new(line, &(a_conf->time_cache_count));
|
||||||
|
if (!a_format) {
|
||||||
|
zc_error("zlog_format_new fail [%s]", line);
|
||||||
|
if (a_conf->strict_init) return -1;
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
if (zc_arraylist_add(a_conf->formats, a_format)) {
|
||||||
|
zlog_format_del(a_format);
|
||||||
|
zc_error("zc_arraylist_add fail");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
a_rule = zlog_rule_new(line,
|
||||||
|
a_conf->levels,
|
||||||
|
a_conf->default_format,
|
||||||
|
a_conf->formats,
|
||||||
|
a_conf->file_perms,
|
||||||
|
a_conf->fsync_period,
|
||||||
|
&(a_conf->time_cache_count));
|
||||||
|
|
||||||
|
if (!a_rule) {
|
||||||
|
zc_error("zlog_rule_new fail [%s]", line);
|
||||||
|
if (a_conf->strict_init) return -1;
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
if (zc_arraylist_add(a_conf->rules, a_rule)) {
|
||||||
|
zlog_rule_del(a_rule);
|
||||||
|
zc_error("zc_arraylist_add fail");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
zc_error("not in any section");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*******************************************************************************/
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __zlog_conf_h
|
||||||
|
#define __zlog_conf_h
|
||||||
|
|
||||||
|
#include "zc_defs.h"
|
||||||
|
#include "format.h"
|
||||||
|
#include "rotater.h"
|
||||||
|
|
||||||
|
typedef struct zlog_conf_s {
|
||||||
|
char file[MAXLEN_PATH + 1];
|
||||||
|
char cfg_ptr[MAXLEN_CFG_LINE*MAXLINES_NO];
|
||||||
|
char mtime[20 + 1];
|
||||||
|
|
||||||
|
int strict_init;
|
||||||
|
size_t buf_size_min;
|
||||||
|
size_t buf_size_max;
|
||||||
|
|
||||||
|
char rotate_lock_file[MAXLEN_CFG_LINE + 1];
|
||||||
|
zlog_rotater_t *rotater;
|
||||||
|
|
||||||
|
char default_format_line[MAXLEN_CFG_LINE + 1];
|
||||||
|
zlog_format_t *default_format;
|
||||||
|
|
||||||
|
unsigned int file_perms;
|
||||||
|
size_t fsync_period;
|
||||||
|
size_t reload_conf_period;
|
||||||
|
|
||||||
|
zc_arraylist_t *levels;
|
||||||
|
zc_arraylist_t *formats;
|
||||||
|
zc_arraylist_t *rules;
|
||||||
|
int time_cache_count;
|
||||||
|
} zlog_conf_t;
|
||||||
|
|
||||||
|
extern zlog_conf_t * zlog_env_conf;
|
||||||
|
|
||||||
|
zlog_conf_t *zlog_conf_new(const char *config);
|
||||||
|
void zlog_conf_del(zlog_conf_t * a_conf);
|
||||||
|
void zlog_conf_profile(zlog_conf_t * a_conf, int flag);
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,182 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE // For distros like Centos for syscall interface
|
||||||
|
|
||||||
|
#include "fmacros.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
|
||||||
|
#include "zc_defs.h"
|
||||||
|
#include "event.h"
|
||||||
|
|
||||||
|
void zlog_event_profile(zlog_event_t * a_event, int flag)
|
||||||
|
{
|
||||||
|
zc_assert(a_event,);
|
||||||
|
zc_profile(flag, "---event[%p][%s,%s][%s(%ld),%s(%ld),%ld,%d][%p,%s][%ld,%ld][%ld,%ld][%d]---",
|
||||||
|
a_event,
|
||||||
|
a_event->category_name, a_event->host_name,
|
||||||
|
a_event->file, a_event->file_len,
|
||||||
|
a_event->func, a_event->func_len,
|
||||||
|
a_event->line, a_event->level,
|
||||||
|
a_event->hex_buf, a_event->str_format,
|
||||||
|
a_event->time_stamp.tv_sec, a_event->time_stamp.tv_usec,
|
||||||
|
(long)a_event->pid, (long)a_event->tid,
|
||||||
|
a_event->time_cache_count);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
|
||||||
|
void zlog_event_del(zlog_event_t * a_event)
|
||||||
|
{
|
||||||
|
zc_assert(a_event,);
|
||||||
|
if (a_event->time_caches) free(a_event->time_caches);
|
||||||
|
zc_debug("zlog_event_del[%p]", a_event);
|
||||||
|
free(a_event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
zlog_event_t *zlog_event_new(int time_cache_count)
|
||||||
|
{
|
||||||
|
zlog_event_t *a_event;
|
||||||
|
|
||||||
|
a_event = calloc(1, sizeof(zlog_event_t));
|
||||||
|
if (!a_event) {
|
||||||
|
zc_error("calloc fail, errno[%d]", errno);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_event->time_caches = calloc(time_cache_count, sizeof(zlog_time_cache_t));
|
||||||
|
if (!a_event->time_caches) {
|
||||||
|
zc_error("calloc fail, errno[%d]", errno);
|
||||||
|
free(a_event);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
a_event->time_cache_count = time_cache_count;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* at the zlog_init we gethostname,
|
||||||
|
* u don't always change your hostname, eh?
|
||||||
|
*/
|
||||||
|
if (gethostname(a_event->host_name, sizeof(a_event->host_name) - 1)) {
|
||||||
|
zc_error("gethostname fail, errno[%d]", errno);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_event->host_name_len = strlen(a_event->host_name);
|
||||||
|
|
||||||
|
/* tid is bound to a_event
|
||||||
|
* as in whole lifecycle event persists
|
||||||
|
* even fork to oth pid, tid not change
|
||||||
|
*/
|
||||||
|
a_event->tid = pthread_self();
|
||||||
|
|
||||||
|
a_event->tid_str_len = sprintf(a_event->tid_str, "%lu", (unsigned long)a_event->tid);
|
||||||
|
a_event->tid_hex_str_len = sprintf(a_event->tid_hex_str, "%x", (unsigned int)a_event->tid);
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
a_event->ktid = syscall(SYS_gettid);
|
||||||
|
#elif __APPLE__
|
||||||
|
uint64_t tid64;
|
||||||
|
pthread_threadid_np(NULL, &tid64);
|
||||||
|
a_event->tid = (pid_t)tid64;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined __linux__ || __APPLE__
|
||||||
|
a_event->ktid_str_len = sprintf(a_event->ktid_str, "%u", (unsigned int)a_event->ktid);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//zlog_event_profile(a_event, ZC_DEBUG);
|
||||||
|
return a_event;
|
||||||
|
err:
|
||||||
|
zlog_event_del(a_event);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
void zlog_event_set_fmt(zlog_event_t * a_event,
|
||||||
|
char *category_name, size_t category_name_len,
|
||||||
|
const char *file, size_t file_len, const char *func, size_t func_len, long line, int level,
|
||||||
|
const char *str_format, va_list str_args)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* category_name point to zlog_category_output's category.name
|
||||||
|
*/
|
||||||
|
a_event->category_name = category_name;
|
||||||
|
a_event->category_name_len = category_name_len;
|
||||||
|
|
||||||
|
a_event->file = (char *) file;
|
||||||
|
a_event->file_len = file_len;
|
||||||
|
a_event->func = (char *) func;
|
||||||
|
a_event->func_len = func_len;
|
||||||
|
a_event->line = line;
|
||||||
|
a_event->level = level;
|
||||||
|
|
||||||
|
a_event->generate_cmd = ZLOG_FMT;
|
||||||
|
a_event->str_format = str_format;
|
||||||
|
va_copy(a_event->str_args, str_args);
|
||||||
|
|
||||||
|
/* pid should fetch eveytime, as no one knows,
|
||||||
|
* when does user fork his process
|
||||||
|
* so clean here, and fetch at spec.c
|
||||||
|
*/
|
||||||
|
a_event->pid = (pid_t) 0;
|
||||||
|
|
||||||
|
/* in a event's life cycle, time will be get when spec need,
|
||||||
|
* and keep unchange though all event's life cycle
|
||||||
|
* zlog_spec_write_time gettimeofday
|
||||||
|
*/
|
||||||
|
a_event->time_stamp.tv_sec = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void zlog_event_set_hex(zlog_event_t * a_event,
|
||||||
|
char *category_name, size_t category_name_len,
|
||||||
|
const char *file, size_t file_len, const char *func, size_t func_len, long line, int level,
|
||||||
|
const void *hex_buf, size_t hex_buf_len)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* category_name point to zlog_category_output's category.name
|
||||||
|
*/
|
||||||
|
a_event->category_name = category_name;
|
||||||
|
a_event->category_name_len = category_name_len;
|
||||||
|
|
||||||
|
a_event->file = (char *) file;
|
||||||
|
a_event->file_len = file_len;
|
||||||
|
a_event->func = (char *) func;
|
||||||
|
a_event->func_len = func_len;
|
||||||
|
a_event->line = line;
|
||||||
|
a_event->level = level;
|
||||||
|
|
||||||
|
a_event->generate_cmd = ZLOG_HEX;
|
||||||
|
a_event->hex_buf = hex_buf;
|
||||||
|
a_event->hex_buf_len = hex_buf_len;
|
||||||
|
|
||||||
|
/* pid should fetch eveytime, as no one knows,
|
||||||
|
* when does user fork his process
|
||||||
|
* so clean here, and fetch at spec.c
|
||||||
|
*/
|
||||||
|
a_event->pid = (pid_t) 0;
|
||||||
|
|
||||||
|
/* in a event's life cycle, time will be get when spec need,
|
||||||
|
* and keep unchange though all event's life cycle
|
||||||
|
*/
|
||||||
|
a_event->time_stamp.tv_sec = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __zlog_event_h
|
||||||
|
#define __zlog_event_h
|
||||||
|
|
||||||
|
#include <sys/types.h> /* for pid_t */
|
||||||
|
#include <sys/time.h> /* for struct timeval */
|
||||||
|
#include <pthread.h> /* for pthread_t */
|
||||||
|
#include <stdarg.h> /* for va_list */
|
||||||
|
#include "zc_defs.h"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ZLOG_FMT = 0,
|
||||||
|
ZLOG_HEX = 1,
|
||||||
|
} zlog_event_cmd;
|
||||||
|
|
||||||
|
typedef struct zlog_time_cache_s {
|
||||||
|
char str[MAXLEN_CFG_LINE + 1];
|
||||||
|
size_t len;
|
||||||
|
time_t sec;
|
||||||
|
} zlog_time_cache_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *category_name;
|
||||||
|
size_t category_name_len;
|
||||||
|
char host_name[256 + 1];
|
||||||
|
size_t host_name_len;
|
||||||
|
|
||||||
|
const char *file;
|
||||||
|
size_t file_len;
|
||||||
|
const char *func;
|
||||||
|
size_t func_len;
|
||||||
|
long line;
|
||||||
|
int level;
|
||||||
|
|
||||||
|
const void *hex_buf;
|
||||||
|
size_t hex_buf_len;
|
||||||
|
const char *str_format;
|
||||||
|
va_list str_args;
|
||||||
|
zlog_event_cmd generate_cmd;
|
||||||
|
|
||||||
|
struct timeval time_stamp;
|
||||||
|
|
||||||
|
time_t time_local_sec;
|
||||||
|
struct tm time_local;
|
||||||
|
|
||||||
|
zlog_time_cache_t *time_caches;
|
||||||
|
int time_cache_count;
|
||||||
|
|
||||||
|
pid_t pid;
|
||||||
|
pid_t last_pid;
|
||||||
|
char pid_str[30 + 1];
|
||||||
|
size_t pid_str_len;
|
||||||
|
|
||||||
|
pthread_t tid;
|
||||||
|
char tid_str[30 + 1];
|
||||||
|
size_t tid_str_len;
|
||||||
|
|
||||||
|
char tid_hex_str[30 + 1];
|
||||||
|
size_t tid_hex_str_len;
|
||||||
|
|
||||||
|
#if defined __linux__ || __APPLE__
|
||||||
|
pid_t ktid;
|
||||||
|
char ktid_str[30+1];
|
||||||
|
size_t ktid_str_len;
|
||||||
|
#endif
|
||||||
|
} zlog_event_t;
|
||||||
|
|
||||||
|
|
||||||
|
zlog_event_t *zlog_event_new(int time_cache_count);
|
||||||
|
void zlog_event_del(zlog_event_t * a_event);
|
||||||
|
void zlog_event_profile(zlog_event_t * a_event, int flag);
|
||||||
|
|
||||||
|
void zlog_event_set_fmt(zlog_event_t * a_event,
|
||||||
|
char *category_name, size_t category_name_len,
|
||||||
|
const char *file, size_t file_len, const char *func, size_t func_len, long line, int level,
|
||||||
|
const char *str_format, va_list str_args);
|
||||||
|
|
||||||
|
void zlog_event_set_hex(zlog_event_t * a_event,
|
||||||
|
char *category_name, size_t category_name_len,
|
||||||
|
const char *file, size_t file_len, const char *func, size_t func_len, long line, int level,
|
||||||
|
const void *hex_buf, size_t hex_buf_len);
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef __zlog_fmacro_h
|
||||||
|
#define __zlog_fmacro_h
|
||||||
|
|
||||||
|
#define _DEFAULT_SOURCE
|
||||||
|
|
||||||
|
#if defined(__linux__) || defined(__OpenBSD__) || defined(_AIX)
|
||||||
|
#ifndef _XOPEN_SOURCE
|
||||||
|
#define _XOPEN_SOURCE 700
|
||||||
|
#endif
|
||||||
|
#ifndef _XOPEN_SOURCE_EXTENDED
|
||||||
|
#define _XOPEN_SOURCE_EXTENDED
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define _XOPEN_SOURCE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _LARGEFILE_SOURCE
|
||||||
|
#define _LARGEFILE_SOURCE
|
||||||
|
#endif
|
||||||
|
#ifndef _FILE_OFFSET_BITS
|
||||||
|
#define _FILE_OFFSET_BITS 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,164 @@
|
|||||||
|
/*
|
||||||
|
* 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 <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "zc_defs.h"
|
||||||
|
#include "thread.h"
|
||||||
|
#include "spec.h"
|
||||||
|
#include "format.h"
|
||||||
|
|
||||||
|
void zlog_format_profile(zlog_format_t * a_format, int flag)
|
||||||
|
{
|
||||||
|
|
||||||
|
zc_assert(a_format,);
|
||||||
|
zc_profile(flag, "---format[%p][%s = %s(%p)]---",
|
||||||
|
a_format,
|
||||||
|
a_format->name,
|
||||||
|
a_format->pattern,
|
||||||
|
a_format->pattern_specs);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
int i;
|
||||||
|
zlog_spec_t *a_spec;
|
||||||
|
zc_arraylist_foreach(a_format->pattern_specs, i, a_spec) {
|
||||||
|
zlog_spec_profile(a_spec, flag);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
void zlog_format_del(zlog_format_t * a_format)
|
||||||
|
{
|
||||||
|
zc_assert(a_format,);
|
||||||
|
if (a_format->pattern_specs) {
|
||||||
|
zc_arraylist_del(a_format->pattern_specs);
|
||||||
|
}
|
||||||
|
zc_debug("zlog_format_del[%p]", a_format);
|
||||||
|
free(a_format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
zlog_format_t *zlog_format_new(char *line, int * time_cache_count)
|
||||||
|
{
|
||||||
|
int nscan = 0;
|
||||||
|
zlog_format_t *a_format = NULL;
|
||||||
|
int nread = 0;
|
||||||
|
const char *p_start;
|
||||||
|
const char *p_end;
|
||||||
|
char *p;
|
||||||
|
char *q;
|
||||||
|
zlog_spec_t *a_spec;
|
||||||
|
|
||||||
|
zc_assert(line, NULL);
|
||||||
|
|
||||||
|
a_format = calloc(1, sizeof(zlog_format_t));
|
||||||
|
if (!a_format) {
|
||||||
|
zc_error("calloc fail, errno[%d]", errno);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* line default = "%d(%F %X.%l) %-6V (%c:%F:%L) - %m%n"
|
||||||
|
* name default
|
||||||
|
* pattern %d(%F %X.%l) %-6V (%c:%F:%L) - %m%n
|
||||||
|
*/
|
||||||
|
memset(a_format->name, 0x00, sizeof(a_format->name));
|
||||||
|
nread = 0;
|
||||||
|
nscan = sscanf(line, " %[^= \t] = %n", a_format->name, &nread);
|
||||||
|
if (nscan != 1) {
|
||||||
|
zc_error("format[%s], syntax wrong", line);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*(line + nread) != '"') {
|
||||||
|
zc_error("the 1st char of pattern is not \", line+nread[%s]", line+nread);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (p = a_format->name; *p != '\0'; p++) {
|
||||||
|
if ((!isalnum(*p)) && (*p != '_')) {
|
||||||
|
zc_error("a_format->name[%s] character is not in [a-Z][0-9][_]", a_format->name);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p_start = line + nread + 1;
|
||||||
|
p_end = strrchr(p_start, '"');
|
||||||
|
if (!p_end) {
|
||||||
|
zc_error("there is no \" at end of pattern, line[%s]", line);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_end - p_start > sizeof(a_format->pattern) - 1) {
|
||||||
|
zc_error("pattern is too long");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
memset(a_format->pattern, 0x00, sizeof(a_format->pattern));
|
||||||
|
memcpy(a_format->pattern, p_start, p_end - p_start);
|
||||||
|
|
||||||
|
if (zc_str_replace_env(a_format->pattern, sizeof(a_format->pattern))) {
|
||||||
|
zc_error("zc_str_replace_env fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_format->pattern_specs =
|
||||||
|
zc_arraylist_new((zc_arraylist_del_fn) zlog_spec_del);
|
||||||
|
if (!(a_format->pattern_specs)) {
|
||||||
|
zc_error("zc_arraylist_new fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (p = a_format->pattern; *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(a_format->pattern_specs, a_spec)) {
|
||||||
|
zlog_spec_del(a_spec);
|
||||||
|
zc_error("zc_arraylist_add fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zlog_format_profile(a_format, ZC_DEBUG);
|
||||||
|
return a_format;
|
||||||
|
err:
|
||||||
|
zlog_format_del(a_format);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/* return 0 success, or buf is full
|
||||||
|
* return -1 fail
|
||||||
|
*/
|
||||||
|
int zlog_format_gen_msg(zlog_format_t * a_format, zlog_thread_t * a_thread)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
zlog_spec_t *a_spec;
|
||||||
|
|
||||||
|
zlog_buf_restart(a_thread->msg_buf);
|
||||||
|
|
||||||
|
zc_arraylist_foreach(a_format->pattern_specs, i, a_spec) {
|
||||||
|
if (zlog_spec_gen_msg(a_spec, a_thread) == 0) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __zlog_format_h
|
||||||
|
#define __zlog_format_h
|
||||||
|
|
||||||
|
#include "thread.h"
|
||||||
|
#include "zc_defs.h"
|
||||||
|
|
||||||
|
typedef struct zlog_format_s zlog_format_t;
|
||||||
|
|
||||||
|
struct zlog_format_s {
|
||||||
|
char name[MAXLEN_CFG_LINE + 1];
|
||||||
|
char pattern[MAXLEN_CFG_LINE + 1];
|
||||||
|
zc_arraylist_t *pattern_specs;
|
||||||
|
};
|
||||||
|
|
||||||
|
zlog_format_t *zlog_format_new(char *line, int * time_cache_count);
|
||||||
|
void zlog_format_del(zlog_format_t * a_format);
|
||||||
|
void zlog_format_profile(zlog_format_t * a_format, int flag);
|
||||||
|
|
||||||
|
int zlog_format_gen_msg(zlog_format_t * a_format, zlog_thread_t * a_thread);
|
||||||
|
|
||||||
|
#define zlog_format_has_name(a_format, fname) \
|
||||||
|
STRCMP(a_format->name, ==, fname)
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,141 @@
|
|||||||
|
/*
|
||||||
|
* 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 <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include "syslog.h"
|
||||||
|
|
||||||
|
#include "zc_defs.h"
|
||||||
|
#include "level.h"
|
||||||
|
|
||||||
|
void zlog_level_profile(zlog_level_t *a_level, int flag)
|
||||||
|
{
|
||||||
|
zc_assert(a_level,);
|
||||||
|
zc_profile(flag, "---level[%p][%d,%s,%s,%d,%d]---",
|
||||||
|
a_level,
|
||||||
|
a_level->int_level,
|
||||||
|
a_level->str_uppercase,
|
||||||
|
a_level->str_lowercase,
|
||||||
|
(int) a_level->str_len,
|
||||||
|
a_level->syslog_level);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
void zlog_level_del(zlog_level_t *a_level)
|
||||||
|
{
|
||||||
|
zc_assert(a_level,);
|
||||||
|
zc_debug("zlog_level_del[%p]", a_level);
|
||||||
|
free(a_level);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int syslog_level_atoi(char *str)
|
||||||
|
{
|
||||||
|
/* guess no unix system will choose -187
|
||||||
|
* as its syslog level, so it is a safe return value
|
||||||
|
*/
|
||||||
|
zc_assert(str, -187);
|
||||||
|
|
||||||
|
if (STRICMP(str, ==, "LOG_EMERG"))
|
||||||
|
return LOG_EMERG;
|
||||||
|
if (STRICMP(str, ==, "LOG_ALERT"))
|
||||||
|
return LOG_ALERT;
|
||||||
|
if (STRICMP(str, ==, "LOG_CRIT"))
|
||||||
|
return LOG_CRIT;
|
||||||
|
if (STRICMP(str, ==, "LOG_ERR"))
|
||||||
|
return LOG_ERR;
|
||||||
|
if (STRICMP(str, ==, "LOG_WARNING"))
|
||||||
|
return LOG_WARNING;
|
||||||
|
if (STRICMP(str, ==, "LOG_NOTICE"))
|
||||||
|
return LOG_NOTICE;
|
||||||
|
if (STRICMP(str, ==, "LOG_INFO"))
|
||||||
|
return LOG_INFO;
|
||||||
|
if (STRICMP(str, ==, "LOG_DEBUG"))
|
||||||
|
return LOG_DEBUG;
|
||||||
|
|
||||||
|
zc_error("wrong syslog level[%s]", str);
|
||||||
|
return -187;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* line: TRACE = 10, LOG_ERR */
|
||||||
|
zlog_level_t *zlog_level_new(char *line)
|
||||||
|
{
|
||||||
|
zlog_level_t *a_level = NULL;
|
||||||
|
int i;
|
||||||
|
int nscan;
|
||||||
|
char str[MAXLEN_CFG_LINE + 1];
|
||||||
|
int l = 0;
|
||||||
|
char sl[MAXLEN_CFG_LINE + 1];
|
||||||
|
|
||||||
|
zc_assert(line, NULL);
|
||||||
|
|
||||||
|
memset(str, 0x00, sizeof(str));
|
||||||
|
memset(sl, 0x00, sizeof(sl));
|
||||||
|
|
||||||
|
nscan = sscanf(line, " %[^= \t] = %d ,%s", str, &l, sl);
|
||||||
|
if (nscan < 2) {
|
||||||
|
zc_error("level[%s], syntax wrong", line);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check level and str */
|
||||||
|
if ((l < 0) || (l > 255)) {
|
||||||
|
zc_error("l[%d] not in [0,255], wrong", l);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str[0] == '\0') {
|
||||||
|
zc_error("str[0] = 0");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_level = calloc(1, sizeof(zlog_level_t));
|
||||||
|
if (!a_level) {
|
||||||
|
zc_error("calloc fail, errno[%d]", errno);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_level->int_level = l;
|
||||||
|
|
||||||
|
/* fill syslog level */
|
||||||
|
if (sl[0] == '\0') {
|
||||||
|
a_level->syslog_level = LOG_DEBUG;
|
||||||
|
} else {
|
||||||
|
a_level->syslog_level = syslog_level_atoi(sl);
|
||||||
|
if (a_level->syslog_level == -187) {
|
||||||
|
zc_error("syslog_level_atoi fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* strncpy and toupper(str) */
|
||||||
|
for (i = 0; (i < sizeof(a_level->str_uppercase) - 1) && str[i] != '\0'; i++) {
|
||||||
|
(a_level->str_uppercase)[i] = toupper(str[i]);
|
||||||
|
(a_level->str_lowercase)[i] = tolower(str[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str[i] != '\0') {
|
||||||
|
/* overflow */
|
||||||
|
zc_error("not enough space for str, str[%s] > %d", str, i);
|
||||||
|
goto err;
|
||||||
|
} else {
|
||||||
|
(a_level->str_uppercase)[i] = '\0';
|
||||||
|
(a_level->str_lowercase)[i] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
a_level->str_len = i;
|
||||||
|
|
||||||
|
//zlog_level_profile(a_level, ZC_DEBUG);
|
||||||
|
return a_level;
|
||||||
|
err:
|
||||||
|
zc_error("line[%s]", line);
|
||||||
|
zlog_level_del(a_level);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __zlog_level_h
|
||||||
|
#define __zlog_level_h
|
||||||
|
|
||||||
|
#include "zc_defs.h"
|
||||||
|
|
||||||
|
typedef struct zlog_level_s {
|
||||||
|
int int_level;
|
||||||
|
char str_uppercase[MAXLEN_PATH + 1];
|
||||||
|
char str_lowercase[MAXLEN_PATH + 1];
|
||||||
|
size_t str_len;
|
||||||
|
int syslog_level;
|
||||||
|
} zlog_level_t;
|
||||||
|
|
||||||
|
zlog_level_t *zlog_level_new(char *line);
|
||||||
|
void zlog_level_del(zlog_level_t *a_level);
|
||||||
|
void zlog_level_profile(zlog_level_t *a_level, int flag);
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,145 @@
|
|||||||
|
/*
|
||||||
|
* 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 <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include "syslog.h"
|
||||||
|
|
||||||
|
#include "zc_defs.h"
|
||||||
|
#include "level.h"
|
||||||
|
#include "level_list.h"
|
||||||
|
|
||||||
|
/* zlog_level_list == zc_arraylist_t<zlog_level_t> */
|
||||||
|
|
||||||
|
void zlog_level_list_profile(zc_arraylist_t *levels, int flag)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
zlog_level_t *a_level;
|
||||||
|
|
||||||
|
zc_assert(levels,);
|
||||||
|
zc_profile(flag, "--level_list[%p]--", levels);
|
||||||
|
zc_arraylist_foreach(levels, i, a_level) {
|
||||||
|
/* skip empty slots */
|
||||||
|
if (a_level) zlog_level_profile(a_level, flag);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
void zlog_level_list_del(zc_arraylist_t *levels)
|
||||||
|
{
|
||||||
|
zc_assert(levels,);
|
||||||
|
zc_arraylist_del(levels);
|
||||||
|
zc_debug("zc_level_list_del[%p]", levels);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zlog_level_list_set_default(zc_arraylist_t *levels)
|
||||||
|
{
|
||||||
|
return zlog_level_list_set(levels, "* = 0, LOG_INFO")
|
||||||
|
|| zlog_level_list_set(levels, "DEBUG = 20, LOG_DEBUG")
|
||||||
|
|| zlog_level_list_set(levels, "INFO = 40, LOG_INFO")
|
||||||
|
|| zlog_level_list_set(levels, "NOTICE = 60, LOG_NOTICE")
|
||||||
|
|| zlog_level_list_set(levels, "WARN = 80, LOG_WARNING")
|
||||||
|
|| zlog_level_list_set(levels, "ERROR = 100, LOG_ERR")
|
||||||
|
|| zlog_level_list_set(levels, "FATAL = 120, LOG_ALERT")
|
||||||
|
|| zlog_level_list_set(levels, "UNKNOWN = 254, LOG_ERR")
|
||||||
|
|| zlog_level_list_set(levels, "! = 255, LOG_INFO");
|
||||||
|
}
|
||||||
|
|
||||||
|
zc_arraylist_t *zlog_level_list_new(void)
|
||||||
|
{
|
||||||
|
zc_arraylist_t *levels;
|
||||||
|
|
||||||
|
levels = zc_arraylist_new((zc_arraylist_del_fn)zlog_level_del);
|
||||||
|
if (!levels) {
|
||||||
|
zc_error("zc_arraylist_new fail");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zlog_level_list_set_default(levels)) {
|
||||||
|
zc_error("zlog_level_set_default fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
//zlog_level_list_profile(levels, ZC_DEBUG);
|
||||||
|
return levels;
|
||||||
|
err:
|
||||||
|
zc_arraylist_del(levels);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
int zlog_level_list_set(zc_arraylist_t *levels, char *line)
|
||||||
|
{
|
||||||
|
zlog_level_t *a_level;
|
||||||
|
|
||||||
|
a_level = zlog_level_new(line);
|
||||||
|
if (!a_level) {
|
||||||
|
zc_error("zlog_level_new fail");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zc_arraylist_set(levels, a_level->int_level, a_level)) {
|
||||||
|
zc_error("zc_arraylist_set fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
err:
|
||||||
|
zc_error("line[%s]", line);
|
||||||
|
zlog_level_del(a_level);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
zlog_level_t *zlog_level_list_get(zc_arraylist_t *levels, int l)
|
||||||
|
{
|
||||||
|
zlog_level_t *a_level;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if ((l <= 0) || (l > 254)) {
|
||||||
|
/* illegal input from zlog() */
|
||||||
|
zc_error("l[%d] not in (0,254), set to UNKOWN", l);
|
||||||
|
l = 254;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
a_level = zc_arraylist_get(levels, l);
|
||||||
|
if (a_level) {
|
||||||
|
return a_level;
|
||||||
|
} else {
|
||||||
|
/* empty slot */
|
||||||
|
zc_error("l[%d] not in (0,254), or has no level defined,"
|
||||||
|
"see configure file define, set to UNKOWN", l);
|
||||||
|
return zc_arraylist_get(levels, 254);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
|
||||||
|
int zlog_level_list_atoi(zc_arraylist_t *levels, char *str)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
zlog_level_t *a_level;
|
||||||
|
|
||||||
|
if (str == NULL || *str == '\0') {
|
||||||
|
zc_error("str is [%s], can't find level", str);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
zc_arraylist_foreach(levels, i, a_level) {
|
||||||
|
if (a_level && STRICMP(str, ==, a_level->str_uppercase)) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zc_error("str[%s] can't found in level list", str);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __zlog_level_list_h
|
||||||
|
#define __zlog_level_list_h
|
||||||
|
|
||||||
|
#include "zc_defs.h"
|
||||||
|
#include "level.h"
|
||||||
|
|
||||||
|
zc_arraylist_t *zlog_level_list_new(void);
|
||||||
|
void zlog_level_list_del(zc_arraylist_t *levels);
|
||||||
|
void zlog_level_list_profile(zc_arraylist_t *levels, int flag);
|
||||||
|
|
||||||
|
/* conf init use, slow */
|
||||||
|
/* if l is wrong or str=="", return -1 */
|
||||||
|
int zlog_level_list_set(zc_arraylist_t *levels, char *line);
|
||||||
|
|
||||||
|
/* spec ouput use, fast */
|
||||||
|
/* rule output use, fast */
|
||||||
|
/* if not found, return levels[254] */
|
||||||
|
zlog_level_t *zlog_level_list_get(zc_arraylist_t *levels, int l);
|
||||||
|
|
||||||
|
/* rule init use, slow */
|
||||||
|
/* if not found, return -1 */
|
||||||
|
int zlog_level_list_atoi(zc_arraylist_t *levels, char *str);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,204 @@
|
|||||||
|
# zlog makefile
|
||||||
|
# Copyright (C) 2010-2012 Hardy Simpson <HardySimpson1984@gmail.com>
|
||||||
|
# This file is released under the LGPL 2.1 license, see the COPYING file
|
||||||
|
|
||||||
|
OBJ= \
|
||||||
|
buf.o \
|
||||||
|
category.o \
|
||||||
|
category_table.o \
|
||||||
|
conf.o \
|
||||||
|
event.o \
|
||||||
|
format.o \
|
||||||
|
level.o \
|
||||||
|
level_list.o \
|
||||||
|
mdc.o \
|
||||||
|
record.o \
|
||||||
|
record_table.o \
|
||||||
|
rotater.o \
|
||||||
|
rule.o \
|
||||||
|
spec.o \
|
||||||
|
thread.o \
|
||||||
|
zc_arraylist.o \
|
||||||
|
zc_hashtable.o \
|
||||||
|
zc_profile.o \
|
||||||
|
zc_util.o \
|
||||||
|
zlog.o
|
||||||
|
BINS=zlog-chk-conf
|
||||||
|
LIBNAME=libzlog
|
||||||
|
|
||||||
|
ZLOG_MAJOR=1
|
||||||
|
ZLOG_MINOR=2
|
||||||
|
|
||||||
|
# Fallback to gcc when $CC is not in $PATH.
|
||||||
|
CC:=$(shell sh -c 'type $(CC) >/dev/null 2>/dev/null && echo $(CC) || echo gcc')
|
||||||
|
OPTIMIZATION?=-O2
|
||||||
|
WARNINGS=-Wall -Wstrict-prototypes -fwrapv
|
||||||
|
DEBUG?= -g -ggdb
|
||||||
|
REAL_CFLAGS=$(OPTIMIZATION) -fPIC -pthread $(CFLAGS) $(WARNINGS) $(DEBUG)
|
||||||
|
REAL_LDFLAGS=$(LDFLAGS) -pthread
|
||||||
|
|
||||||
|
DYLIBSUFFIX=so
|
||||||
|
STLIBSUFFIX=a
|
||||||
|
DYLIB_MINOR_NAME=$(LIBNAME).$(DYLIBSUFFIX).$(ZLOG_MAJOR).$(ZLOG_MINOR)
|
||||||
|
DYLIB_MAJOR_NAME=$(LIBNAME).$(DYLIBSUFFIX).$(ZLOG_MAJOR)
|
||||||
|
DYLIBNAME=$(LIBNAME).$(DYLIBSUFFIX)
|
||||||
|
DYLIB_MAKE_CMD=$(CC) -shared -Wl,-soname,$(DYLIB_MINOR_NAME) -o $(DYLIBNAME) $(LDFLAGS)
|
||||||
|
STLIBNAME=$(LIBNAME).$(STLIBSUFFIX)
|
||||||
|
STLIB_MAKE_CMD=ar rcs $(STLIBNAME)
|
||||||
|
|
||||||
|
# Installation related variables
|
||||||
|
PREFIX?=/usr/local
|
||||||
|
INCLUDE_PATH=include
|
||||||
|
LIBRARY_PATH=lib
|
||||||
|
BINARY_PATH=bin
|
||||||
|
INSTALL_INCLUDE_PATH= $(PREFIX)/$(INCLUDE_PATH)
|
||||||
|
INSTALL_LIBRARY_PATH= $(PREFIX)/$(LIBRARY_PATH)
|
||||||
|
INSTALL_BINARY_PATH= $(PREFIX)/$(BINARY_PATH)
|
||||||
|
|
||||||
|
# Platform-specific overrides
|
||||||
|
uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
|
||||||
|
compiler_platform := $(shell sh -c '$(CC) --version|grep -i apple')
|
||||||
|
|
||||||
|
ifeq ($(uname_S),SunOS)
|
||||||
|
# REAL_LDFLAGS+= -ldl -lnsl -lsocket
|
||||||
|
DYLIB_MAKE_CMD=$(CC) -G -o $(DYLIBNAME) -h $(DYLIB_MINOR_NAME) $(LDFLAGS)
|
||||||
|
INSTALL= cp -r
|
||||||
|
endif
|
||||||
|
|
||||||
|
# For Darwin builds, check the compiler platform above is not empty. The covers cross compilation on Linux
|
||||||
|
ifneq ($(compiler_platform),)
|
||||||
|
DYLIBSUFFIX=dylib
|
||||||
|
DYLIB_MINOR_NAME=$(LIBNAME).$(ZLOG_MAJOR).$(ZLOG_MINOR).$(DYLIBSUFFIX)
|
||||||
|
DYLIB_MAJOR_NAME=$(LIBNAME).$(ZLOG_MAJOR).$(DYLIBSUFFIX)
|
||||||
|
DYLIB_MAKE_CMD=$(CC) -dynamiclib -install_name $(INSTALL_LIBRARY_PATH)/$(DYLIB_MINOR_NAME) -o $(DYLIBNAME) $(LDFLAGS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(uname_S),AIX)
|
||||||
|
# this logic of minor major is not relevant on AIX or at least not widely used
|
||||||
|
# not to mention dynamic linker .a preference...
|
||||||
|
DYLIB_MAKE_CMD=$(CC) -shared -Wl,-G,-b64 -maix64 -pthread -o $(DYLIBNAME) $(LDFLAGS)
|
||||||
|
REAL_CFLAGS+= -maix64
|
||||||
|
STLIB_MAKE_CMD=OBJECT_MODE=64 ar rcs $(STLIBNAME) $(DYLIB_MAJOR_NAME)
|
||||||
|
endif
|
||||||
|
|
||||||
|
all: $(DYLIBNAME) $(BINS)
|
||||||
|
|
||||||
|
# Deps (use make dep to generate this)
|
||||||
|
buf.o: buf.c zc_defs.h zc_profile.h zc_arraylist.h zc_hashtable.h \
|
||||||
|
zc_xplatform.h zc_util.h buf.h
|
||||||
|
category.o: category.c fmacros.h category.h zc_defs.h zc_profile.h \
|
||||||
|
zc_arraylist.h zc_hashtable.h zc_xplatform.h zc_util.h thread.h event.h \
|
||||||
|
buf.h mdc.h rule.h format.h rotater.h record.h
|
||||||
|
category_table.o: category_table.c zc_defs.h zc_profile.h zc_arraylist.h \
|
||||||
|
zc_hashtable.h zc_xplatform.h zc_util.h category_table.h category.h \
|
||||||
|
thread.h event.h buf.h mdc.h
|
||||||
|
conf.o: conf.c fmacros.h conf.h zc_defs.h zc_profile.h zc_arraylist.h \
|
||||||
|
zc_hashtable.h zc_xplatform.h zc_util.h format.h thread.h event.h buf.h \
|
||||||
|
mdc.h rotater.h rule.h record.h level_list.h level.h
|
||||||
|
event.o: event.c fmacros.h zc_defs.h zc_profile.h zc_arraylist.h \
|
||||||
|
zc_hashtable.h zc_xplatform.h zc_util.h event.h
|
||||||
|
format.o: format.c zc_defs.h zc_profile.h zc_arraylist.h zc_hashtable.h \
|
||||||
|
zc_xplatform.h zc_util.h thread.h event.h buf.h mdc.h spec.h format.h
|
||||||
|
level.o: level.c zc_defs.h zc_profile.h zc_arraylist.h zc_hashtable.h \
|
||||||
|
zc_xplatform.h zc_util.h level.h
|
||||||
|
level_list.o: level_list.c zc_defs.h zc_profile.h zc_arraylist.h \
|
||||||
|
zc_hashtable.h zc_xplatform.h zc_util.h level.h level_list.h
|
||||||
|
mdc.o: mdc.c mdc.h zc_defs.h zc_profile.h zc_arraylist.h zc_hashtable.h \
|
||||||
|
zc_xplatform.h zc_util.h
|
||||||
|
record.o: record.c zc_defs.h zc_profile.h zc_arraylist.h zc_hashtable.h \
|
||||||
|
zc_xplatform.h zc_util.h record.h
|
||||||
|
record_table.o: record_table.c zc_defs.h zc_profile.h zc_arraylist.h \
|
||||||
|
zc_hashtable.h zc_xplatform.h zc_util.h record_table.h record.h
|
||||||
|
rotater.o: rotater.c zc_defs.h zc_profile.h zc_arraylist.h zc_hashtable.h \
|
||||||
|
zc_xplatform.h zc_util.h rotater.h
|
||||||
|
rule.o: rule.c fmacros.h rule.h zc_defs.h zc_profile.h zc_arraylist.h \
|
||||||
|
zc_hashtable.h zc_xplatform.h zc_util.h format.h thread.h event.h buf.h \
|
||||||
|
mdc.h rotater.h record.h level_list.h level.h spec.h
|
||||||
|
spec.o: spec.c fmacros.h spec.h event.h zc_defs.h zc_profile.h \
|
||||||
|
zc_arraylist.h zc_hashtable.h zc_xplatform.h zc_util.h buf.h thread.h \
|
||||||
|
mdc.h level_list.h level.h
|
||||||
|
thread.o: thread.c zc_defs.h zc_profile.h zc_arraylist.h zc_hashtable.h \
|
||||||
|
zc_xplatform.h zc_util.h event.h buf.h thread.h mdc.h
|
||||||
|
zc_arraylist.o: zc_arraylist.c zc_defs.h zc_profile.h zc_arraylist.h \
|
||||||
|
zc_hashtable.h zc_xplatform.h zc_util.h
|
||||||
|
zc_hashtable.o: zc_hashtable.c zc_defs.h zc_profile.h zc_arraylist.h \
|
||||||
|
zc_hashtable.h zc_xplatform.h zc_util.h
|
||||||
|
zc_profile.o: zc_profile.c fmacros.h zc_profile.h zc_xplatform.h
|
||||||
|
zc_util.o: zc_util.c zc_defs.h zc_profile.h zc_arraylist.h zc_hashtable.h \
|
||||||
|
zc_xplatform.h zc_util.h
|
||||||
|
zlog-chk-conf.o: zlog-chk-conf.c fmacros.h zlog.h
|
||||||
|
zlog.o: zlog.c fmacros.h conf.h zc_defs.h zc_profile.h zc_arraylist.h \
|
||||||
|
zc_hashtable.h zc_xplatform.h zc_util.h format.h thread.h event.h buf.h \
|
||||||
|
mdc.h rotater.h category_table.h category.h record_table.h \
|
||||||
|
record.h rule.h
|
||||||
|
|
||||||
|
$(DYLIBNAME): $(OBJ)
|
||||||
|
$(DYLIB_MAKE_CMD) $(OBJ) $(REAL_LDFLAGS)
|
||||||
|
# for use in test folder - linux and requirement for aix runtime
|
||||||
|
# resolving
|
||||||
|
cp -f $(DYLIBNAME) $(DYLIB_MAJOR_NAME)
|
||||||
|
cp -f $(DYLIBNAME) $(DYLIB_MINOR_NAME)
|
||||||
|
|
||||||
|
$(STLIBNAME): $(OBJ)
|
||||||
|
$(STLIB_MAKE_CMD) $(OBJ)
|
||||||
|
|
||||||
|
dynamic: $(DYLIBNAME)
|
||||||
|
static: $(STLIBNAME)
|
||||||
|
|
||||||
|
# Binaries:
|
||||||
|
zlog-chk-conf: zlog-chk-conf.o $(STLIBNAME) $(DYLIBNAME)
|
||||||
|
$(CC) -o $@ zlog-chk-conf.o -L. -lzlog $(REAL_LDFLAGS)
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CC) -std=c99 -pedantic -c $(REAL_CFLAGS) $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(DYLIBNAME) $(STLIBNAME) $(BINS) *.o *.gcda *.gcno *.gcov $(DYLIB_MINOR_NAME) $(DYLIB_MAJOR_NAME)
|
||||||
|
|
||||||
|
dep:
|
||||||
|
$(CC) -MM *.c
|
||||||
|
|
||||||
|
# Installation target
|
||||||
|
|
||||||
|
ifeq ($(uname_S),SunOS)
|
||||||
|
INSTALL?= cp -r
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(uname_S),AIX)
|
||||||
|
INSTALL?= cp -r
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
INSTALL?= cp -a
|
||||||
|
|
||||||
|
install: $(DYLIBNAME) $(STLIBNAME)
|
||||||
|
mkdir -p $(INSTALL_INCLUDE_PATH) $(INSTALL_LIBRARY_PATH) $(INSTALL_BINARY_PATH)
|
||||||
|
$(INSTALL) zlog.h $(INSTALL_INCLUDE_PATH)
|
||||||
|
$(INSTALL) zlog-chk-conf $(INSTALL_BINARY_PATH)
|
||||||
|
$(INSTALL) $(DYLIBNAME) $(INSTALL_LIBRARY_PATH)/$(DYLIB_MINOR_NAME)
|
||||||
|
cd $(INSTALL_LIBRARY_PATH) && ln -sf $(DYLIB_MINOR_NAME) $(DYLIB_MAJOR_NAME)
|
||||||
|
cd $(INSTALL_LIBRARY_PATH) && ln -sf $(DYLIB_MAJOR_NAME) $(DYLIBNAME)
|
||||||
|
$(INSTALL) $(STLIBNAME) $(INSTALL_LIBRARY_PATH)
|
||||||
|
|
||||||
|
32bit:
|
||||||
|
@echo ""
|
||||||
|
@echo "WARNING: if this fails under Linux you probably need to install libc6-dev-i386"
|
||||||
|
@echo ""
|
||||||
|
$(MAKE) CFLAGS="-m32" LDFLAGS="-m32"
|
||||||
|
|
||||||
|
gprof:
|
||||||
|
$(MAKE) CFLAGS="-pg" LDFLAGS="-pg"
|
||||||
|
|
||||||
|
gcov:
|
||||||
|
$(MAKE) CFLAGS="-fprofile-arcs -ftest-coverage" LDFLAGS="-fprofile-arcs"
|
||||||
|
|
||||||
|
coverage: gcov
|
||||||
|
make check
|
||||||
|
mkdir -p tmp/lcov
|
||||||
|
lcov -d . -c -o tmp/lcov/hiredis.info
|
||||||
|
genhtml --legend -o tmp/lcov/report tmp/lcov/hiredis.info
|
||||||
|
|
||||||
|
noopt:
|
||||||
|
$(MAKE) OPTIMIZATION=""
|
||||||
|
|
||||||
|
.PHONY: all clean dep install 32bit gprof gcov noopt
|
||||||
@ -0,0 +1,145 @@
|
|||||||
|
/*
|
||||||
|
* 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 <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "mdc.h"
|
||||||
|
#include "zc_defs.h"
|
||||||
|
|
||||||
|
void zlog_mdc_profile(zlog_mdc_t *a_mdc, int flag)
|
||||||
|
{
|
||||||
|
zc_hashtable_entry_t *a_entry;
|
||||||
|
zlog_mdc_kv_t *a_mdc_kv;
|
||||||
|
|
||||||
|
zc_assert(a_mdc,);
|
||||||
|
zc_profile(flag, "---mdc[%p]---", a_mdc);
|
||||||
|
|
||||||
|
zc_hashtable_foreach(a_mdc->tab, a_entry) {
|
||||||
|
a_mdc_kv = a_entry->value;
|
||||||
|
zc_profile(flag, "----mdc_kv[%p][%s]-[%s]----",
|
||||||
|
a_mdc_kv,
|
||||||
|
a_mdc_kv->key, a_mdc_kv->value);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*******************************************************************************/
|
||||||
|
void zlog_mdc_del(zlog_mdc_t * a_mdc)
|
||||||
|
{
|
||||||
|
zc_assert(a_mdc,);
|
||||||
|
if (a_mdc->tab) zc_hashtable_del(a_mdc->tab);
|
||||||
|
zc_debug("zlog_mdc_del[%p]", a_mdc);
|
||||||
|
free(a_mdc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void zlog_mdc_kv_del(zlog_mdc_kv_t * a_mdc_kv)
|
||||||
|
{
|
||||||
|
zc_debug("zlog_mdc_kv_del[%p]", a_mdc_kv);
|
||||||
|
free(a_mdc_kv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static zlog_mdc_kv_t *zlog_mdc_kv_new(const char *key, const char *value)
|
||||||
|
{
|
||||||
|
zlog_mdc_kv_t *a_mdc_kv;
|
||||||
|
|
||||||
|
a_mdc_kv = calloc(1, sizeof(zlog_mdc_kv_t));
|
||||||
|
if (!a_mdc_kv) {
|
||||||
|
zc_error("calloc fail, errno[%d]", errno);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(a_mdc_kv->key, sizeof(a_mdc_kv->key), "%s", key);
|
||||||
|
a_mdc_kv->value_len = snprintf(a_mdc_kv->value, sizeof(a_mdc_kv->value), "%s", value);
|
||||||
|
return a_mdc_kv;
|
||||||
|
}
|
||||||
|
|
||||||
|
zlog_mdc_t *zlog_mdc_new(void)
|
||||||
|
{
|
||||||
|
zlog_mdc_t *a_mdc;
|
||||||
|
|
||||||
|
a_mdc = calloc(1, sizeof(zlog_mdc_t));
|
||||||
|
if (!a_mdc) {
|
||||||
|
zc_error("calloc fail, errno[%d]", errno);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_mdc->tab = zc_hashtable_new(20,
|
||||||
|
zc_hashtable_str_hash,
|
||||||
|
zc_hashtable_str_equal, NULL,
|
||||||
|
(zc_hashtable_del_fn) zlog_mdc_kv_del);
|
||||||
|
if (!a_mdc->tab) {
|
||||||
|
zc_error("zc_hashtable_new fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
//zlog_mdc_profile(a_mdc, ZC_DEBUG);
|
||||||
|
return a_mdc;
|
||||||
|
err:
|
||||||
|
zlog_mdc_del(a_mdc);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
int zlog_mdc_put(zlog_mdc_t * a_mdc, const char *key, const char *value)
|
||||||
|
{
|
||||||
|
zlog_mdc_kv_t *a_mdc_kv;
|
||||||
|
|
||||||
|
a_mdc_kv = zlog_mdc_kv_new(key, value);
|
||||||
|
if (!a_mdc_kv) {
|
||||||
|
zc_error("zlog_mdc_kv_new failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zc_hashtable_put(a_mdc->tab, a_mdc_kv->key, a_mdc_kv)) {
|
||||||
|
zc_error("zc_hashtable_put fail");
|
||||||
|
zlog_mdc_kv_del(a_mdc_kv);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void zlog_mdc_clean(zlog_mdc_t * a_mdc)
|
||||||
|
{
|
||||||
|
zc_hashtable_clean(a_mdc->tab);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *zlog_mdc_get(zlog_mdc_t * a_mdc, const char *key)
|
||||||
|
{
|
||||||
|
zlog_mdc_kv_t *a_mdc_kv;
|
||||||
|
|
||||||
|
a_mdc_kv = zc_hashtable_get(a_mdc->tab, key);
|
||||||
|
if (!a_mdc_kv) {
|
||||||
|
zc_error("zc_hashtable_get fail");
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
return a_mdc_kv->value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zlog_mdc_kv_t *zlog_mdc_get_kv(zlog_mdc_t * a_mdc, const char *key)
|
||||||
|
{
|
||||||
|
zlog_mdc_kv_t *a_mdc_kv;
|
||||||
|
|
||||||
|
a_mdc_kv = zc_hashtable_get(a_mdc->tab, key);
|
||||||
|
if (!a_mdc_kv) {
|
||||||
|
zc_error("zc_hashtable_get fail");
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
return a_mdc_kv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void zlog_mdc_remove(zlog_mdc_t * a_mdc, const char *key)
|
||||||
|
{
|
||||||
|
zc_hashtable_remove(a_mdc->tab, key);
|
||||||
|
return;
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __zlog_mdc_h
|
||||||
|
#define __zlog_mdc_h
|
||||||
|
|
||||||
|
#include "zc_defs.h"
|
||||||
|
|
||||||
|
typedef struct zlog_mdc_s zlog_mdc_t;
|
||||||
|
struct zlog_mdc_s {
|
||||||
|
zc_hashtable_t *tab;
|
||||||
|
};
|
||||||
|
|
||||||
|
zlog_mdc_t *zlog_mdc_new(void);
|
||||||
|
void zlog_mdc_del(zlog_mdc_t * a_mdc);
|
||||||
|
void zlog_mdc_profile(zlog_mdc_t *a_mdc, int flag);
|
||||||
|
|
||||||
|
void zlog_mdc_clean(zlog_mdc_t * a_mdc);
|
||||||
|
int zlog_mdc_put(zlog_mdc_t * a_mdc, const char *key, const char *value);
|
||||||
|
char *zlog_mdc_get(zlog_mdc_t * a_mdc, const char *key);
|
||||||
|
void zlog_mdc_remove(zlog_mdc_t * a_mdc, const char *key);
|
||||||
|
|
||||||
|
typedef struct zlog_mdc_kv_s {
|
||||||
|
char key[MAXLEN_PATH + 1];
|
||||||
|
char value[MAXLEN_PATH + 1];
|
||||||
|
size_t value_len;
|
||||||
|
} zlog_mdc_kv_t;
|
||||||
|
|
||||||
|
zlog_mdc_kv_t *zlog_mdc_get_kv(zlog_mdc_t * a_mdc, const char *key);
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* 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 "errno.h"
|
||||||
|
#include "zc_defs.h"
|
||||||
|
#include "record.h"
|
||||||
|
|
||||||
|
void zlog_record_profile(zlog_record_t *a_record, int flag)
|
||||||
|
{
|
||||||
|
zc_assert(a_record,);
|
||||||
|
zc_profile(flag, "--record:[%p][%s:%p]--", a_record, a_record->name, a_record->output);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void zlog_record_del(zlog_record_t *a_record)
|
||||||
|
{
|
||||||
|
zc_assert(a_record,);
|
||||||
|
zc_debug("zlog_record_del[%p]", a_record);
|
||||||
|
free(a_record);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
zlog_record_t *zlog_record_new(const char *name, zlog_record_fn output)
|
||||||
|
{
|
||||||
|
zlog_record_t *a_record;
|
||||||
|
|
||||||
|
zc_assert(name, NULL);
|
||||||
|
zc_assert(output, NULL);
|
||||||
|
|
||||||
|
a_record = calloc(1, sizeof(zlog_record_t));
|
||||||
|
if (!a_record) {
|
||||||
|
zc_error("calloc fail, errno[%d]", errno);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(name) > sizeof(a_record->name) - 1) {
|
||||||
|
zc_error("name[%s] is too long", name);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(a_record->name, name);
|
||||||
|
a_record->output = output;
|
||||||
|
|
||||||
|
zlog_record_profile(a_record, ZC_DEBUG);
|
||||||
|
return a_record;
|
||||||
|
err:
|
||||||
|
zlog_record_del(a_record);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __zlog_record_h
|
||||||
|
#define __zlog_record_h
|
||||||
|
|
||||||
|
#include "zc_defs.h"
|
||||||
|
|
||||||
|
/* record is user-defined output function and it's name from configure file */
|
||||||
|
typedef struct zlog_msg_s {
|
||||||
|
char *buf;
|
||||||
|
size_t len;
|
||||||
|
char *path;
|
||||||
|
} zlog_msg_t; /* 3 of this first, see need thread or not later */
|
||||||
|
|
||||||
|
typedef int (*zlog_record_fn)(zlog_msg_t * msg);
|
||||||
|
|
||||||
|
typedef struct zlog_record_s {
|
||||||
|
char name[MAXLEN_PATH + 1];
|
||||||
|
zlog_record_fn output;
|
||||||
|
} zlog_record_t;
|
||||||
|
|
||||||
|
zlog_record_t *zlog_record_new(const char *name, zlog_record_fn output);
|
||||||
|
void zlog_record_del(zlog_record_t *a_record);
|
||||||
|
void zlog_record_profile(zlog_record_t *a_record, int flag);
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* 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 <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "zc_defs.h"
|
||||||
|
#include "record_table.h"
|
||||||
|
|
||||||
|
void zlog_record_table_profile(zc_hashtable_t * records, int flag)
|
||||||
|
{
|
||||||
|
zc_hashtable_entry_t *a_entry;
|
||||||
|
zlog_record_t *a_record;
|
||||||
|
|
||||||
|
zc_assert(records,);
|
||||||
|
zc_profile(flag, "-record_table[%p]-", records);
|
||||||
|
zc_hashtable_foreach(records, a_entry) {
|
||||||
|
a_record = (zlog_record_t *) a_entry->value;
|
||||||
|
zlog_record_profile(a_record, flag);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
|
||||||
|
void zlog_record_table_del(zc_hashtable_t * records)
|
||||||
|
{
|
||||||
|
zc_assert(records,);
|
||||||
|
zc_hashtable_del(records);
|
||||||
|
zc_debug("zlog_record_table_del[%p]", records);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
zc_hashtable_t *zlog_record_table_new(void)
|
||||||
|
{
|
||||||
|
zc_hashtable_t *records;
|
||||||
|
|
||||||
|
records = zc_hashtable_new(20,
|
||||||
|
(zc_hashtable_hash_fn) zc_hashtable_str_hash,
|
||||||
|
(zc_hashtable_equal_fn) zc_hashtable_str_equal,
|
||||||
|
NULL, (zc_hashtable_del_fn) zlog_record_del);
|
||||||
|
if (!records) {
|
||||||
|
zc_error("zc_hashtable_new fail");
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
zlog_record_table_profile(records, ZC_DEBUG);
|
||||||
|
return records;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*******************************************************************************/
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __zlog_record_table_h
|
||||||
|
#define __zlog_record_table_h
|
||||||
|
|
||||||
|
#include "zc_defs.h"
|
||||||
|
#include "record.h"
|
||||||
|
|
||||||
|
zc_hashtable_t *zlog_record_table_new(void);
|
||||||
|
void zlog_record_table_del(zc_hashtable_t * records);
|
||||||
|
void zlog_record_table_profile(zc_hashtable_t * records, int flag);
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,575 @@
|
|||||||
|
/*
|
||||||
|
* 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 <string.h>
|
||||||
|
#include <glob.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include "zc_defs.h"
|
||||||
|
#include "rotater.h"
|
||||||
|
|
||||||
|
#define ROLLING 1 /* aa.02->aa.03, aa.01->aa.02, aa->aa.01 */
|
||||||
|
#define SEQUENCE 2 /* aa->aa.03 */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int index;
|
||||||
|
char path[MAXLEN_PATH + 1];
|
||||||
|
} zlog_file_t;
|
||||||
|
|
||||||
|
void zlog_rotater_profile(zlog_rotater_t * a_rotater, int flag)
|
||||||
|
{
|
||||||
|
zc_assert(a_rotater,);
|
||||||
|
zc_profile(flag, "--rotater[%p][%p,%s,%d][%s,%s,%s,%ld,%ld,%d,%d,%d]--",
|
||||||
|
a_rotater,
|
||||||
|
|
||||||
|
&(a_rotater->lock_mutex),
|
||||||
|
a_rotater->lock_file,
|
||||||
|
a_rotater->lock_fd,
|
||||||
|
|
||||||
|
a_rotater->base_path,
|
||||||
|
a_rotater->archive_path,
|
||||||
|
a_rotater->glob_path,
|
||||||
|
(long)a_rotater->num_start_len,
|
||||||
|
(long)a_rotater->num_end_len,
|
||||||
|
a_rotater->num_width,
|
||||||
|
a_rotater->mv_type,
|
||||||
|
a_rotater->max_count
|
||||||
|
);
|
||||||
|
if (a_rotater->files) {
|
||||||
|
int i;
|
||||||
|
zlog_file_t *a_file;
|
||||||
|
zc_arraylist_foreach(a_rotater->files, i, a_file) {
|
||||||
|
zc_profile(flag, "[%s,%d]->", a_file->path, a_file->index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
void zlog_rotater_del(zlog_rotater_t *a_rotater)
|
||||||
|
{
|
||||||
|
zc_assert(a_rotater,);
|
||||||
|
|
||||||
|
if (a_rotater->lock_fd) {
|
||||||
|
if (close(a_rotater->lock_fd)) {
|
||||||
|
zc_error("close fail, errno[%d]", errno);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pthread_mutex_destroy(&(a_rotater->lock_mutex))) {
|
||||||
|
zc_error("pthread_mutex_destroy fail, errno[%d]", errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
zc_debug("zlog_rotater_del[%p]", a_rotater);
|
||||||
|
free(a_rotater);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
zlog_rotater_t *zlog_rotater_new(char *lock_file)
|
||||||
|
{
|
||||||
|
int fd = 0;
|
||||||
|
zlog_rotater_t *a_rotater;
|
||||||
|
|
||||||
|
zc_assert(lock_file, NULL);
|
||||||
|
|
||||||
|
a_rotater = calloc(1, sizeof(zlog_rotater_t));
|
||||||
|
if (!a_rotater) {
|
||||||
|
zc_error("calloc fail, errno[%d]", errno);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pthread_mutex_init(&(a_rotater->lock_mutex), NULL)) {
|
||||||
|
zc_error("pthread_mutex_init fail, errno[%d]", errno);
|
||||||
|
free(a_rotater);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* depends on umask of the user here
|
||||||
|
* if user A create /tmp/zlog.lock 0600
|
||||||
|
* user B is unable to read /tmp/zlog.lock
|
||||||
|
* B has to choose another lock file except /tmp/zlog.lock
|
||||||
|
*/
|
||||||
|
fd = open(lock_file, O_RDWR | O_CREAT,
|
||||||
|
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
|
||||||
|
if (fd < 0) {
|
||||||
|
zc_error("open file[%s] fail, errno[%d]", lock_file, errno);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_rotater->lock_fd = fd;
|
||||||
|
a_rotater->lock_file = lock_file;
|
||||||
|
|
||||||
|
//zlog_rotater_profile(a_rotater, ZC_DEBUG);
|
||||||
|
return a_rotater;
|
||||||
|
err:
|
||||||
|
zlog_rotater_del(a_rotater);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
|
||||||
|
static void zlog_file_del(zlog_file_t * a_file)
|
||||||
|
{
|
||||||
|
zc_debug("del onefile[%p]", a_file);
|
||||||
|
zc_debug("a_file->path[%s]", a_file->path);
|
||||||
|
free(a_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
static zlog_file_t *zlog_file_check_new(zlog_rotater_t * a_rotater, const char *path)
|
||||||
|
{
|
||||||
|
int nwrite;
|
||||||
|
int nread;
|
||||||
|
zlog_file_t *a_file;
|
||||||
|
|
||||||
|
/* base_path will not be in list */
|
||||||
|
if (STRCMP(a_rotater->base_path, ==, path)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* omit dirs */
|
||||||
|
if ((path)[strlen(path) - 1] == '/') {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_file = calloc(1, sizeof(zlog_file_t));
|
||||||
|
if (!a_file) {
|
||||||
|
zc_error("calloc fail, errno[%d]", errno);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
nwrite = snprintf(a_file->path, sizeof(a_file->path), "%s", path);
|
||||||
|
if (nwrite < 0 || nwrite >= sizeof(a_file->path)) {
|
||||||
|
zc_error("snprintf fail or overflow, nwrite=[%d], errno[%d]", nwrite, errno);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
nread = 0;
|
||||||
|
sscanf(a_file->path + a_rotater->num_start_len, "%d%n", &(a_file->index), &(nread));
|
||||||
|
|
||||||
|
if (a_rotater->num_width != 0) {
|
||||||
|
if (nread < a_rotater->num_width) {
|
||||||
|
zc_warn("aa.1.log is not expect, need aa.01.log");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
} /* else all file is ok */
|
||||||
|
|
||||||
|
return a_file;
|
||||||
|
err:
|
||||||
|
free(a_file);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int zlog_file_cmp(zlog_file_t * a_file_1, zlog_file_t * a_file_2)
|
||||||
|
{
|
||||||
|
return (a_file_1->index > a_file_2->index);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zlog_rotater_add_archive_files(zlog_rotater_t * a_rotater)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
glob_t glob_buf;
|
||||||
|
size_t pathc;
|
||||||
|
char **pathv;
|
||||||
|
zlog_file_t *a_file;
|
||||||
|
|
||||||
|
a_rotater->files = zc_arraylist_new((zc_arraylist_del_fn)zlog_file_del);
|
||||||
|
if (!a_rotater->files) {
|
||||||
|
zc_error("zc_arraylist_new fail");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* scan file which is aa.*.log and aa */
|
||||||
|
rc = glob(a_rotater->glob_path, GLOB_ERR | GLOB_MARK | GLOB_NOSORT, NULL, &glob_buf);
|
||||||
|
if (rc == GLOB_NOMATCH) {
|
||||||
|
goto exit;
|
||||||
|
} else if (rc) {
|
||||||
|
zc_error("glob err, rc=[%d], errno[%d]", rc, errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pathv = glob_buf.gl_pathv;
|
||||||
|
pathc = glob_buf.gl_pathc;
|
||||||
|
|
||||||
|
/* check and find match aa.[0-9]*.log, depend on num_width */
|
||||||
|
for (; pathc-- > 0; pathv++) {
|
||||||
|
a_file = zlog_file_check_new(a_rotater, *pathv);
|
||||||
|
if (!a_file) {
|
||||||
|
zc_warn("not the expect pattern file");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* file in list aa.00, aa.01, aa.02... */
|
||||||
|
rc = zc_arraylist_sortadd(a_rotater->files,
|
||||||
|
(zc_arraylist_cmp_fn)zlog_file_cmp, a_file);
|
||||||
|
if (rc) {
|
||||||
|
zc_error("zc_arraylist_sortadd fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
globfree(&glob_buf);
|
||||||
|
return 0;
|
||||||
|
err:
|
||||||
|
globfree(&glob_buf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zlog_rotater_seq_files(zlog_rotater_t * a_rotater)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
int nwrite = 0;
|
||||||
|
int i, j;
|
||||||
|
zlog_file_t *a_file;
|
||||||
|
char new_path[MAXLEN_PATH + 1];
|
||||||
|
|
||||||
|
zc_arraylist_foreach(a_rotater->files, i, a_file) {
|
||||||
|
if (a_rotater->max_count > 0
|
||||||
|
&& i < zc_arraylist_len(a_rotater->files) - a_rotater->max_count) {
|
||||||
|
/* unlink aa.0 aa.1 .. aa.(n-c) */
|
||||||
|
rc = unlink(a_file->path);
|
||||||
|
if (rc) {
|
||||||
|
zc_error("unlink[%s] fail, errno[%d]",a_file->path , errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zc_arraylist_len(a_rotater->files) > 0) { /* list is not empty */
|
||||||
|
a_file = zc_arraylist_get(a_rotater->files, zc_arraylist_len(a_rotater->files)-1);
|
||||||
|
if (!a_file) {
|
||||||
|
zc_error("zc_arraylist_get fail");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
j = zc_max(zc_arraylist_len(a_rotater->files)-1, a_file->index) + 1;
|
||||||
|
} else {
|
||||||
|
j = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do the base_path mv */
|
||||||
|
memset(new_path, 0x00, sizeof(new_path));
|
||||||
|
nwrite = snprintf(new_path, sizeof(new_path), "%.*s%0*d%s",
|
||||||
|
(int) a_rotater->num_start_len, a_rotater->glob_path,
|
||||||
|
a_rotater->num_width, j,
|
||||||
|
a_rotater->glob_path + a_rotater->num_end_len);
|
||||||
|
if (nwrite < 0 || nwrite >= sizeof(new_path)) {
|
||||||
|
zc_error("nwirte[%d], overflow or errno[%d]", nwrite, errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rename(a_rotater->base_path, new_path)) {
|
||||||
|
zc_error("rename[%s]->[%s] fail, errno[%d]", a_rotater->base_path, new_path, errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int zlog_rotater_roll_files(zlog_rotater_t * a_rotater)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int rc = 0;
|
||||||
|
int nwrite;
|
||||||
|
char new_path[MAXLEN_PATH + 1];
|
||||||
|
zlog_file_t *a_file;
|
||||||
|
|
||||||
|
/* now in the list, aa.0 aa.1 aa.2 aa.02... */
|
||||||
|
for (i = zc_arraylist_len(a_rotater->files) - 1; i > -1; i--) {
|
||||||
|
a_file = zc_arraylist_get(a_rotater->files, i);
|
||||||
|
if (!a_file) {
|
||||||
|
zc_error("zc_arraylist_get fail");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a_rotater->max_count > 0 && i >= a_rotater->max_count - 1) {
|
||||||
|
/* remove file.3 >= 3*/
|
||||||
|
rc = unlink(a_file->path);
|
||||||
|
if (rc) {
|
||||||
|
zc_error("unlink[%s] fail, errno[%d]",a_file->path , errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* begin rename aa.01.log -> aa.02.log , using i, as index in list maybe repeat */
|
||||||
|
memset(new_path, 0x00, sizeof(new_path));
|
||||||
|
nwrite = snprintf(new_path, sizeof(new_path), "%.*s%0*d%s",
|
||||||
|
(int) a_rotater->num_start_len, a_rotater->glob_path,
|
||||||
|
a_rotater->num_width, i + 1,
|
||||||
|
a_rotater->glob_path + a_rotater->num_end_len);
|
||||||
|
if (nwrite < 0 || nwrite >= sizeof(new_path)) {
|
||||||
|
zc_error("nwirte[%d], overflow or errno[%d]", nwrite, errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rename(a_file->path, new_path)) {
|
||||||
|
zc_error("rename[%s]->[%s] fail, errno[%d]", a_file->path, new_path, errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do the base_path mv */
|
||||||
|
memset(new_path, 0x00, sizeof(new_path));
|
||||||
|
nwrite = snprintf(new_path, sizeof(new_path), "%.*s%0*d%s",
|
||||||
|
(int) a_rotater->num_start_len, a_rotater->glob_path,
|
||||||
|
a_rotater->num_width, 0,
|
||||||
|
a_rotater->glob_path + a_rotater->num_end_len);
|
||||||
|
if (nwrite < 0 || nwrite >= sizeof(new_path)) {
|
||||||
|
zc_error("nwirte[%d], overflow or errno[%d]", nwrite, errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rename(a_rotater->base_path, new_path)) {
|
||||||
|
zc_error("rename[%s]->[%s] fail, errno[%d]", a_rotater->base_path, new_path, errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int zlog_rotater_parse_archive_path(zlog_rotater_t * a_rotater)
|
||||||
|
{
|
||||||
|
int nwrite;
|
||||||
|
int nread;
|
||||||
|
char *p;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
/* no archive path is set */
|
||||||
|
if (a_rotater->archive_path[0] == '\0') {
|
||||||
|
nwrite = snprintf(a_rotater->glob_path, sizeof(a_rotater->glob_path),
|
||||||
|
"%s.*", a_rotater->base_path);
|
||||||
|
if (nwrite < 0 || nwrite > sizeof(a_rotater->glob_path)) {
|
||||||
|
zc_error("nwirte[%d], overflow or errno[%d]", nwrite, errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_rotater->mv_type = ROLLING;
|
||||||
|
a_rotater->num_width = 0;
|
||||||
|
a_rotater->num_start_len = strlen(a_rotater->base_path) + 1;
|
||||||
|
a_rotater->num_end_len = strlen(a_rotater->base_path) + 2;
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/* find the 1st # */
|
||||||
|
p = strchr(a_rotater->archive_path, '#');
|
||||||
|
if (!p) {
|
||||||
|
zc_error("no # in archive_path[%s]", a_rotater->archive_path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
nread = 0;
|
||||||
|
sscanf(p, "#%d%n", &(a_rotater->num_width), &nread);
|
||||||
|
if (nread == 0) nread = 1;
|
||||||
|
if (*(p+nread) == 'r') {
|
||||||
|
a_rotater->mv_type = ROLLING;
|
||||||
|
} else if (*(p+nread) == 's') {
|
||||||
|
a_rotater->mv_type = SEQUENCE;
|
||||||
|
} else {
|
||||||
|
zc_error("#r or #s not found");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy and substitue #i to * in glob_path*/
|
||||||
|
len = p - a_rotater->archive_path;
|
||||||
|
if (len > sizeof(a_rotater->glob_path) - 1) {
|
||||||
|
zc_error("sizeof glob_path not enough,len[%ld]", (long) len);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memcpy(a_rotater->glob_path, a_rotater->archive_path, len);
|
||||||
|
|
||||||
|
nwrite = snprintf(a_rotater->glob_path + len, sizeof(a_rotater->glob_path) - len,
|
||||||
|
"*%s", p + nread + 1);
|
||||||
|
if (nwrite < 0 || nwrite > sizeof(a_rotater->glob_path) - len) {
|
||||||
|
zc_error("nwirte[%d], overflow or errno[%d]", nwrite, errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_rotater->num_start_len = len;
|
||||||
|
a_rotater->num_end_len = len + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void zlog_rotater_clean(zlog_rotater_t *a_rotater)
|
||||||
|
{
|
||||||
|
a_rotater->base_path = NULL;
|
||||||
|
a_rotater->archive_path = NULL;
|
||||||
|
a_rotater->max_count = 0;
|
||||||
|
a_rotater->mv_type = 0;
|
||||||
|
a_rotater->num_width = 0;
|
||||||
|
a_rotater->num_start_len = 0;
|
||||||
|
a_rotater->num_end_len = 0;
|
||||||
|
memset(a_rotater->glob_path, 0x00, sizeof(a_rotater->glob_path));
|
||||||
|
|
||||||
|
if (a_rotater->files) zc_arraylist_del(a_rotater->files);
|
||||||
|
a_rotater->files = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zlog_rotater_lsmv(zlog_rotater_t *a_rotater,
|
||||||
|
char *base_path, char *archive_path, int archive_max_count)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
a_rotater->base_path = base_path;
|
||||||
|
a_rotater->archive_path = archive_path;
|
||||||
|
a_rotater->max_count = archive_max_count;
|
||||||
|
rc = zlog_rotater_parse_archive_path(a_rotater);
|
||||||
|
if (rc) {
|
||||||
|
zc_error("zlog_rotater_parse_archive_path fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = zlog_rotater_add_archive_files(a_rotater);
|
||||||
|
if (rc) {
|
||||||
|
zc_error("zlog_rotater_add_archive_files fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a_rotater->mv_type == ROLLING) {
|
||||||
|
rc = zlog_rotater_roll_files(a_rotater);
|
||||||
|
if (rc) {
|
||||||
|
zc_error("zlog_rotater_roll_files fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
} else if (a_rotater->mv_type == SEQUENCE) {
|
||||||
|
rc = zlog_rotater_seq_files(a_rotater);
|
||||||
|
if (rc) {
|
||||||
|
zc_error("zlog_rotater_seq_files fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zlog_rotater_clean(a_rotater);
|
||||||
|
return 0;
|
||||||
|
err:
|
||||||
|
zlog_rotater_clean(a_rotater);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/*******************************************************************************/
|
||||||
|
|
||||||
|
static int zlog_rotater_trylock(zlog_rotater_t *a_rotater)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
struct flock fl;
|
||||||
|
|
||||||
|
fl.l_type = F_WRLCK;
|
||||||
|
fl.l_start = 0;
|
||||||
|
fl.l_whence = SEEK_SET;
|
||||||
|
fl.l_len = 0;
|
||||||
|
|
||||||
|
rc = pthread_mutex_trylock(&(a_rotater->lock_mutex));
|
||||||
|
if (rc == EBUSY) {
|
||||||
|
zc_warn("pthread_mutex_trylock fail, as lock_mutex is locked by other threads");
|
||||||
|
return -1;
|
||||||
|
} else if (rc != 0) {
|
||||||
|
zc_error("pthread_mutex_trylock fail, rc[%d]", rc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fcntl(a_rotater->lock_fd, F_SETLK, &fl)) {
|
||||||
|
if (errno == EAGAIN || errno == EACCES) {
|
||||||
|
/* lock by other process, that's right, go on */
|
||||||
|
/* EAGAIN on linux */
|
||||||
|
/* EACCES on AIX */
|
||||||
|
zc_warn("fcntl lock fail, as file is lock by other process");
|
||||||
|
} else {
|
||||||
|
zc_error("lock fd[%d] fail, errno[%d]", a_rotater->lock_fd, errno);
|
||||||
|
}
|
||||||
|
if (pthread_mutex_unlock(&(a_rotater->lock_mutex))) {
|
||||||
|
zc_error("pthread_mutex_unlock fail, errno[%d]", errno);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zlog_rotater_unlock(zlog_rotater_t *a_rotater)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
struct flock fl;
|
||||||
|
|
||||||
|
fl.l_type = F_UNLCK;
|
||||||
|
fl.l_start = 0;
|
||||||
|
fl.l_whence = SEEK_SET;
|
||||||
|
fl.l_len = 0;
|
||||||
|
|
||||||
|
if (fcntl(a_rotater->lock_fd, F_SETLK, &fl)) {
|
||||||
|
rc = -1;
|
||||||
|
zc_error("unlock fd[%s] fail, errno[%d]", a_rotater->lock_fd, errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pthread_mutex_unlock(&(a_rotater->lock_mutex))) {
|
||||||
|
rc = -1;
|
||||||
|
zc_error("pthread_mutext_unlock fail, errno[%d]", errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int zlog_rotater_rotate(zlog_rotater_t *a_rotater,
|
||||||
|
char *base_path, size_t msg_len,
|
||||||
|
char *archive_path, long archive_max_size, int archive_max_count)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
struct zlog_stat info;
|
||||||
|
|
||||||
|
zc_assert(base_path, -1);
|
||||||
|
|
||||||
|
if (zlog_rotater_trylock(a_rotater)) {
|
||||||
|
zc_warn("zlog_rotater_trylock fail, maybe lock by other process or threads");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stat(base_path, &info)) {
|
||||||
|
rc = -1;
|
||||||
|
zc_error("stat [%s] fail, errno[%d]", base_path, errno);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.st_size + msg_len <= archive_max_size) {
|
||||||
|
/* file not so big,
|
||||||
|
* may alread rotate by oth process or thread,
|
||||||
|
* return */
|
||||||
|
rc = 0;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* begin list and move files */
|
||||||
|
rc = zlog_rotater_lsmv(a_rotater, base_path, archive_path, archive_max_count);
|
||||||
|
if (rc) {
|
||||||
|
zc_error("zlog_rotater_lsmv [%s] fail, return", base_path);
|
||||||
|
rc = -1;
|
||||||
|
} /* else if (rc == 0) */
|
||||||
|
|
||||||
|
//zc_debug("zlog_rotater_file_ls_mv success");
|
||||||
|
|
||||||
|
exit:
|
||||||
|
/* unlock file */
|
||||||
|
if (zlog_rotater_unlock(a_rotater)) {
|
||||||
|
zc_error("zlog_rotater_unlock fail");
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __zlog_rotater_h
|
||||||
|
#define __zlog_rotater_h
|
||||||
|
|
||||||
|
#include "zc_defs.h"
|
||||||
|
|
||||||
|
typedef struct zlog_rotater_s {
|
||||||
|
pthread_mutex_t lock_mutex;
|
||||||
|
char *lock_file;
|
||||||
|
int lock_fd;
|
||||||
|
|
||||||
|
/* single-use members */
|
||||||
|
char *base_path; /* aa.log */
|
||||||
|
char *archive_path; /* aa.#5i.log */
|
||||||
|
char glob_path[MAXLEN_PATH + 1]; /* aa.*.log */
|
||||||
|
size_t num_start_len; /* 3, offset to glob_path */
|
||||||
|
size_t num_end_len; /* 6, offset to glob_path */
|
||||||
|
int num_width; /* 5 */
|
||||||
|
int mv_type; /* ROLLING or SEQUENCE */
|
||||||
|
int max_count;
|
||||||
|
zc_arraylist_t *files;
|
||||||
|
} zlog_rotater_t;
|
||||||
|
|
||||||
|
zlog_rotater_t *zlog_rotater_new(char *lock_file);
|
||||||
|
void zlog_rotater_del(zlog_rotater_t *a_rotater);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* return
|
||||||
|
* -1 fail
|
||||||
|
* 0 no rotate, or rotate and success
|
||||||
|
*/
|
||||||
|
int zlog_rotater_rotate(zlog_rotater_t *a_rotater,
|
||||||
|
char *base_path, size_t msg_len,
|
||||||
|
char *archive_path, long archive_max_size, int archive_max_count);
|
||||||
|
|
||||||
|
void zlog_rotater_profile(zlog_rotater_t *a_rotater, int flag);
|
||||||
|
|
||||||
|
#endif
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file rule.h
|
||||||
|
* @brief rule decide to output in format by category & level
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __zlog_rule_h
|
||||||
|
#define __zlog_rule_h
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include "zc_defs.h"
|
||||||
|
#include "format.h"
|
||||||
|
#include "thread.h"
|
||||||
|
#include "rotater.h"
|
||||||
|
#include "record.h"
|
||||||
|
|
||||||
|
typedef struct zlog_rule_s zlog_rule_t;
|
||||||
|
|
||||||
|
typedef int (*zlog_rule_output_fn) (zlog_rule_t * a_rule, zlog_thread_t * a_thread);
|
||||||
|
|
||||||
|
struct zlog_rule_s {
|
||||||
|
char category[MAXLEN_CFG_LINE + 1];
|
||||||
|
char compare_char;
|
||||||
|
/*
|
||||||
|
* [*] log all level
|
||||||
|
* [.] log level >= rule level, default
|
||||||
|
* [=] log level == rule level
|
||||||
|
* [!] log level != rule level
|
||||||
|
*/
|
||||||
|
int level;
|
||||||
|
unsigned char level_bitmap[32]; /* for category determine whether ouput or not */
|
||||||
|
|
||||||
|
unsigned int file_perms;
|
||||||
|
int file_open_flags;
|
||||||
|
|
||||||
|
char file_path[MAXLEN_PATH + 1];
|
||||||
|
zc_arraylist_t *dynamic_specs;
|
||||||
|
int static_fd;
|
||||||
|
dev_t static_dev;
|
||||||
|
ino_t static_ino;
|
||||||
|
|
||||||
|
long archive_max_size;
|
||||||
|
int archive_max_count;
|
||||||
|
char archive_path[MAXLEN_PATH + 1];
|
||||||
|
zc_arraylist_t *archive_specs;
|
||||||
|
|
||||||
|
FILE *pipe_fp;
|
||||||
|
int pipe_fd;
|
||||||
|
|
||||||
|
size_t fsync_period;
|
||||||
|
size_t fsync_count;
|
||||||
|
|
||||||
|
zc_arraylist_t *levels;
|
||||||
|
int syslog_facility;
|
||||||
|
|
||||||
|
zlog_format_t *format;
|
||||||
|
zlog_rule_output_fn output;
|
||||||
|
|
||||||
|
char record_name[MAXLEN_PATH + 1];
|
||||||
|
char record_path[MAXLEN_PATH + 1];
|
||||||
|
zlog_record_fn record_func;
|
||||||
|
};
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
void zlog_rule_del(zlog_rule_t * a_rule);
|
||||||
|
void zlog_rule_profile(zlog_rule_t * a_rule, int flag);
|
||||||
|
int zlog_rule_match_category(zlog_rule_t * a_rule, char *category);
|
||||||
|
int zlog_rule_is_wastebin(zlog_rule_t * a_rule);
|
||||||
|
int zlog_rule_set_record(zlog_rule_t * a_rule, zc_hashtable_t *records);
|
||||||
|
int zlog_rule_output(zlog_rule_t * a_rule, zlog_thread_t * a_thread);
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,667 @@
|
|||||||
|
/*
|
||||||
|
* 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 <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "conf.h"
|
||||||
|
#include "spec.h"
|
||||||
|
#include "level_list.h"
|
||||||
|
#include "zc_defs.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define ZLOG_DEFAULT_TIME_FMT "%F %T"
|
||||||
|
#define ZLOG_HEX_HEAD \
|
||||||
|
"\n 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF"
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
void zlog_spec_profile(zlog_spec_t * a_spec, int flag)
|
||||||
|
{
|
||||||
|
zc_assert(a_spec,);
|
||||||
|
zc_profile(flag, "----spec[%p][%.*s][%s|%d][%s,%ld,%ld,%s][%s]----",
|
||||||
|
a_spec,
|
||||||
|
a_spec->len, a_spec->str,
|
||||||
|
a_spec->time_fmt,
|
||||||
|
a_spec->time_cache_index,
|
||||||
|
a_spec->print_fmt, (long)a_spec->max_width, (long)a_spec->min_width, a_spec->left_fill_zeros ? "true" : "false",
|
||||||
|
a_spec->mdc_key);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/* implementation of write function */
|
||||||
|
|
||||||
|
static int zlog_spec_write_time(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
|
||||||
|
{
|
||||||
|
zlog_time_cache_t * a_cache = a_thread->event->time_caches + a_spec->time_cache_index;
|
||||||
|
time_t now_sec = a_thread->event->time_stamp.tv_sec;
|
||||||
|
struct tm *time_local = &(a_thread->event->time_local);
|
||||||
|
|
||||||
|
/* the event meet the 1st time_spec in his life cycle */
|
||||||
|
if (!now_sec) {
|
||||||
|
gettimeofday(&(a_thread->event->time_stamp), NULL);
|
||||||
|
now_sec = a_thread->event->time_stamp.tv_sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When this event's last cached time_local is not now */
|
||||||
|
if (a_thread->event->time_local_sec != now_sec) {
|
||||||
|
localtime_r(&(now_sec), time_local);
|
||||||
|
a_thread->event->time_local_sec = now_sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When this spec's last cache time string is not now */
|
||||||
|
if (a_cache->sec != now_sec) {
|
||||||
|
a_cache->len = strftime(a_cache->str, sizeof(a_cache->str), a_spec->time_fmt, time_local);
|
||||||
|
a_cache->sec = now_sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
return zlog_buf_append(a_buf, a_cache->str, a_cache->len);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static int zlog_spec_write_time_D(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
|
||||||
|
{
|
||||||
|
if (!a_thread->event->time_stamp.tv_sec) {
|
||||||
|
gettimeofday(&(a_thread->event->time_stamp), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* It is modified when time slips one second.
|
||||||
|
* So it is a strong cache, as Default time format is always %F %T.
|
||||||
|
* That's why I said %D is faster than %d()
|
||||||
|
*/
|
||||||
|
if (a_thread->event->time_stamp.tv_sec != a_thread->event->time_last_D) {
|
||||||
|
|
||||||
|
a_thread->event->time_last_D = a_thread->event->time_stamp.tv_sec;
|
||||||
|
localtime_r(&(a_thread->event->time_stamp.tv_sec),
|
||||||
|
&(a_thread->event->time_local));
|
||||||
|
|
||||||
|
strftime(a_thread->event->time_cache_D,
|
||||||
|
sizeof(a_thread->event->time_cache_D),
|
||||||
|
ZLOG_DEFAULT_TIME_FMT, &(a_thread->event->time_local) );
|
||||||
|
}
|
||||||
|
return zlog_buf_append(a_buf, a_thread->event->time_cache_D, sizeof(a_thread->event->time_cache_D) - 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int zlog_spec_write_ms(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
|
||||||
|
{
|
||||||
|
if (!a_thread->event->time_stamp.tv_sec) {
|
||||||
|
gettimeofday(&(a_thread->event->time_stamp), NULL);
|
||||||
|
}
|
||||||
|
return zlog_buf_printf_dec32(a_buf, (a_thread->event->time_stamp.tv_usec / 1000), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zlog_spec_write_us(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
|
||||||
|
{
|
||||||
|
if (!a_thread->event->time_stamp.tv_sec) {
|
||||||
|
gettimeofday(&(a_thread->event->time_stamp), NULL);
|
||||||
|
}
|
||||||
|
return zlog_buf_printf_dec32(a_buf, a_thread->event->time_stamp.tv_usec, 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zlog_spec_write_mdc(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
|
||||||
|
{
|
||||||
|
zlog_mdc_kv_t *a_mdc_kv;
|
||||||
|
|
||||||
|
a_mdc_kv = zlog_mdc_get_kv(a_thread->mdc, a_spec->mdc_key);
|
||||||
|
if (!a_mdc_kv) {
|
||||||
|
zc_error("zlog_mdc_get_kv key[%s] fail", a_spec->mdc_key);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return zlog_buf_append(a_buf, a_mdc_kv->value, a_mdc_kv->value_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zlog_spec_write_str(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
|
||||||
|
{
|
||||||
|
return zlog_buf_append(a_buf, a_spec->str, a_spec->len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zlog_spec_write_category(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
|
||||||
|
{
|
||||||
|
return zlog_buf_append(a_buf, a_thread->event->category_name, a_thread->event->category_name_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zlog_spec_write_srcfile(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
|
||||||
|
{
|
||||||
|
if (!a_thread->event->file) {
|
||||||
|
return zlog_buf_append(a_buf, "(file=null)", sizeof("(file=null)") - 1);
|
||||||
|
} else {
|
||||||
|
return zlog_buf_append(a_buf, a_thread->event->file, a_thread->event->file_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zlog_spec_write_srcfile_neat(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if ((p = strrchr(a_thread->event->file, '/')) != NULL) {
|
||||||
|
return zlog_buf_append(a_buf, p + 1,
|
||||||
|
(char*)a_thread->event->file + a_thread->event->file_len - p - 1);
|
||||||
|
} else {
|
||||||
|
if (!a_thread->event->file) {
|
||||||
|
return zlog_buf_append(a_buf, "(file=null)", sizeof("(file=null)") - 1);
|
||||||
|
} else {
|
||||||
|
return zlog_buf_append(a_buf, a_thread->event->file, a_thread->event->file_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zlog_spec_write_srcline(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
|
||||||
|
{
|
||||||
|
|
||||||
|
return zlog_buf_printf_dec64(a_buf, a_thread->event->line, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zlog_spec_write_srcfunc(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
|
||||||
|
{
|
||||||
|
if (!a_thread->event->file) {
|
||||||
|
return zlog_buf_append(a_buf, "(func=null)", sizeof("(func=null)") - 1);
|
||||||
|
} else {
|
||||||
|
return zlog_buf_append(a_buf, a_thread->event->func, a_thread->event->func_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int zlog_spec_write_hostname(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
|
||||||
|
{
|
||||||
|
return zlog_buf_append(a_buf, a_thread->event->host_name, a_thread->event->host_name_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zlog_spec_write_newline(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
|
||||||
|
{
|
||||||
|
return zlog_buf_append(a_buf, FILE_NEWLINE, FILE_NEWLINE_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zlog_spec_write_cr(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
|
||||||
|
{
|
||||||
|
return zlog_buf_append(a_buf, "\r", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zlog_spec_write_percent(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
|
||||||
|
{
|
||||||
|
return zlog_buf_append(a_buf, "%", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zlog_spec_write_pid(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
|
||||||
|
{
|
||||||
|
/* 1st in event lifecycle */
|
||||||
|
if (!a_thread->event->pid) {
|
||||||
|
a_thread->event->pid = getpid();
|
||||||
|
|
||||||
|
/* compare with previous event */
|
||||||
|
if (a_thread->event->pid != a_thread->event->last_pid) {
|
||||||
|
a_thread->event->last_pid = a_thread->event->pid;
|
||||||
|
a_thread->event->pid_str_len
|
||||||
|
= sprintf(a_thread->event->pid_str, "%u", a_thread->event->pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return zlog_buf_append(a_buf, a_thread->event->pid_str, a_thread->event->pid_str_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zlog_spec_write_tid_hex(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* don't need to get tid again, as tmap_new_thread fetched it already */
|
||||||
|
/* and fork not change tid */
|
||||||
|
return zlog_buf_append(a_buf, a_thread->event->tid_hex_str, a_thread->event->tid_hex_str_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zlog_spec_write_tid_long(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* don't need to get tid again, as tmap_new_thread fetched it already */
|
||||||
|
/* and fork not change tid */
|
||||||
|
return zlog_buf_append(a_buf, a_thread->event->tid_str, a_thread->event->tid_str_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zlog_spec_write_ktid(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* don't need to get ktid again, as tmap_new_thread fetched it already */
|
||||||
|
/* and fork not change tid */
|
||||||
|
return zlog_buf_append(a_buf, a_thread->event->ktid_str, a_thread->event->ktid_str_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zlog_spec_write_level_lowercase(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
|
||||||
|
{
|
||||||
|
zlog_level_t *a_level;
|
||||||
|
|
||||||
|
a_level = zlog_level_list_get(zlog_env_conf->levels, a_thread->event->level);
|
||||||
|
return zlog_buf_append(a_buf, a_level->str_lowercase, a_level->str_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zlog_spec_write_level_uppercase(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
|
||||||
|
{
|
||||||
|
zlog_level_t *a_level;
|
||||||
|
|
||||||
|
a_level = zlog_level_list_get(zlog_env_conf->levels, a_thread->event->level);
|
||||||
|
return zlog_buf_append(a_buf, a_level->str_uppercase, a_level->str_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zlog_spec_write_usrmsg(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
|
||||||
|
{
|
||||||
|
if (a_thread->event->generate_cmd == ZLOG_FMT) {
|
||||||
|
if (a_thread->event->str_format) {
|
||||||
|
return zlog_buf_vprintf(a_buf,
|
||||||
|
a_thread->event->str_format,
|
||||||
|
a_thread->event->str_args);
|
||||||
|
} else {
|
||||||
|
return zlog_buf_append(a_buf, "format=(null)", sizeof("format=(null)")-1);
|
||||||
|
}
|
||||||
|
} else if (a_thread->event->generate_cmd == ZLOG_HEX) {
|
||||||
|
int rc;
|
||||||
|
long line_offset;
|
||||||
|
long byte_offset;
|
||||||
|
|
||||||
|
/* thread buf start == null or len <= 0 */
|
||||||
|
if (a_thread->event->hex_buf == NULL) {
|
||||||
|
rc = zlog_buf_append(a_buf, "buf=(null)", sizeof("buf=(null)")-1);
|
||||||
|
goto zlog_hex_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = zlog_buf_append(a_buf, ZLOG_HEX_HEAD, sizeof(ZLOG_HEX_HEAD)-1);
|
||||||
|
if (rc) {
|
||||||
|
goto zlog_hex_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
line_offset = 0;
|
||||||
|
//byte_offset = 0;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
unsigned char c;
|
||||||
|
|
||||||
|
rc = zlog_buf_append(a_buf, "\n", 1);
|
||||||
|
if (rc) goto zlog_hex_exit;
|
||||||
|
|
||||||
|
rc = zlog_buf_printf_dec64(a_buf, line_offset + 1, 10);
|
||||||
|
if (rc) goto zlog_hex_exit;
|
||||||
|
rc = zlog_buf_append(a_buf, " ", 3);
|
||||||
|
if (rc) goto zlog_hex_exit;
|
||||||
|
|
||||||
|
for (byte_offset = 0; byte_offset < 16; byte_offset++) {
|
||||||
|
if (line_offset * 16 + byte_offset < a_thread->event->hex_buf_len) {
|
||||||
|
c = *((unsigned char *)a_thread->event->hex_buf
|
||||||
|
+ line_offset * 16 + byte_offset);
|
||||||
|
rc = zlog_buf_printf_hex(a_buf, c, 2);
|
||||||
|
if (rc) goto zlog_hex_exit;
|
||||||
|
rc = zlog_buf_append(a_buf, " ", 1);
|
||||||
|
if (rc) goto zlog_hex_exit;
|
||||||
|
} else {
|
||||||
|
rc = zlog_buf_append(a_buf, " ", 3);
|
||||||
|
if (rc) goto zlog_hex_exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = zlog_buf_append(a_buf, " ", 2);
|
||||||
|
if (rc) goto zlog_hex_exit;
|
||||||
|
|
||||||
|
for (byte_offset = 0; byte_offset < 16; byte_offset++) {
|
||||||
|
if (line_offset * 16 + byte_offset < a_thread->event->hex_buf_len) {
|
||||||
|
c = *((unsigned char *)a_thread->event->hex_buf
|
||||||
|
+ line_offset * 16 + byte_offset);
|
||||||
|
if (c >= 32 && c <= 126) {
|
||||||
|
rc = zlog_buf_append(a_buf,(char*)&c, 1);
|
||||||
|
if (rc) goto zlog_hex_exit;
|
||||||
|
} else {
|
||||||
|
rc = zlog_buf_append(a_buf, ".", 1);
|
||||||
|
if (rc) goto zlog_hex_exit;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rc = zlog_buf_append(a_buf, " ", 1);
|
||||||
|
if (rc) goto zlog_hex_exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line_offset * 16 + byte_offset >= a_thread->event->hex_buf_len) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
line_offset++;
|
||||||
|
}
|
||||||
|
|
||||||
|
zlog_hex_exit:
|
||||||
|
if (rc < 0) {
|
||||||
|
zc_error("write hex msg fail");
|
||||||
|
return -1;
|
||||||
|
} else if (rc > 0) {
|
||||||
|
zc_error("write hex msg, buf is full");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/* implementation of gen function */
|
||||||
|
|
||||||
|
static int zlog_spec_gen_msg_direct(zlog_spec_t * a_spec, zlog_thread_t * a_thread)
|
||||||
|
{
|
||||||
|
/* no need to reprint %1.2d here */
|
||||||
|
return a_spec->write_buf(a_spec, a_thread, a_thread->msg_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zlog_spec_gen_msg_reformat(zlog_spec_t * a_spec, zlog_thread_t * a_thread)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
zlog_buf_restart(a_thread->pre_msg_buf);
|
||||||
|
|
||||||
|
rc = a_spec->write_buf(a_spec, a_thread, a_thread->pre_msg_buf);
|
||||||
|
if (rc < 0) {
|
||||||
|
zc_error("a_spec->gen_buf fail");
|
||||||
|
return -1;
|
||||||
|
} else if (rc > 0) {
|
||||||
|
/* buf is full, try printf */
|
||||||
|
}
|
||||||
|
|
||||||
|
return zlog_buf_adjust_append(a_thread->msg_buf,
|
||||||
|
zlog_buf_str(a_thread->pre_msg_buf), zlog_buf_len(a_thread->pre_msg_buf),
|
||||||
|
a_spec->left_adjust, a_spec->left_fill_zeros, a_spec->min_width, a_spec->max_width);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
static int zlog_spec_gen_path_direct(zlog_spec_t * a_spec, zlog_thread_t * a_thread)
|
||||||
|
{
|
||||||
|
/* no need to reprint %1.2d here */
|
||||||
|
return a_spec->write_buf(a_spec, a_thread, a_thread->path_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zlog_spec_gen_path_reformat(zlog_spec_t * a_spec, zlog_thread_t * a_thread)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
zlog_buf_restart(a_thread->pre_path_buf);
|
||||||
|
|
||||||
|
rc = a_spec->write_buf(a_spec, a_thread, a_thread->pre_path_buf);
|
||||||
|
if (rc < 0) {
|
||||||
|
zc_error("a_spec->gen_buf fail");
|
||||||
|
return -1;
|
||||||
|
} else if (rc > 0) {
|
||||||
|
/* buf is full, try printf */
|
||||||
|
}
|
||||||
|
|
||||||
|
return zlog_buf_adjust_append(a_thread->path_buf,
|
||||||
|
zlog_buf_str(a_thread->pre_path_buf), zlog_buf_len(a_thread->pre_path_buf),
|
||||||
|
a_spec->left_adjust, a_spec->left_fill_zeros, a_spec->min_width, a_spec->max_width);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
static int zlog_spec_gen_archive_path_direct(zlog_spec_t * a_spec, zlog_thread_t * a_thread)
|
||||||
|
{
|
||||||
|
/* no need to reprint %1.2d here */
|
||||||
|
return a_spec->write_buf(a_spec, a_thread, a_thread->archive_path_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zlog_spec_gen_archive_path_reformat(zlog_spec_t * a_spec, zlog_thread_t * a_thread)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
zlog_buf_restart(a_thread->pre_path_buf);
|
||||||
|
|
||||||
|
rc = a_spec->write_buf(a_spec, a_thread, a_thread->pre_path_buf);
|
||||||
|
if (rc < 0) {
|
||||||
|
zc_error("a_spec->gen_buf fail");
|
||||||
|
return -1;
|
||||||
|
} else if (rc > 0) {
|
||||||
|
/* buf is full, try printf */
|
||||||
|
}
|
||||||
|
|
||||||
|
return zlog_buf_adjust_append(a_thread->archive_path_buf,
|
||||||
|
zlog_buf_str(a_thread->pre_path_buf), zlog_buf_len(a_thread->pre_path_buf),
|
||||||
|
a_spec->left_adjust, a_spec->left_fill_zeros, a_spec->min_width, a_spec->max_width);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
static int zlog_spec_parse_print_fmt(zlog_spec_t * a_spec)
|
||||||
|
{
|
||||||
|
/* -12.35 12 .35 */
|
||||||
|
char *p, *q;
|
||||||
|
long i, j;
|
||||||
|
|
||||||
|
p = a_spec->print_fmt;
|
||||||
|
if (*p == '-') {
|
||||||
|
a_spec->left_adjust = 1;
|
||||||
|
p++;
|
||||||
|
} else {
|
||||||
|
if (*p == '0') {
|
||||||
|
a_spec->left_fill_zeros = 1;
|
||||||
|
}
|
||||||
|
a_spec->left_adjust = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = j = 0;
|
||||||
|
sscanf(p, "%ld.", &i);
|
||||||
|
q = strchr(p, '.');
|
||||||
|
if (q) sscanf(q, ".%ld", &j);
|
||||||
|
|
||||||
|
a_spec->min_width = (size_t) i;
|
||||||
|
a_spec->max_width = (size_t) j;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
void zlog_spec_del(zlog_spec_t * a_spec)
|
||||||
|
{
|
||||||
|
zc_assert(a_spec,);
|
||||||
|
zc_debug("zlog_spec_del[%p]", a_spec);
|
||||||
|
free(a_spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* a spec may consist of
|
||||||
|
* a const string: /home/bb
|
||||||
|
* a string begin with %: %12.35d(%F %X,%l)
|
||||||
|
*/
|
||||||
|
zlog_spec_t *zlog_spec_new(char *pattern_start, char **pattern_next, int *time_cache_count)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
int nscan = 0;
|
||||||
|
int nread = 0;
|
||||||
|
zlog_spec_t *a_spec;
|
||||||
|
|
||||||
|
zc_assert(pattern_start, NULL);
|
||||||
|
zc_assert(pattern_next, NULL);
|
||||||
|
|
||||||
|
a_spec = calloc(1, sizeof(zlog_spec_t));
|
||||||
|
if (!a_spec) {
|
||||||
|
zc_error("calloc fail, errno[%d]", errno);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_spec->str = p = pattern_start;
|
||||||
|
|
||||||
|
switch (*p) {
|
||||||
|
case '%':
|
||||||
|
/* a string begin with %: %12.35d(%F %X) */
|
||||||
|
|
||||||
|
/* process width and precision char in %-12.35P */
|
||||||
|
nread = 0;
|
||||||
|
nscan = sscanf(p, "%%%[.0-9-]%n", a_spec->print_fmt, &nread);
|
||||||
|
if (nscan == 1) {
|
||||||
|
a_spec->gen_msg = zlog_spec_gen_msg_reformat;
|
||||||
|
a_spec->gen_path = zlog_spec_gen_path_reformat;
|
||||||
|
a_spec->gen_archive_path = zlog_spec_gen_archive_path_reformat;
|
||||||
|
if (zlog_spec_parse_print_fmt(a_spec)) {
|
||||||
|
zc_error("zlog_spec_parse_print_fmt fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
nread = 1; /* skip the % char */
|
||||||
|
a_spec->gen_msg = zlog_spec_gen_msg_direct;
|
||||||
|
a_spec->gen_path = zlog_spec_gen_path_direct;
|
||||||
|
a_spec->gen_archive_path = zlog_spec_gen_archive_path_direct;
|
||||||
|
}
|
||||||
|
|
||||||
|
p += nread;
|
||||||
|
|
||||||
|
if (*p == 'd') {
|
||||||
|
if (*(p+1) != '(') {
|
||||||
|
/* without '(' , use default */
|
||||||
|
strcpy(a_spec->time_fmt, ZLOG_DEFAULT_TIME_FMT);
|
||||||
|
p++;
|
||||||
|
} else if (STRNCMP(p, ==, "d()", 3)) {
|
||||||
|
/* with () but without detail time format,
|
||||||
|
* keep a_spec->time_fmt=="" */
|
||||||
|
strcpy(a_spec->time_fmt, ZLOG_DEFAULT_TIME_FMT);
|
||||||
|
p += 3;
|
||||||
|
} else {
|
||||||
|
nread = 0;
|
||||||
|
nscan = sscanf(p, "d(%[^)])%n", a_spec->time_fmt, &nread);
|
||||||
|
if (nscan != 1) {
|
||||||
|
nread = 0;
|
||||||
|
}
|
||||||
|
p += nread;
|
||||||
|
if (*(p - 1) != ')') {
|
||||||
|
zc_error("in string[%s] can't find match \')\'", a_spec->str);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a_spec->time_cache_index = *time_cache_count;
|
||||||
|
(*time_cache_count)++;
|
||||||
|
a_spec->write_buf = zlog_spec_write_time;
|
||||||
|
|
||||||
|
*pattern_next = p;
|
||||||
|
a_spec->len = p - a_spec->str;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*p == 'M') {
|
||||||
|
nread = 0;
|
||||||
|
nscan = sscanf(p, "M(%[^)])%n", a_spec->mdc_key, &nread);
|
||||||
|
if (nscan != 1) {
|
||||||
|
nread = 0;
|
||||||
|
if (STRNCMP(p, ==, "M()", 3)) {
|
||||||
|
nread = 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p += nread;
|
||||||
|
if (*(p - 1) != ')') {
|
||||||
|
zc_error("in string[%s] can't find match \')\'", a_spec->str);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pattern_next = p;
|
||||||
|
a_spec->len = p - a_spec->str;
|
||||||
|
a_spec->write_buf = zlog_spec_write_mdc;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (STRNCMP(p, ==, "ms", 2)) {
|
||||||
|
p += 2;
|
||||||
|
*pattern_next = p;
|
||||||
|
a_spec->len = p - a_spec->str;
|
||||||
|
a_spec->write_buf = zlog_spec_write_ms;
|
||||||
|
break;
|
||||||
|
} else if (STRNCMP(p, ==, "us", 2)) {
|
||||||
|
p += 2;
|
||||||
|
*pattern_next = p;
|
||||||
|
a_spec->len = p - a_spec->str;
|
||||||
|
a_spec->write_buf = zlog_spec_write_us;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pattern_next = p + 1;
|
||||||
|
a_spec->len = p - a_spec->str + 1;
|
||||||
|
|
||||||
|
switch (*p) {
|
||||||
|
case 'c':
|
||||||
|
a_spec->write_buf = zlog_spec_write_category;
|
||||||
|
break;
|
||||||
|
case 'D':
|
||||||
|
strcpy(a_spec->time_fmt, ZLOG_DEFAULT_TIME_FMT);
|
||||||
|
a_spec->time_cache_index = *time_cache_count;
|
||||||
|
(*time_cache_count)++;
|
||||||
|
a_spec->write_buf = zlog_spec_write_time;
|
||||||
|
break;
|
||||||
|
case 'F':
|
||||||
|
a_spec->write_buf = zlog_spec_write_srcfile;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
a_spec->write_buf = zlog_spec_write_srcfile_neat;
|
||||||
|
break;
|
||||||
|
case 'H':
|
||||||
|
a_spec->write_buf = zlog_spec_write_hostname;
|
||||||
|
break;
|
||||||
|
case 'k':
|
||||||
|
a_spec->write_buf = zlog_spec_write_ktid;
|
||||||
|
break;
|
||||||
|
case 'L':
|
||||||
|
a_spec->write_buf = zlog_spec_write_srcline;
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
a_spec->write_buf = zlog_spec_write_usrmsg;
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
a_spec->write_buf = zlog_spec_write_newline;
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
a_spec->write_buf = zlog_spec_write_cr;
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
a_spec->write_buf = zlog_spec_write_pid;
|
||||||
|
break;
|
||||||
|
case 'U':
|
||||||
|
a_spec->write_buf = zlog_spec_write_srcfunc;
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
a_spec->write_buf = zlog_spec_write_level_lowercase;
|
||||||
|
break;
|
||||||
|
case 'V':
|
||||||
|
a_spec->write_buf = zlog_spec_write_level_uppercase;
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
a_spec->write_buf = zlog_spec_write_tid_hex;
|
||||||
|
break;
|
||||||
|
case 'T':
|
||||||
|
a_spec->write_buf = zlog_spec_write_tid_long;
|
||||||
|
break;
|
||||||
|
case '%':
|
||||||
|
a_spec->write_buf = zlog_spec_write_percent;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
zc_error("str[%s] in wrong format, p[%c]", a_spec->str, *p);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* a const string: /home/bb */
|
||||||
|
*pattern_next = strchr(p, '%');
|
||||||
|
if (*pattern_next) {
|
||||||
|
a_spec->len = *pattern_next - p;
|
||||||
|
} else {
|
||||||
|
a_spec->len = strlen(p);
|
||||||
|
*pattern_next = p + a_spec->len;
|
||||||
|
}
|
||||||
|
a_spec->write_buf = zlog_spec_write_str;
|
||||||
|
a_spec->gen_msg = zlog_spec_gen_msg_direct;
|
||||||
|
a_spec->gen_path = zlog_spec_gen_path_direct;
|
||||||
|
a_spec->gen_archive_path = zlog_spec_gen_archive_path_direct;
|
||||||
|
}
|
||||||
|
|
||||||
|
zlog_spec_profile(a_spec, ZC_DEBUG);
|
||||||
|
return a_spec;
|
||||||
|
err:
|
||||||
|
zlog_spec_del(a_spec);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __zlog_spec_h
|
||||||
|
#define __zlog_spec_h
|
||||||
|
|
||||||
|
#include "event.h"
|
||||||
|
#include "buf.h"
|
||||||
|
#include "thread.h"
|
||||||
|
|
||||||
|
typedef struct zlog_spec_s zlog_spec_t;
|
||||||
|
|
||||||
|
/* write buf, according to each spec's Conversion Characters */
|
||||||
|
typedef int (*zlog_spec_write_fn) (zlog_spec_t * a_spec,
|
||||||
|
zlog_thread_t * a_thread,
|
||||||
|
zlog_buf_t * a_buf);
|
||||||
|
|
||||||
|
/* gen a_thread->msg or gen a_thread->path by using write_fn */
|
||||||
|
typedef int (*zlog_spec_gen_fn) (zlog_spec_t * a_spec,
|
||||||
|
zlog_thread_t * a_thread);
|
||||||
|
|
||||||
|
struct zlog_spec_s {
|
||||||
|
char *str;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
char time_fmt[MAXLEN_CFG_LINE + 1];
|
||||||
|
int time_cache_index;
|
||||||
|
char mdc_key[MAXLEN_PATH + 1];
|
||||||
|
|
||||||
|
char print_fmt[MAXLEN_CFG_LINE + 1];
|
||||||
|
int left_adjust;
|
||||||
|
int left_fill_zeros;
|
||||||
|
size_t max_width;
|
||||||
|
size_t min_width;
|
||||||
|
|
||||||
|
zlog_spec_write_fn write_buf;
|
||||||
|
zlog_spec_gen_fn gen_msg;
|
||||||
|
zlog_spec_gen_fn gen_path;
|
||||||
|
zlog_spec_gen_fn gen_archive_path;
|
||||||
|
};
|
||||||
|
|
||||||
|
zlog_spec_t *zlog_spec_new(char *pattern_start, char **pattern_end, int * time_cache_count);
|
||||||
|
void zlog_spec_del(zlog_spec_t * a_spec);
|
||||||
|
void zlog_spec_profile(zlog_spec_t * a_spec, int flag);
|
||||||
|
|
||||||
|
#define zlog_spec_gen_msg(a_spec, a_thread) \
|
||||||
|
a_spec->gen_msg(a_spec, a_thread)
|
||||||
|
|
||||||
|
#define zlog_spec_gen_path(a_spec, a_thread) \
|
||||||
|
a_spec->gen_path(a_spec, a_thread)
|
||||||
|
|
||||||
|
#define zlog_spec_gen_archive_path(a_spec, a_thread) \
|
||||||
|
a_spec->gen_archive_path(a_spec, a_thread)
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,184 @@
|
|||||||
|
/*
|
||||||
|
* 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 <pthread.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "zc_defs.h"
|
||||||
|
#include "event.h"
|
||||||
|
#include "buf.h"
|
||||||
|
#include "thread.h"
|
||||||
|
#include "mdc.h"
|
||||||
|
|
||||||
|
void zlog_thread_profile(zlog_thread_t * a_thread, int flag)
|
||||||
|
{
|
||||||
|
zc_assert(a_thread,);
|
||||||
|
zc_profile(flag, "--thread[%p][%p][%p][%p,%p,%p,%p,%p]--",
|
||||||
|
a_thread,
|
||||||
|
a_thread->mdc,
|
||||||
|
a_thread->event,
|
||||||
|
a_thread->pre_path_buf,
|
||||||
|
a_thread->path_buf,
|
||||||
|
a_thread->archive_path_buf,
|
||||||
|
a_thread->pre_msg_buf,
|
||||||
|
a_thread->msg_buf);
|
||||||
|
|
||||||
|
zlog_mdc_profile(a_thread->mdc, flag);
|
||||||
|
zlog_event_profile(a_thread->event, flag);
|
||||||
|
zlog_buf_profile(a_thread->pre_path_buf, flag);
|
||||||
|
zlog_buf_profile(a_thread->path_buf, flag);
|
||||||
|
zlog_buf_profile(a_thread->archive_path_buf, flag);
|
||||||
|
zlog_buf_profile(a_thread->pre_msg_buf, flag);
|
||||||
|
zlog_buf_profile(a_thread->msg_buf, flag);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*******************************************************************************/
|
||||||
|
void zlog_thread_del(zlog_thread_t * a_thread)
|
||||||
|
{
|
||||||
|
zc_assert(a_thread,);
|
||||||
|
if (a_thread->mdc)
|
||||||
|
zlog_mdc_del(a_thread->mdc);
|
||||||
|
if (a_thread->event)
|
||||||
|
zlog_event_del(a_thread->event);
|
||||||
|
if (a_thread->pre_path_buf)
|
||||||
|
zlog_buf_del(a_thread->pre_path_buf);
|
||||||
|
if (a_thread->path_buf)
|
||||||
|
zlog_buf_del(a_thread->path_buf);
|
||||||
|
if (a_thread->archive_path_buf)
|
||||||
|
zlog_buf_del(a_thread->archive_path_buf);
|
||||||
|
if (a_thread->pre_msg_buf)
|
||||||
|
zlog_buf_del(a_thread->pre_msg_buf);
|
||||||
|
if (a_thread->msg_buf)
|
||||||
|
zlog_buf_del(a_thread->msg_buf);
|
||||||
|
|
||||||
|
zc_debug("zlog_thread_del[%p]", a_thread);
|
||||||
|
free(a_thread);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
zlog_thread_t *zlog_thread_new(int init_version, size_t buf_size_min, size_t buf_size_max, int time_cache_count)
|
||||||
|
{
|
||||||
|
zlog_thread_t *a_thread;
|
||||||
|
|
||||||
|
a_thread = calloc(1, sizeof(zlog_thread_t));
|
||||||
|
if (!a_thread) {
|
||||||
|
zc_error("calloc fail, errno[%d]", errno);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_thread->init_version = init_version;
|
||||||
|
|
||||||
|
a_thread->mdc = zlog_mdc_new();
|
||||||
|
if (!a_thread->mdc) {
|
||||||
|
zc_error("zlog_mdc_new fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_thread->event = zlog_event_new(time_cache_count);
|
||||||
|
if (!a_thread->event) {
|
||||||
|
zc_error("zlog_event_new fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_thread->pre_path_buf = zlog_buf_new(MAXLEN_PATH + 1, MAXLEN_PATH + 1, NULL);
|
||||||
|
if (!a_thread->pre_path_buf) {
|
||||||
|
zc_error("zlog_buf_new fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_thread->path_buf = zlog_buf_new(MAXLEN_PATH + 1, MAXLEN_PATH + 1, NULL);
|
||||||
|
if (!a_thread->path_buf) {
|
||||||
|
zc_error("zlog_buf_new fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_thread->archive_path_buf = zlog_buf_new(MAXLEN_PATH + 1, MAXLEN_PATH + 1, NULL);
|
||||||
|
if (!a_thread->archive_path_buf) {
|
||||||
|
zc_error("zlog_buf_new fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_thread->pre_msg_buf = zlog_buf_new(buf_size_min, buf_size_max, "..." FILE_NEWLINE);
|
||||||
|
if (!a_thread->pre_msg_buf) {
|
||||||
|
zc_error("zlog_buf_new fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_thread->msg_buf = zlog_buf_new(buf_size_min, buf_size_max, "..." FILE_NEWLINE);
|
||||||
|
if (!a_thread->msg_buf) {
|
||||||
|
zc_error("zlog_buf_new fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//zlog_thread_profile(a_thread, ZC_DEBUG);
|
||||||
|
return a_thread;
|
||||||
|
err:
|
||||||
|
zlog_thread_del(a_thread);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
int zlog_thread_rebuild_msg_buf(zlog_thread_t * a_thread, size_t buf_size_min, size_t buf_size_max)
|
||||||
|
{
|
||||||
|
zlog_buf_t *pre_msg_buf_new = NULL;
|
||||||
|
zlog_buf_t *msg_buf_new = NULL;
|
||||||
|
zc_assert(a_thread, -1);
|
||||||
|
|
||||||
|
if ( (a_thread->msg_buf->size_min == buf_size_min)
|
||||||
|
&& (a_thread->msg_buf->size_max == buf_size_max)) {
|
||||||
|
zc_debug("buf size not changed, no need rebuild");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre_msg_buf_new = zlog_buf_new(buf_size_min, buf_size_max, "..." FILE_NEWLINE);
|
||||||
|
if (!pre_msg_buf_new) {
|
||||||
|
zc_error("zlog_buf_new fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg_buf_new = zlog_buf_new(buf_size_min, buf_size_max, "..." FILE_NEWLINE);
|
||||||
|
if (!msg_buf_new) {
|
||||||
|
zc_error("zlog_buf_new fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
zlog_buf_del(a_thread->pre_msg_buf);
|
||||||
|
a_thread->pre_msg_buf = pre_msg_buf_new;
|
||||||
|
|
||||||
|
zlog_buf_del(a_thread->msg_buf);
|
||||||
|
a_thread->msg_buf = msg_buf_new;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
err:
|
||||||
|
if (pre_msg_buf_new) zlog_buf_del(pre_msg_buf_new);
|
||||||
|
if (msg_buf_new) zlog_buf_del(msg_buf_new);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int zlog_thread_rebuild_event(zlog_thread_t * a_thread, int time_cache_count)
|
||||||
|
{
|
||||||
|
zlog_event_t *event_new = NULL;
|
||||||
|
zc_assert(a_thread, -1);
|
||||||
|
|
||||||
|
event_new = zlog_event_new(time_cache_count);
|
||||||
|
if (!event_new) {
|
||||||
|
zc_error("zlog_event_new fail");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
zlog_event_del(a_thread->event);
|
||||||
|
a_thread->event = event_new;
|
||||||
|
return 0;
|
||||||
|
err:
|
||||||
|
if (event_new) zlog_event_del(event_new);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __zlog_thread_h
|
||||||
|
#define __zlog_thread_h
|
||||||
|
|
||||||
|
#include "zc_defs.h"
|
||||||
|
#include "event.h"
|
||||||
|
#include "buf.h"
|
||||||
|
#include "mdc.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int init_version;
|
||||||
|
zlog_mdc_t *mdc;
|
||||||
|
zlog_event_t *event;
|
||||||
|
|
||||||
|
zlog_buf_t *pre_path_buf;
|
||||||
|
zlog_buf_t *path_buf;
|
||||||
|
zlog_buf_t *archive_path_buf;
|
||||||
|
zlog_buf_t *pre_msg_buf;
|
||||||
|
zlog_buf_t *msg_buf;
|
||||||
|
} zlog_thread_t;
|
||||||
|
|
||||||
|
|
||||||
|
void zlog_thread_del(zlog_thread_t * a_thread);
|
||||||
|
void zlog_thread_profile(zlog_thread_t * a_thread, int flag);
|
||||||
|
zlog_thread_t *zlog_thread_new(int init_version,
|
||||||
|
size_t buf_size_min, size_t buf_size_max, int time_cache_count);
|
||||||
|
|
||||||
|
int zlog_thread_rebuild_msg_buf(zlog_thread_t * a_thread, size_t buf_size_min, size_t buf_size_max);
|
||||||
|
int zlog_thread_rebuild_event(zlog_thread_t * a_thread, int time_cache_count);
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1 @@
|
|||||||
|
#define ZLOG_VERSION "1.2.12"
|
||||||
@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
* 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 <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "zc_defs.h"
|
||||||
|
|
||||||
|
zc_arraylist_t *zc_arraylist_new(zc_arraylist_del_fn del)
|
||||||
|
{
|
||||||
|
zc_arraylist_t *a_list;
|
||||||
|
|
||||||
|
a_list = (zc_arraylist_t *) calloc(1, sizeof(zc_arraylist_t));
|
||||||
|
if (!a_list) {
|
||||||
|
zc_error("calloc fail, errno[%d]", errno);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
a_list->size = ARRAY_LIST_DEFAULT_SIZE;
|
||||||
|
a_list->len = 0;
|
||||||
|
|
||||||
|
/* this could be NULL */
|
||||||
|
a_list->del = del;
|
||||||
|
a_list->array = (void **)calloc(a_list->size, sizeof(void *));
|
||||||
|
if (!a_list->array) {
|
||||||
|
zc_error("calloc fail, errno[%d]", errno);
|
||||||
|
free(a_list);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return a_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void zc_arraylist_del(zc_arraylist_t * a_list)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!a_list)
|
||||||
|
return;
|
||||||
|
if (a_list->del) {
|
||||||
|
for (i = 0; i < a_list->len; i++) {
|
||||||
|
if (a_list->array[i])
|
||||||
|
a_list->del(a_list->array[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (a_list->array)
|
||||||
|
free(a_list->array);
|
||||||
|
free(a_list);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zc_arraylist_expand_inner(zc_arraylist_t * a_list, int max)
|
||||||
|
{
|
||||||
|
void *tmp;
|
||||||
|
int new_size;
|
||||||
|
int diff_size;
|
||||||
|
|
||||||
|
new_size = zc_max(a_list->size * 2, max);
|
||||||
|
tmp = realloc(a_list->array, new_size * sizeof(void *));
|
||||||
|
if (!tmp) {
|
||||||
|
zc_error("realloc fail, errno[%d]", errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
a_list->array = (void **)tmp;
|
||||||
|
diff_size = new_size - a_list->size;
|
||||||
|
if (diff_size) memset(a_list->array + a_list->size, 0x00, diff_size * sizeof(void *));
|
||||||
|
a_list->size = new_size;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int zc_arraylist_set(zc_arraylist_t * a_list, int idx, void *data)
|
||||||
|
{
|
||||||
|
if (idx > a_list->size - 1) {
|
||||||
|
if (zc_arraylist_expand_inner(a_list, idx)) {
|
||||||
|
zc_error("expand_internal fail");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (a_list->array[idx] && a_list->del) a_list->del(a_list->array[idx]);
|
||||||
|
a_list->array[idx] = data;
|
||||||
|
if (a_list->len <= idx)
|
||||||
|
a_list->len = idx + 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int zc_arraylist_add(zc_arraylist_t * a_list, void *data)
|
||||||
|
{
|
||||||
|
return zc_arraylist_set(a_list, a_list->len, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* assum idx < len */
|
||||||
|
static int zc_arraylist_insert_inner(zc_arraylist_t * a_list, int idx,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
if (a_list->array[idx] == NULL) {
|
||||||
|
a_list->array[idx] = data;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (a_list->len > a_list->size - 1) {
|
||||||
|
if (zc_arraylist_expand_inner(a_list, 0)) {
|
||||||
|
zc_error("expand_internal fail");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
memmove(a_list->array + idx + 1, a_list->array + idx,
|
||||||
|
(a_list->len - idx) * sizeof(void *));
|
||||||
|
a_list->array[idx] = data;
|
||||||
|
a_list->len++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int zc_arraylist_sortadd(zc_arraylist_t * a_list, zc_arraylist_cmp_fn cmp,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < a_list->len; i++) {
|
||||||
|
if ((*cmp) (a_list->array[i], data) > 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == a_list->len)
|
||||||
|
return zc_arraylist_add(a_list, data);
|
||||||
|
else
|
||||||
|
return zc_arraylist_insert_inner(a_list, i, data);
|
||||||
|
}
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __zc_arraylist_h
|
||||||
|
#define __zc_arraylist_h
|
||||||
|
|
||||||
|
#define ARRAY_LIST_DEFAULT_SIZE 32
|
||||||
|
|
||||||
|
typedef void (*zc_arraylist_del_fn) (void *data);
|
||||||
|
typedef int (*zc_arraylist_cmp_fn) (void *data1, void *data2);
|
||||||
|
|
||||||
|
/* make zc_arraylist_foreach speed up, so keep struct defination here */
|
||||||
|
typedef struct {
|
||||||
|
void **array;
|
||||||
|
int len;
|
||||||
|
int size;
|
||||||
|
zc_arraylist_del_fn del;
|
||||||
|
} zc_arraylist_t;
|
||||||
|
|
||||||
|
zc_arraylist_t *zc_arraylist_new(zc_arraylist_del_fn del);
|
||||||
|
void zc_arraylist_del(zc_arraylist_t * a_list);
|
||||||
|
|
||||||
|
int zc_arraylist_set(zc_arraylist_t * a_list, int i, void *data);
|
||||||
|
int zc_arraylist_add(zc_arraylist_t * a_list, void *data);
|
||||||
|
int zc_arraylist_sortadd(zc_arraylist_t * a_list, zc_arraylist_cmp_fn cmp,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
#define zc_arraylist_len(a_list) (a_list->len)
|
||||||
|
|
||||||
|
#define zc_arraylist_get(a_list, i) \
|
||||||
|
((i >= a_list->len) ? NULL : a_list->array[i])
|
||||||
|
|
||||||
|
#define zc_arraylist_foreach(a_list, i, a_unit) \
|
||||||
|
for(i = 0, a_unit = a_list->array[0]; (i < a_list->len) && (a_unit = a_list->array[i], 1) ; i++)
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __zc_defs_h
|
||||||
|
#define __zc_defs_h
|
||||||
|
|
||||||
|
#include "zc_profile.h"
|
||||||
|
#include "zc_arraylist.h"
|
||||||
|
#include "zc_hashtable.h"
|
||||||
|
#include "zc_xplatform.h"
|
||||||
|
#include "zc_util.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,330 @@
|
|||||||
|
/*
|
||||||
|
* 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 <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include "zc_defs.h"
|
||||||
|
#include "zc_hashtable.h"
|
||||||
|
|
||||||
|
struct zc_hashtable_s {
|
||||||
|
size_t nelem;
|
||||||
|
|
||||||
|
zc_hashtable_entry_t **tab;
|
||||||
|
size_t tab_size;
|
||||||
|
|
||||||
|
zc_hashtable_hash_fn hash;
|
||||||
|
zc_hashtable_equal_fn equal;
|
||||||
|
zc_hashtable_del_fn key_del;
|
||||||
|
zc_hashtable_del_fn value_del;
|
||||||
|
};
|
||||||
|
|
||||||
|
zc_hashtable_t *zc_hashtable_new(size_t a_size,
|
||||||
|
zc_hashtable_hash_fn hash,
|
||||||
|
zc_hashtable_equal_fn equal,
|
||||||
|
zc_hashtable_del_fn key_del,
|
||||||
|
zc_hashtable_del_fn value_del)
|
||||||
|
{
|
||||||
|
zc_hashtable_t *a_table;
|
||||||
|
|
||||||
|
a_table = calloc(1, sizeof(*a_table));
|
||||||
|
if (!a_table) {
|
||||||
|
zc_error("calloc fail, errno[%d]", errno);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_table->tab = calloc(a_size, sizeof(*(a_table->tab)));
|
||||||
|
if (!a_table->tab) {
|
||||||
|
zc_error("calloc fail, errno[%d]", errno);
|
||||||
|
free(a_table);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
a_table->tab_size = a_size;
|
||||||
|
|
||||||
|
a_table->nelem = 0;
|
||||||
|
a_table->hash = hash;
|
||||||
|
a_table->equal = equal;
|
||||||
|
|
||||||
|
/* these two could be NULL */
|
||||||
|
a_table->key_del = key_del;
|
||||||
|
a_table->value_del = value_del;
|
||||||
|
|
||||||
|
return a_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
void zc_hashtable_del(zc_hashtable_t * a_table)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
zc_hashtable_entry_t *p;
|
||||||
|
zc_hashtable_entry_t *q;
|
||||||
|
|
||||||
|
if (!a_table) {
|
||||||
|
zc_error("a_table[%p] is NULL, just do nothing", a_table);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < a_table->tab_size; i++) {
|
||||||
|
for (p = (a_table->tab)[i]; p; p = q) {
|
||||||
|
q = p->next;
|
||||||
|
if (a_table->key_del) {
|
||||||
|
a_table->key_del(p->key);
|
||||||
|
}
|
||||||
|
if (a_table->value_del) {
|
||||||
|
a_table->value_del(p->value);
|
||||||
|
}
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (a_table->tab)
|
||||||
|
free(a_table->tab);
|
||||||
|
free(a_table);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void zc_hashtable_clean(zc_hashtable_t * a_table)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
zc_hashtable_entry_t *p;
|
||||||
|
zc_hashtable_entry_t *q;
|
||||||
|
|
||||||
|
for (i = 0; i < a_table->tab_size; i++) {
|
||||||
|
for (p = (a_table->tab)[i]; p; p = q) {
|
||||||
|
q = p->next;
|
||||||
|
if (a_table->key_del) {
|
||||||
|
a_table->key_del(p->key);
|
||||||
|
}
|
||||||
|
if (a_table->value_del) {
|
||||||
|
a_table->value_del(p->value);
|
||||||
|
}
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
(a_table->tab)[i] = NULL;
|
||||||
|
}
|
||||||
|
a_table->nelem = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zc_hashtable_rehash(zc_hashtable_t * a_table)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
size_t j;
|
||||||
|
size_t tab_size;
|
||||||
|
zc_hashtable_entry_t **tab;
|
||||||
|
zc_hashtable_entry_t *p;
|
||||||
|
zc_hashtable_entry_t *q;
|
||||||
|
|
||||||
|
tab_size = 2 * a_table->tab_size;
|
||||||
|
tab = calloc(tab_size, sizeof(*tab));
|
||||||
|
if (!tab) {
|
||||||
|
zc_error("calloc fail, errno[%d]", errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < a_table->tab_size; i++) {
|
||||||
|
for (p = (a_table->tab)[i]; p; p = q) {
|
||||||
|
q = p->next;
|
||||||
|
|
||||||
|
p->next = NULL;
|
||||||
|
p->prev = NULL;
|
||||||
|
j = p->hash_key % tab_size;
|
||||||
|
if (tab[j]) {
|
||||||
|
tab[j]->prev = p;
|
||||||
|
p->next = tab[j];
|
||||||
|
}
|
||||||
|
tab[j] = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(a_table->tab);
|
||||||
|
a_table->tab = tab;
|
||||||
|
a_table->tab_size = tab_size;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
zc_hashtable_entry_t *zc_hashtable_get_entry(zc_hashtable_t * a_table, const void *a_key)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
zc_hashtable_entry_t *p;
|
||||||
|
|
||||||
|
i = a_table->hash(a_key) % a_table->tab_size;
|
||||||
|
for (p = (a_table->tab)[i]; p; p = p->next) {
|
||||||
|
if (a_table->equal(a_key, p->key))
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *zc_hashtable_get(zc_hashtable_t * a_table, const void *a_key)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
zc_hashtable_entry_t *p;
|
||||||
|
|
||||||
|
i = a_table->hash(a_key) % a_table->tab_size;
|
||||||
|
for (p = (a_table->tab)[i]; p; p = p->next) {
|
||||||
|
if (a_table->equal(a_key, p->key))
|
||||||
|
return p->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int zc_hashtable_put(zc_hashtable_t * a_table, void *a_key, void *a_value)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
unsigned int i;
|
||||||
|
zc_hashtable_entry_t *p = NULL;
|
||||||
|
|
||||||
|
i = a_table->hash(a_key) % a_table->tab_size;
|
||||||
|
for (p = (a_table->tab)[i]; p; p = p->next) {
|
||||||
|
if (a_table->equal(a_key, p->key))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p) {
|
||||||
|
if (a_table->key_del) {
|
||||||
|
a_table->key_del(p->key);
|
||||||
|
}
|
||||||
|
if (a_table->value_del) {
|
||||||
|
a_table->value_del(p->value);
|
||||||
|
}
|
||||||
|
p->key = a_key;
|
||||||
|
p->value = a_value;
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
if (a_table->nelem > a_table->tab_size * 1.3) {
|
||||||
|
rc = zc_hashtable_rehash(a_table);
|
||||||
|
if (rc) {
|
||||||
|
zc_error("rehash fail");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p = calloc(1, sizeof(*p));
|
||||||
|
if (!p) {
|
||||||
|
zc_error("calloc fail, errno[%d]", errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
p->hash_key = a_table->hash(a_key);
|
||||||
|
p->key = a_key;
|
||||||
|
p->value = a_value;
|
||||||
|
p->next = NULL;
|
||||||
|
p->prev = NULL;
|
||||||
|
|
||||||
|
i = p->hash_key % a_table->tab_size;
|
||||||
|
if ((a_table->tab)[i]) {
|
||||||
|
(a_table->tab)[i]->prev = p;
|
||||||
|
p->next = (a_table->tab)[i];
|
||||||
|
}
|
||||||
|
(a_table->tab)[i] = p;
|
||||||
|
a_table->nelem++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void zc_hashtable_remove(zc_hashtable_t * a_table, const void *a_key)
|
||||||
|
{
|
||||||
|
zc_hashtable_entry_t *p;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (!a_table || !a_key) {
|
||||||
|
zc_error("a_table[%p] or a_key[%p] is NULL, just do nothing", a_table, a_key);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = a_table->hash(a_key) % a_table->tab_size;
|
||||||
|
for (p = (a_table->tab)[i]; p; p = p->next) {
|
||||||
|
if (a_table->equal(a_key, p->key))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!p) {
|
||||||
|
zc_error("p[%p] not found in hashtable", p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a_table->key_del) {
|
||||||
|
a_table->key_del(p->key);
|
||||||
|
}
|
||||||
|
if (a_table->value_del) {
|
||||||
|
a_table->value_del(p->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p->next) {
|
||||||
|
p->next->prev = p->prev;
|
||||||
|
}
|
||||||
|
if (p->prev) {
|
||||||
|
p->prev->next = p->next;
|
||||||
|
} else {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
i = p->hash_key % a_table->tab_size;
|
||||||
|
a_table->tab[i] = p->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(p);
|
||||||
|
a_table->nelem--;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
zc_hashtable_entry_t *zc_hashtable_begin(zc_hashtable_t * a_table)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
zc_hashtable_entry_t *p;
|
||||||
|
|
||||||
|
for (i = 0; i < a_table->tab_size; i++) {
|
||||||
|
for (p = (a_table->tab)[i]; p; p = p->next) {
|
||||||
|
if (p)
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
zc_hashtable_entry_t *zc_hashtable_next(zc_hashtable_t * a_table, zc_hashtable_entry_t * a_entry)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
size_t j;
|
||||||
|
|
||||||
|
if (a_entry->next)
|
||||||
|
return a_entry->next;
|
||||||
|
|
||||||
|
i = a_entry->hash_key % a_table->tab_size;
|
||||||
|
|
||||||
|
for (j = i + 1; j < a_table->tab_size; j++) {
|
||||||
|
if ((a_table->tab)[j]) {
|
||||||
|
return (a_table->tab)[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
|
||||||
|
unsigned int zc_hashtable_str_hash(const void *str)
|
||||||
|
{
|
||||||
|
unsigned int h = 5381;
|
||||||
|
const char *p = (const char *)str;
|
||||||
|
|
||||||
|
while (*p != '\0')
|
||||||
|
h = ((h << 5) + h) + (*p++); /* hash * 33 + c */
|
||||||
|
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
int zc_hashtable_str_equal(const void *key1, const void *key2)
|
||||||
|
{
|
||||||
|
return (STRCMP((const char *)key1, ==, (const char *)key2));
|
||||||
|
}
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __zc_hashtalbe_h
|
||||||
|
#define __zc_hashtalbe_h
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
typedef struct zc_hashtable_entry_s {
|
||||||
|
unsigned int hash_key;
|
||||||
|
void *key;
|
||||||
|
void *value;
|
||||||
|
struct zc_hashtable_entry_s *prev;
|
||||||
|
struct zc_hashtable_entry_s *next;
|
||||||
|
} zc_hashtable_entry_t;
|
||||||
|
|
||||||
|
typedef struct zc_hashtable_s zc_hashtable_t;
|
||||||
|
|
||||||
|
typedef unsigned int (*zc_hashtable_hash_fn) (const void *key);
|
||||||
|
typedef int (*zc_hashtable_equal_fn) (const void *key1, const void *key2);
|
||||||
|
typedef void (*zc_hashtable_del_fn) (void *kv);
|
||||||
|
|
||||||
|
zc_hashtable_t *zc_hashtable_new(size_t a_size,
|
||||||
|
zc_hashtable_hash_fn hash_fn,
|
||||||
|
zc_hashtable_equal_fn equal_fn,
|
||||||
|
zc_hashtable_del_fn key_del_fn,
|
||||||
|
zc_hashtable_del_fn value_del_fn);
|
||||||
|
|
||||||
|
void zc_hashtable_del(zc_hashtable_t * a_table);
|
||||||
|
void zc_hashtable_clean(zc_hashtable_t * a_table);
|
||||||
|
int zc_hashtable_put(zc_hashtable_t * a_table, void *a_key, void *a_value);
|
||||||
|
zc_hashtable_entry_t *zc_hashtable_get_entry(zc_hashtable_t * a_table, const void *a_key);
|
||||||
|
void *zc_hashtable_get(zc_hashtable_t * a_table, const void *a_key);
|
||||||
|
void zc_hashtable_remove(zc_hashtable_t * a_table, const void *a_key);
|
||||||
|
zc_hashtable_entry_t *zc_hashtable_begin(zc_hashtable_t * a_table);
|
||||||
|
zc_hashtable_entry_t *zc_hashtable_next(zc_hashtable_t * a_table, zc_hashtable_entry_t * a_entry);
|
||||||
|
|
||||||
|
#define zc_hashtable_foreach(a_table, a_entry) \
|
||||||
|
for(a_entry = zc_hashtable_begin(a_table); a_entry; a_entry = zc_hashtable_next(a_table, a_entry))
|
||||||
|
|
||||||
|
unsigned int zc_hashtable_str_hash(const void *str);
|
||||||
|
int zc_hashtable_str_equal(const void *key1, const void *key2);
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* 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 <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "zc_profile.h"
|
||||||
|
#include "zc_xplatform.h"
|
||||||
|
|
||||||
|
static void zc_time(char *time_str, size_t time_str_size)
|
||||||
|
{
|
||||||
|
time_t tt;
|
||||||
|
struct tm local_time;
|
||||||
|
|
||||||
|
time(&tt);
|
||||||
|
localtime_r(&tt, &local_time);
|
||||||
|
strftime(time_str, time_str_size, "%m-%d %T", &local_time);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int zc_profile_inner(int flag, const char *file, const long line, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
char time_str[20 + 1];
|
||||||
|
FILE *fp = NULL;
|
||||||
|
|
||||||
|
static char *debug_log = NULL;
|
||||||
|
static char *error_log = NULL;
|
||||||
|
static size_t init_flag = 0;
|
||||||
|
|
||||||
|
if (!init_flag) {
|
||||||
|
init_flag = 1;
|
||||||
|
debug_log = getenv("ZLOG_PROFILE_DEBUG");
|
||||||
|
error_log = getenv("ZLOG_PROFILE_ERROR");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (flag) {
|
||||||
|
case ZC_DEBUG:
|
||||||
|
if (debug_log == NULL) return 0;
|
||||||
|
fp = fopen(debug_log, "a");
|
||||||
|
if (!fp) return -1;
|
||||||
|
zc_time(time_str, sizeof(time_str));
|
||||||
|
fprintf(fp, "%s DEBUG (%d:%s:%ld) ", time_str, getpid(), file, line);
|
||||||
|
break;
|
||||||
|
case ZC_WARN:
|
||||||
|
if (error_log == NULL) return 0;
|
||||||
|
fp = fopen(error_log, "a");
|
||||||
|
if (!fp) return -1;
|
||||||
|
zc_time(time_str, sizeof(time_str));
|
||||||
|
fprintf(fp, "%s WARN (%d:%s:%ld) ", time_str, getpid(), file, line);
|
||||||
|
break;
|
||||||
|
case ZC_ERROR:
|
||||||
|
if (error_log == NULL) return 0;
|
||||||
|
fp = fopen(error_log, "a");
|
||||||
|
if (!fp) return -1;
|
||||||
|
zc_time(time_str, sizeof(time_str));
|
||||||
|
fprintf(fp, "%s ERROR (%d:%s:%ld) ", time_str, getpid(), file, line);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* writing file twice(time & msg) is not atomic
|
||||||
|
* may cause cross
|
||||||
|
* but avoid log size limit */
|
||||||
|
va_start(args, fmt);
|
||||||
|
vfprintf(fp, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __zc_profile_h
|
||||||
|
#define __zc_profile_h
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#define EMPTY()
|
||||||
|
#define zc_assert(expr, rv) \
|
||||||
|
if(!(expr)) { \
|
||||||
|
zc_error(#expr" is null or 0"); \
|
||||||
|
return rv; \
|
||||||
|
}
|
||||||
|
|
||||||
|
enum zc_profile_flag {
|
||||||
|
ZC_DEBUG = 0,
|
||||||
|
ZC_WARN = 1,
|
||||||
|
ZC_ERROR = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
|
||||||
|
#define zc_debug(...) \
|
||||||
|
zc_profile_inner(ZC_DEBUG, __FILE__, __LINE__, __VA_ARGS__)
|
||||||
|
#define zc_warn(...) \
|
||||||
|
zc_profile_inner(ZC_WARN, __FILE__, __LINE__, __VA_ARGS__)
|
||||||
|
#define zc_error(...) \
|
||||||
|
zc_profile_inner(ZC_ERROR, __FILE__, __LINE__, __VA_ARGS__)
|
||||||
|
#define zc_profile(flag, ...) \
|
||||||
|
zc_profile_inner(flag, __FILE__, __LINE__, __VA_ARGS__)
|
||||||
|
#elif defined __GNUC__
|
||||||
|
#define zc_debug(fmt, args...) \
|
||||||
|
zc_profile_inner(ZC_DEBUG, __FILE__, __LINE__, fmt, ## args)
|
||||||
|
#define zc_warn(fmt, args...) \
|
||||||
|
zc_profile_inner(ZC_WARN, __FILE__, __LINE__, fmt, ## args)
|
||||||
|
#define zc_error(fmt, args...) \
|
||||||
|
zc_profile_inner(ZC_ERROR, __FILE__, __LINE__, fmt, ## args)
|
||||||
|
#define zc_profile(flag, fmt, args...) \
|
||||||
|
zc_profile_inner(flag, __FILE__, __LINE__, fmt, ## args)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
int zc_profile_inner(int flag,
|
||||||
|
const char *file, const long line,
|
||||||
|
const char *fmt, ...);
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,147 @@
|
|||||||
|
/*
|
||||||
|
* 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 <string.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "zc_defs.h"
|
||||||
|
|
||||||
|
size_t zc_parse_byte_size(char *astring)
|
||||||
|
{
|
||||||
|
/* Parse size in bytes depending on the suffix. Valid suffixes are KB, MB and GB */
|
||||||
|
char *p;
|
||||||
|
char *q;
|
||||||
|
size_t sz;
|
||||||
|
long res;
|
||||||
|
int c, m;
|
||||||
|
|
||||||
|
zc_assert(astring, 0);
|
||||||
|
|
||||||
|
/* clear space */
|
||||||
|
for (p = q = astring; *p != '\0'; p++) {
|
||||||
|
if (isspace(*p)) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
*q = *p;
|
||||||
|
q++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*q = '\0';
|
||||||
|
|
||||||
|
sz = strlen(astring);
|
||||||
|
res = strtol(astring, (char **)NULL, 10);
|
||||||
|
|
||||||
|
if (res <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (astring[sz - 1] == 'B' || astring[sz - 1] == 'b') {
|
||||||
|
c = astring[sz - 2];
|
||||||
|
m = 1024;
|
||||||
|
} else {
|
||||||
|
c = astring[sz - 1];
|
||||||
|
m = 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (c) {
|
||||||
|
case 'K':
|
||||||
|
case 'k':
|
||||||
|
res *= m;
|
||||||
|
break;
|
||||||
|
case 'M':
|
||||||
|
case 'm':
|
||||||
|
res *= m * m;
|
||||||
|
break;
|
||||||
|
case 'G':
|
||||||
|
case 'g':
|
||||||
|
res *= m * m * m;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (!isdigit(c)) {
|
||||||
|
zc_error("Wrong suffix parsing " "size in bytes for string [%s], ignoring suffix",
|
||||||
|
astring);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (res);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
int zc_str_replace_env(char *str, size_t str_size)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
char *q;
|
||||||
|
char fmt[MAXLEN_CFG_LINE + 1];
|
||||||
|
char env_key[MAXLEN_CFG_LINE + 1];
|
||||||
|
char env_value[MAXLEN_CFG_LINE + 1];
|
||||||
|
int str_len;
|
||||||
|
int env_value_len;
|
||||||
|
int nscan;
|
||||||
|
int nread;
|
||||||
|
|
||||||
|
str_len = strlen(str);
|
||||||
|
q = str;
|
||||||
|
|
||||||
|
do {
|
||||||
|
p = strchr(q, '%');
|
||||||
|
if (!p) {
|
||||||
|
/* can't find more % */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(fmt, 0x00, sizeof(fmt));
|
||||||
|
memset(env_key, 0x00, sizeof(env_key));
|
||||||
|
memset(env_value, 0x00, sizeof(env_value));
|
||||||
|
nread = 0;
|
||||||
|
nscan = sscanf(p + 1, "%[.0-9-]%n", fmt + 1, &nread);
|
||||||
|
if (nscan == 1) {
|
||||||
|
fmt[0] = '%';
|
||||||
|
fmt[nread + 1] = 's';
|
||||||
|
} else {
|
||||||
|
nread = 0;
|
||||||
|
strcpy(fmt, "%s");
|
||||||
|
}
|
||||||
|
|
||||||
|
q = p + 1 + nread;
|
||||||
|
|
||||||
|
nscan = sscanf(q, "E(%[^)])%n", env_key, &nread);
|
||||||
|
if (nscan == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
q += nread;
|
||||||
|
|
||||||
|
if (*(q - 1) != ')') {
|
||||||
|
zc_error("in string[%s] can't find match )", p);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
env_value_len = snprintf(env_value, sizeof(env_value), fmt, getenv(env_key));
|
||||||
|
if (env_value_len < 0 || env_value_len >= sizeof(env_value)) {
|
||||||
|
zc_error("snprintf fail, errno[%d], evn_value_len[%d]",
|
||||||
|
errno, env_value_len);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
str_len = str_len - (q - p) + env_value_len;
|
||||||
|
if (str_len > str_size - 1) {
|
||||||
|
zc_error("repalce env_value[%s] cause overlap", env_value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memmove(p + env_value_len, q, strlen(q) + 1);
|
||||||
|
memcpy(p, env_value, env_value_len);
|
||||||
|
|
||||||
|
} while (1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
#ifndef __zc_util_h
|
||||||
|
#define __zc_util_h
|
||||||
|
|
||||||
|
size_t zc_parse_byte_size(char *astring);
|
||||||
|
int zc_str_replace_env(char *str, size_t str_size);
|
||||||
|
|
||||||
|
#define zc_max(a,b) ((a) > (b) ? (a) : (b))
|
||||||
|
#define zc_min(a,b) ((a) < (b) ? (a) : (b))
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
#ifndef __zc_xplatform_h
|
||||||
|
#define __zc_xplatform_h
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
#define ZLOG_INT32_LEN sizeof("-2147483648") - 1
|
||||||
|
#define ZLOG_INT64_LEN sizeof("-9223372036854775808") - 1
|
||||||
|
|
||||||
|
#if ((__GNU__ == 2) && (__GNUC_MINOR__ < 8))
|
||||||
|
#define ZLOG_MAX_UINT32_VALUE (uint32_t) 0xffffffffLL
|
||||||
|
#else
|
||||||
|
#define ZLOG_MAX_UINT32_VALUE (uint32_t) 0xffffffff
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ZLOG_MAX_INT32_VALUE (uint32_t) 0x7fffffff
|
||||||
|
|
||||||
|
#define MAXLEN_PATH 1024
|
||||||
|
#define MAXLEN_CFG_LINE (MAXLEN_PATH * 4)
|
||||||
|
#define MAXLINES_NO 128
|
||||||
|
|
||||||
|
#define FILE_NEWLINE "\n"
|
||||||
|
#define FILE_NEWLINE_LEN 1
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <strings.h>
|
||||||
|
|
||||||
|
#define STRCMP(_a_,_C_,_b_) ( strcmp(_a_,_b_) _C_ 0 )
|
||||||
|
#define STRNCMP(_a_,_C_,_b_,_n_) ( strncmp(_a_,_b_,_n_) _C_ 0 )
|
||||||
|
#define STRICMP(_a_,_C_,_b_) ( strcasecmp(_a_,_b_) _C_ 0 )
|
||||||
|
#define STRNICMP(_a_,_C_,_b_,_n_) ( strncasecmp(_a_,_b_,_n_) _C_ 0 )
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <AvailabilityMacros.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Define zlog_fstat to fstat or fstat64() */
|
||||||
|
#if defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_6)
|
||||||
|
#define zlog_fstat fstat64
|
||||||
|
#define zlog_stat stat64
|
||||||
|
#else
|
||||||
|
#define zlog_fstat fstat
|
||||||
|
#define zlog_stat stat
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Define zlog_fsync to fdatasync() in Linux and fsync() for all the rest */
|
||||||
|
#ifdef __linux__
|
||||||
|
#define zlog_fsync fdatasync
|
||||||
|
#else
|
||||||
|
#define zlog_fsync fsync
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* 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 <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "zlog.h"
|
||||||
|
#include "version.h"
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
int op;
|
||||||
|
int quiet = 0;
|
||||||
|
static const char *help =
|
||||||
|
"usage: zlog-chk-conf [conf files]...\n"
|
||||||
|
"\t-q,\tsuppress non-error message\n"
|
||||||
|
"\t-h,\tshow help message\n"
|
||||||
|
"zlog version: " ZLOG_VERSION "\n";
|
||||||
|
|
||||||
|
while((op = getopt(argc, argv, "qhv")) > 0) {
|
||||||
|
if (op == 'h') {
|
||||||
|
fputs(help, stdout);
|
||||||
|
return 0;
|
||||||
|
} else if (op == 'q') {
|
||||||
|
quiet = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
argc -= optind;
|
||||||
|
argv += optind;
|
||||||
|
|
||||||
|
if (argc == 0) {
|
||||||
|
fputs(help, stdout);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
setenv("ZLOG_PROFILE_ERROR", "/dev/stderr", 1);
|
||||||
|
setenv("ZLOG_CHECK_FORMAT_RULE", "1", 1);
|
||||||
|
|
||||||
|
while (argc > 0) {
|
||||||
|
rc = zlog_init(*argv);
|
||||||
|
if (rc) {
|
||||||
|
printf("\n---[%s] syntax error, see error message above\n",
|
||||||
|
*argv);
|
||||||
|
exit(2);
|
||||||
|
} else {
|
||||||
|
zlog_fini();
|
||||||
|
if (!quiet) {
|
||||||
|
printf("--[%s] syntax right\n", *argv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,279 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __zlog_h
|
||||||
|
#define __zlog_h
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdarg.h> /* for va_list */
|
||||||
|
#include <stdio.h> /* for size_t */
|
||||||
|
|
||||||
|
# if defined __GNUC__
|
||||||
|
# define ZLOG_CHECK_PRINTF(m,n) __attribute__((format(printf,m,n)))
|
||||||
|
# else
|
||||||
|
# define ZLOG_CHECK_PRINTF(m,n)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
typedef struct zlog_category_s zlog_category_t;
|
||||||
|
|
||||||
|
int zlog_init(const char *config);
|
||||||
|
int zlog_reload(const char *config);
|
||||||
|
void zlog_fini(void);
|
||||||
|
|
||||||
|
void zlog_profile(void);
|
||||||
|
|
||||||
|
zlog_category_t *zlog_get_category(const char *cname);
|
||||||
|
int zlog_level_enabled(zlog_category_t *category, const int level);
|
||||||
|
|
||||||
|
int zlog_put_mdc(const char *key, const char *value);
|
||||||
|
char *zlog_get_mdc(const char *key);
|
||||||
|
void zlog_remove_mdc(const char *key);
|
||||||
|
void zlog_clean_mdc(void);
|
||||||
|
|
||||||
|
int zlog_level_switch(zlog_category_t * category, int level);
|
||||||
|
int zlog_level_enabled(zlog_category_t * category, int level);
|
||||||
|
|
||||||
|
void zlog(zlog_category_t * category,
|
||||||
|
const char *file, size_t filelen,
|
||||||
|
const char *func, size_t funclen,
|
||||||
|
long line, int level,
|
||||||
|
const char *format, ...) ZLOG_CHECK_PRINTF(8,9);
|
||||||
|
void vzlog(zlog_category_t * category,
|
||||||
|
const char *file, size_t filelen,
|
||||||
|
const char *func, size_t funclen,
|
||||||
|
long line, int level,
|
||||||
|
const char *format, va_list args);
|
||||||
|
void hzlog(zlog_category_t * category,
|
||||||
|
const char *file, size_t filelen,
|
||||||
|
const char *func, size_t funclen,
|
||||||
|
long line, int level,
|
||||||
|
const void *buf, size_t buflen);
|
||||||
|
|
||||||
|
int dzlog_init(const char *confpath, const char *cname);
|
||||||
|
int dzlog_set_category(const char *cname);
|
||||||
|
|
||||||
|
void dzlog(const char *file, size_t filelen,
|
||||||
|
const char *func, size_t funclen,
|
||||||
|
long line, int level,
|
||||||
|
const char *format, ...) ZLOG_CHECK_PRINTF(7,8);
|
||||||
|
void vdzlog(const char *file, size_t filelen,
|
||||||
|
const char *func, size_t funclen,
|
||||||
|
long line, int level,
|
||||||
|
const char *format, va_list args);
|
||||||
|
void hdzlog(const char *file, size_t filelen,
|
||||||
|
const char *func, size_t funclen,
|
||||||
|
long line, int level,
|
||||||
|
const void *buf, size_t buflen);
|
||||||
|
|
||||||
|
typedef struct zlog_msg_s {
|
||||||
|
char *buf;
|
||||||
|
size_t len;
|
||||||
|
char *path;
|
||||||
|
} zlog_msg_t;
|
||||||
|
|
||||||
|
typedef int (*zlog_record_fn)(zlog_msg_t *msg);
|
||||||
|
int zlog_set_record(const char *rname, zlog_record_fn record);
|
||||||
|
|
||||||
|
const char *zlog_version(void);
|
||||||
|
|
||||||
|
/******* useful macros, can be redefined at user's h file **********/
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ZLOG_LEVEL_DEBUG = 20,
|
||||||
|
ZLOG_LEVEL_INFO = 40,
|
||||||
|
ZLOG_LEVEL_NOTICE = 60,
|
||||||
|
ZLOG_LEVEL_WARN = 80,
|
||||||
|
ZLOG_LEVEL_ERROR = 100,
|
||||||
|
ZLOG_LEVEL_FATAL = 120
|
||||||
|
} zlog_level;
|
||||||
|
|
||||||
|
#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
|
||||||
|
# if defined __GNUC__ && __GNUC__ >= 2
|
||||||
|
# define __func__ __FUNCTION__
|
||||||
|
# else
|
||||||
|
# define __func__ "<unknown>"
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
|
||||||
|
/* zlog macros */
|
||||||
|
#define zlog_fatal(cat, ...) \
|
||||||
|
zlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_FATAL, __VA_ARGS__)
|
||||||
|
#define zlog_error(cat, ...) \
|
||||||
|
zlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_ERROR, __VA_ARGS__)
|
||||||
|
#define zlog_warn(cat, ...) \
|
||||||
|
zlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_WARN, __VA_ARGS__)
|
||||||
|
#define zlog_notice(cat, ...) \
|
||||||
|
zlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_NOTICE, __VA_ARGS__)
|
||||||
|
#define zlog_info(cat, ...) \
|
||||||
|
zlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_INFO, __VA_ARGS__)
|
||||||
|
#define zlog_debug(cat, ...) \
|
||||||
|
zlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_DEBUG, __VA_ARGS__)
|
||||||
|
/* dzlog macros */
|
||||||
|
#define dzlog_fatal(...) \
|
||||||
|
dzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_FATAL, __VA_ARGS__)
|
||||||
|
#define dzlog_error(...) \
|
||||||
|
dzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_ERROR, __VA_ARGS__)
|
||||||
|
#define dzlog_warn(...) \
|
||||||
|
dzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_WARN, __VA_ARGS__)
|
||||||
|
#define dzlog_notice(...) \
|
||||||
|
dzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_NOTICE, __VA_ARGS__)
|
||||||
|
#define dzlog_info(...) \
|
||||||
|
dzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_INFO, __VA_ARGS__)
|
||||||
|
#define dzlog_debug(...) \
|
||||||
|
dzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_DEBUG, __VA_ARGS__)
|
||||||
|
#elif defined __GNUC__
|
||||||
|
/* zlog macros */
|
||||||
|
#define zlog_fatal(cat, format, args...) \
|
||||||
|
zlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_FATAL, format, ##args)
|
||||||
|
#define zlog_error(cat, format, args...) \
|
||||||
|
zlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_ERROR, format, ##args)
|
||||||
|
#define zlog_warn(cat, format, args...) \
|
||||||
|
zlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_WARN, format, ##args)
|
||||||
|
#define zlog_notice(cat, format, args...) \
|
||||||
|
zlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_NOTICE, format, ##args)
|
||||||
|
#define zlog_info(cat, format, args...) \
|
||||||
|
zlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_INFO, format, ##args)
|
||||||
|
#define zlog_debug(cat, format, args...) \
|
||||||
|
zlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_DEBUG, format, ##args)
|
||||||
|
/* dzlog macros */
|
||||||
|
#define dzlog_fatal(format, args...) \
|
||||||
|
dzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_FATAL, format, ##args)
|
||||||
|
#define dzlog_error(format, args...) \
|
||||||
|
dzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_ERROR, format, ##args)
|
||||||
|
#define dzlog_warn(format, args...) \
|
||||||
|
dzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_WARN, format, ##args)
|
||||||
|
#define dzlog_notice(format, args...) \
|
||||||
|
dzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_NOTICE, format, ##args)
|
||||||
|
#define dzlog_info(format, args...) \
|
||||||
|
dzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_INFO, format, ##args)
|
||||||
|
#define dzlog_debug(format, args...) \
|
||||||
|
dzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_DEBUG, format, ##args)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* vzlog macros */
|
||||||
|
#define vzlog_fatal(cat, format, args) \
|
||||||
|
vzlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_FATAL, format, args)
|
||||||
|
#define vzlog_error(cat, format, args) \
|
||||||
|
vzlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_ERROR, format, args)
|
||||||
|
#define vzlog_warn(cat, format, args) \
|
||||||
|
vzlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_WARN, format, args)
|
||||||
|
#define vzlog_notice(cat, format, args) \
|
||||||
|
vzlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_NOTICE, format, args)
|
||||||
|
#define vzlog_info(cat, format, args) \
|
||||||
|
vzlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_INFO, format, args)
|
||||||
|
#define vzlog_debug(cat, format, args) \
|
||||||
|
vzlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_DEBUG, format, args)
|
||||||
|
|
||||||
|
/* hzlog macros */
|
||||||
|
#define hzlog_fatal(cat, buf, buf_len) \
|
||||||
|
hzlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_FATAL, buf, buf_len)
|
||||||
|
#define hzlog_error(cat, buf, buf_len) \
|
||||||
|
hzlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_ERROR, buf, buf_len)
|
||||||
|
#define hzlog_warn(cat, buf, buf_len) \
|
||||||
|
hzlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_WARN, buf, buf_len)
|
||||||
|
#define hzlog_notice(cat, buf, buf_len) \
|
||||||
|
hzlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_NOTICE, buf, buf_len)
|
||||||
|
#define hzlog_info(cat, buf, buf_len) \
|
||||||
|
hzlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_INFO, buf, buf_len)
|
||||||
|
#define hzlog_debug(cat, buf, buf_len) \
|
||||||
|
hzlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_DEBUG, buf, buf_len)
|
||||||
|
|
||||||
|
|
||||||
|
/* vdzlog macros */
|
||||||
|
#define vdzlog_fatal(format, args) \
|
||||||
|
vdzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_FATAL, format, args)
|
||||||
|
#define vdzlog_error(format, args) \
|
||||||
|
vdzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_ERROR, format, args)
|
||||||
|
#define vdzlog_warn(format, args) \
|
||||||
|
vdzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_WARN, format, args)
|
||||||
|
#define vdzlog_notice(format, args) \
|
||||||
|
vdzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_NOTICE, format, args)
|
||||||
|
#define vdzlog_info(format, args) \
|
||||||
|
vdzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_INFO, format, args)
|
||||||
|
#define vdzlog_debug(format, args) \
|
||||||
|
vdzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_DEBUG, format, args)
|
||||||
|
|
||||||
|
/* hdzlog macros */
|
||||||
|
#define hdzlog_fatal(buf, buf_len) \
|
||||||
|
hdzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_FATAL, buf, buf_len)
|
||||||
|
#define hdzlog_error(buf, buf_len) \
|
||||||
|
hdzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_ERROR, buf, buf_len)
|
||||||
|
#define hdzlog_warn(buf, buf_len) \
|
||||||
|
hdzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_WARN, buf, buf_len)
|
||||||
|
#define hdzlog_notice(buf, buf_len) \
|
||||||
|
hdzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_NOTICE, buf, buf_len)
|
||||||
|
#define hdzlog_info(buf, buf_len) \
|
||||||
|
hdzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_INFO, buf, buf_len)
|
||||||
|
#define hdzlog_debug(buf, buf_len) \
|
||||||
|
hdzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_DEBUG, buf, buf_len)
|
||||||
|
|
||||||
|
/* enabled macros */
|
||||||
|
#define zlog_fatal_enabled(zc) zlog_level_enabled(zc, ZLOG_LEVEL_FATAL)
|
||||||
|
#define zlog_error_enabled(zc) zlog_level_enabled(zc, ZLOG_LEVEL_ERROR)
|
||||||
|
#define zlog_warn_enabled(zc) zlog_level_enabled(zc, ZLOG_LEVEL_WARN)
|
||||||
|
#define zlog_notice_enabled(zc) zlog_level_enabled(zc, ZLOG_LEVEL_NOTICE)
|
||||||
|
#define zlog_info_enabled(zc) zlog_level_enabled(zc, ZLOG_LEVEL_INFO)
|
||||||
|
#define zlog_debug_enabled(zc) zlog_level_enabled(zc, ZLOG_LEVEL_DEBUG)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "zlog.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||||
|
{
|
||||||
|
char filename[256];
|
||||||
|
sprintf(filename, "/tmp/libfuzzer.%d", getpid());
|
||||||
|
|
||||||
|
FILE *fp = fopen(filename, "wb");
|
||||||
|
if (!fp)
|
||||||
|
return 0;
|
||||||
|
fwrite(data, size, 1, fp);
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
int rc = zlog_init(filename);
|
||||||
|
if (rc == 0)
|
||||||
|
{
|
||||||
|
zlog_fini();
|
||||||
|
}
|
||||||
|
unlink(filename);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
exe = \
|
||||||
|
test_tmp \
|
||||||
|
test_longlog \
|
||||||
|
test_buf \
|
||||||
|
test_bitmap \
|
||||||
|
test_conf \
|
||||||
|
test_conf2 \
|
||||||
|
test_hashtable \
|
||||||
|
test_hello \
|
||||||
|
test_hex \
|
||||||
|
test_init \
|
||||||
|
test_level \
|
||||||
|
test_leak \
|
||||||
|
test_mdc \
|
||||||
|
test_multithread \
|
||||||
|
test_record \
|
||||||
|
test_pipe \
|
||||||
|
test_press_zlog \
|
||||||
|
test_press_zlog2 \
|
||||||
|
test_press_write \
|
||||||
|
test_press_write2 \
|
||||||
|
test_press_syslog \
|
||||||
|
test_syslog \
|
||||||
|
test_default \
|
||||||
|
test_profile \
|
||||||
|
test_category \
|
||||||
|
test_prompt \
|
||||||
|
test_enabled
|
||||||
|
|
||||||
|
all : $(exe)
|
||||||
|
|
||||||
|
$(exe) : %:%.o
|
||||||
|
gcc -O2 -g -o $@ $^ -L../src -lzlog -lpthread -Wl,-rpath ../src
|
||||||
|
|
||||||
|
.c.o :
|
||||||
|
gcc -O2 -g -Wall -D_GNU_SOURCE -o $@ -c $< -I. -I../src
|
||||||
|
|
||||||
|
clean :
|
||||||
|
rm -f press.log* *.o $(exe)
|
||||||
|
|
||||||
|
.PHONY : clean all
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* 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 <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "zlog.h"
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
unsigned char aa[32];
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
if (argc != 3) {
|
||||||
|
printf("useage: test_bitmap i j\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
dzlog_init(NULL, "AA");
|
||||||
|
|
||||||
|
|
||||||
|
i = atoi(argv[1]);
|
||||||
|
j = atoi(argv[2]);
|
||||||
|
|
||||||
|
memset(aa, 0x00, sizeof(aa));
|
||||||
|
|
||||||
|
/* 32 byte, 256 bit
|
||||||
|
* [11111..1100...00]
|
||||||
|
* i
|
||||||
|
*/
|
||||||
|
aa[i/8] |= ~(0xFF << (8 - i % 8));
|
||||||
|
memset(aa + i/8 + 1, 0xFF, sizeof(aa) - i/8 - 1);
|
||||||
|
|
||||||
|
hdzlog_info(aa, sizeof(aa));
|
||||||
|
|
||||||
|
dzlog_info("%0x", aa[j/8]);
|
||||||
|
dzlog_info("%0x", aa[j/8] >> 6);
|
||||||
|
|
||||||
|
/* see j of bits fits */
|
||||||
|
dzlog_info("%0x", ~((aa[j/8] >> (7 - j % 8)) & 0x01) );
|
||||||
|
|
||||||
|
zlog_fini();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
* 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 <stdio.h>
|
||||||
|
#include "zc_defs.h"
|
||||||
|
#include "buf.h"
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
zlog_buf_t *a_buf;
|
||||||
|
char *aa;
|
||||||
|
|
||||||
|
a_buf = zlog_buf_new(10, 20, "ABC");
|
||||||
|
if (!a_buf) {
|
||||||
|
zc_error("zlog_buf_new fail");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
aa = "123456789";
|
||||||
|
zlog_buf_append(a_buf, aa, strlen(aa));
|
||||||
|
zc_error("a_buf->start[%s]", a_buf->start);
|
||||||
|
fwrite(a_buf->start, zlog_buf_len(a_buf), 1, stdout);
|
||||||
|
zc_error("------------");
|
||||||
|
|
||||||
|
aa = "0";
|
||||||
|
zlog_buf_append(a_buf, aa, strlen(aa));
|
||||||
|
zc_error("a_buf->start[%s]", a_buf->start);
|
||||||
|
zc_error("------------");
|
||||||
|
|
||||||
|
aa = "12345";
|
||||||
|
zlog_buf_append(a_buf, aa, strlen(aa));
|
||||||
|
zc_error("a_buf->start[%s]", a_buf->start);
|
||||||
|
zc_error("------------");
|
||||||
|
|
||||||
|
aa = "6789";
|
||||||
|
zlog_buf_append(a_buf, aa, strlen(aa));
|
||||||
|
zc_error("a_buf->start[%s]", a_buf->start);
|
||||||
|
zc_error("------------");
|
||||||
|
|
||||||
|
aa = "0";
|
||||||
|
zlog_buf_append(a_buf, aa, strlen(aa));
|
||||||
|
zc_error("a_buf->start[%s]", a_buf->start);
|
||||||
|
zc_error("------------");
|
||||||
|
|
||||||
|
aa = "22345";
|
||||||
|
zlog_buf_append(a_buf, aa, strlen(aa));
|
||||||
|
zc_error("a_buf->start[%s]", a_buf->start);
|
||||||
|
zc_error("------------");
|
||||||
|
|
||||||
|
|
||||||
|
aa = "abc";
|
||||||
|
int i,j;
|
||||||
|
for (i = 0; i <= 5; i++) {
|
||||||
|
for (j = 0; j <= 5; j++) {
|
||||||
|
zlog_buf_restart(a_buf);
|
||||||
|
zc_error("left[1],max[%d],min[%d]", i, j);
|
||||||
|
zlog_buf_adjust_append(a_buf, aa, strlen(aa), 1, 0, i, j);
|
||||||
|
zc_error("a_buf->start[%s]", a_buf->start);
|
||||||
|
|
||||||
|
zc_error("-----");
|
||||||
|
|
||||||
|
zlog_buf_restart(a_buf);
|
||||||
|
zc_error("left[0],max[%d],min[%d]", i, j);
|
||||||
|
zlog_buf_adjust_append(a_buf, aa, strlen(aa), 0, 0, i, j);
|
||||||
|
zc_error("a_buf->start[%s]", a_buf->start);
|
||||||
|
zc_error("------------");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
aa = "1234567890";
|
||||||
|
zc_error("left[0],max[%d],min[%d]", 15, 5);
|
||||||
|
zlog_buf_adjust_append(a_buf, aa, strlen(aa), 0, 0, 15, 5);
|
||||||
|
zc_error("a_buf->start[%s]", a_buf->start);
|
||||||
|
zc_error("------------");
|
||||||
|
|
||||||
|
aa = "1234567890";
|
||||||
|
zlog_buf_restart(a_buf);
|
||||||
|
zc_error("left[0],max[%d],min[%d]", 25, 5);
|
||||||
|
zlog_buf_adjust_append(a_buf, aa, strlen(aa), 1, 0, 25, 5);
|
||||||
|
zc_error("a_buf->start[%s]", a_buf->start);
|
||||||
|
zc_error("------------");
|
||||||
|
|
||||||
|
zlog_buf_restart(a_buf);
|
||||||
|
zc_error("left[0],max[%d],min[%d]", 19, 5);
|
||||||
|
zlog_buf_adjust_append(a_buf, aa, strlen(aa), 0, 0, 19, 5);
|
||||||
|
zc_error("a_buf->start[%s]", a_buf->start);
|
||||||
|
zc_error("------------");
|
||||||
|
|
||||||
|
zlog_buf_restart(a_buf);
|
||||||
|
zc_error("left[0],max[%d],min[%d]", 20, 5);
|
||||||
|
zlog_buf_adjust_append(a_buf, aa, strlen(aa), 0, 0, 20, 5);
|
||||||
|
zc_error("a_buf->start[%s]", a_buf->start);
|
||||||
|
zc_error("------------");
|
||||||
|
|
||||||
|
zlog_buf_del(a_buf);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* 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 <stdio.h>
|
||||||
|
#include "zlog.h"
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
zlog_category_t *zc;
|
||||||
|
|
||||||
|
rc = zlog_init("test_category.conf");
|
||||||
|
if (rc) {
|
||||||
|
printf("init failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
zc = zlog_get_category("my_cat");
|
||||||
|
if (!zc) {
|
||||||
|
printf("get cat fail\n");
|
||||||
|
zlog_fini();
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
zlog_debug(zc, "hello, zlog - debug");
|
||||||
|
|
||||||
|
zc = zlog_get_category("my-cat");
|
||||||
|
if (!zc) {
|
||||||
|
printf("get cat fail\n");
|
||||||
|
zlog_fini();
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
zlog_info(zc, "hello, zlog - info");
|
||||||
|
|
||||||
|
zlog_fini();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
[global]
|
||||||
|
default format = "%V %v %m%n"
|
||||||
|
[rules]
|
||||||
|
my_cat.* >stdout;
|
||||||
|
my-cat.* >stdout;
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* 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 <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "zlog.h"
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
zlog_category_t *zc;
|
||||||
|
|
||||||
|
|
||||||
|
rc = zlog_init("test_conf.conf");
|
||||||
|
if (rc) {
|
||||||
|
printf("init failed, try zlog-chk-conf test_conf.conf for more detail\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
zc = zlog_get_category("my_cat");
|
||||||
|
if (!zc) {
|
||||||
|
printf("get cat fail\n");
|
||||||
|
zlog_fini();
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
zlog_info(zc, "hello, zlog");
|
||||||
|
|
||||||
|
zlog_fini();
|
||||||
|
printf("log end\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
[global]
|
||||||
|
strict init = true
|
||||||
|
buffer min= 1024
|
||||||
|
buffer max= 2MB
|
||||||
|
rotate lock file = /tmp/zlog.lock
|
||||||
|
default format = "defalut - %d(%F %X.%ms) %-6V (%c:%F:%U:%L) - %m%n"
|
||||||
|
|
||||||
|
[formats]
|
||||||
|
null = "%n"
|
||||||
|
print = "print - [%-10.3d(%F)]%n"
|
||||||
|
|
||||||
|
date = "date start%n%d(%a--Wed)%n%d(%A--Wednesday)%n%d(%b--Mar)%n%d(%B--March)%n%d(%c--WedMar211:45:262011)%n%d(%C--20)%n%d(%d--02)%n%d(%D--03/02/11)%n%d(%e--2)%n%d(%F--2011-03-02)%n%d(%g--11)%n%d(%G--2011)%n%d(%h--Mar)%n%d(%H--11)%n%d(%I--11)%n%d(%j--061)%n%d(%k-k)%n%d(%l-l)%n%d(%ms--500)%n%d(%m--03)%n%d(%M--45)%n%d(%us--500730)%n%d(%p--AM)%n%d(%r--11:45:26AM)%n%d(%R--11:45)%n%d(%s--epoch)%n%d(%S--26)%n%d(%t--)%n%d(%T--11:45:26)%n%d(%u--3)%n%d(%U--09)%n%d(%V--09)%n%d(%w--3)%n%d(%W--09)%n%d(%x--03/02/11)%n%d(%X--11:45:26)%n%d(%y--11)%n%d(%Y--2011)%n%d(%z--+0800)%n%d(%Z--CST)%n%d(%%--%)%n%d(%J--%J)%ndate end%n"
|
||||||
|
|
||||||
|
simple = "simple - %m%n"
|
||||||
|
|
||||||
|
text = "text - text%n"
|
||||||
|
|
||||||
|
ms = "ms - %d(%a--Wed)[%d(%ms)]%n"
|
||||||
|
|
||||||
|
msus = "msus - %d(%ms,%us,%ms,%us)%n"
|
||||||
|
|
||||||
|
[rules]
|
||||||
|
*.* >stderr;
|
||||||
|
*.* >stderr; null
|
||||||
|
*.* >stderr; print
|
||||||
|
*.* >stderr; date
|
||||||
|
*.* >stderr; simple
|
||||||
|
*.* >stderr; text
|
||||||
|
*.* >stderr; ms
|
||||||
|
*.* >stderr; msus
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* 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 <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "zlog.h"
|
||||||
|
#include "test_conf2.conf.h"
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
zlog_category_t *zc;
|
||||||
|
|
||||||
|
rc = zlog_init(test_conf2_conf);
|
||||||
|
if (rc) {
|
||||||
|
printf("init failed, save [] in a config file and try zlog-chk-conf for more detail [%s]\n", test_conf2_conf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
zc = zlog_get_category("my_cat");
|
||||||
|
if (!zc) {
|
||||||
|
printf("get cat fail\n");
|
||||||
|
zlog_fini();
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
zlog_info(zc, "hello, zlog");
|
||||||
|
|
||||||
|
zlog_fini();
|
||||||
|
printf("log end\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
#define test_conf2_conf "[global]\nstrict init = true\nbuffer min= 1024\nbuffer max= 2MB\nrotate lock file = /tmp/zlog.lock\ndefault format = \"defalut - %d(%F %X.%ms) %-6V (%c:%F:%U:%L) - %m%n\"\n\n[formats]\nnull = \"%n\"\nprint = \"print - [%-10.3d(%F)]%n\"\n\ndate = \"date start%n%d(%a--Wed)%n%d(%A--Wednesday)%n%d(%b--Mar)%n%d(%B--March)%n%d(%c--WedMar211:45:262011)%n%d(%C--20)%n%d(%d--02)%n%d(%D--03/02/11)%n%d(%e--2)%n%d(%F--2011-03-02)%n%d(%g--11)%n%d(%G--2011)%n%d(%h--Mar)%n%d(%H--11)%n%d(%I--11)%n%d(%j--061)%n%d(%k-k)%n%d(%l-l)%n%d(%ms--500)%n%d(%m--03)%n%d(%M--45)%n%d(%us--500730)%n%d(%p--AM)%n%d(%r--11:45:26AM)%n%d(%R--11:45)%n%d(%s--epoch)%n%d(%S--26)%n%d(%t--)%n%d(%T--11:45:26)%n%d(%u--3)%n%d(%U--09)%n%d(%V--09)%n%d(%w--3)%n%d(%W--09)%n%d(%x--03/02/11)%n%d(%X--11:45:26)%n%d(%y--11)%n%d(%Y--2011)%n%d(%z--+0800)%n%d(%Z--CST)%n%d(%%--%)%n%d(%J--%J)%ndate end%n\"\n\nsimple = \"simple - %m%n\"\n\ntext = \"text - text%n\"\n\nms = \"ms - %d(%a--Wed)[%d(%ms)]%n\"\n\nmsus = \"msus - %d(%ms,%us,%ms,%us)%n\"\n\n[rules]\n*.* >stderr;\n*.* >stderr; null\n*.* >stderr; print\n*.* >stderr; date\n*.* >stderr; simple\n*.* >stderr; text\n*.* >stderr; ms\n*.* >stderr; msus"
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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 <stdio.h>
|
||||||
|
#include "zlog.h"
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = dzlog_init("test_default.conf", "my_cat");
|
||||||
|
if (rc) {
|
||||||
|
printf("init failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dzlog_info("hello, zlog");
|
||||||
|
|
||||||
|
zlog_fini();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
[rules]
|
||||||
|
my_cat.* >stdout
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the zlog Library.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2018 by Teracom Telemática S/A
|
||||||
|
*
|
||||||
|
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "test_enabled.h"
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
zlog_category_t *zc;
|
||||||
|
|
||||||
|
rc = zlog_init("test_enabled.conf");
|
||||||
|
if (rc) {
|
||||||
|
printf("init failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
zc = zlog_get_category("my_cat");
|
||||||
|
if (!zc) {
|
||||||
|
printf("get cat fail\n");
|
||||||
|
zlog_fini();
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zlog_trace_enabled(zc)) {
|
||||||
|
/* do something heavy to collect data */
|
||||||
|
zlog_trace(zc, "hello, zlog - trace");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zlog_debug_enabled(zc)) {
|
||||||
|
/* do something heavy to collect data */
|
||||||
|
zlog_debug(zc, "hello, zlog - debug");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zlog_info_enabled(zc)) {
|
||||||
|
/* do something heavy to collect data */
|
||||||
|
zlog_info(zc, "hello, zlog - info");
|
||||||
|
}
|
||||||
|
|
||||||
|
zlog_fini();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
[global]
|
||||||
|
default format = "%V %v %m%n"
|
||||||
|
[levels]
|
||||||
|
TRACE = 30, LOG_DEBUG
|
||||||
|
[rules]
|
||||||
|
my_cat.TRACE >stdout;
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the zlog Library.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2018 by Teracom Telemática S/A
|
||||||
|
*
|
||||||
|
* The zlog Library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* The zlog Library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with the zlog Library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __test_level_h
|
||||||
|
#define __test_level_h
|
||||||
|
|
||||||
|
#include "zlog.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ZLOG_LEVEL_TRACE = 30,
|
||||||
|
/* must equals conf file setting */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define zlog_trace(cat, format, args...) \
|
||||||
|
zlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
|
||||||
|
ZLOG_LEVEL_TRACE, format, ##args)
|
||||||
|
|
||||||
|
#define zlog_trace_enabled(cat) zlog_level_enabled(cat, ZLOG_LEVEL_TRACE)
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* 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 <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "zc_profile.c"
|
||||||
|
#include "zc_hashtable.h"
|
||||||
|
#include "zc_hashtable.c"
|
||||||
|
|
||||||
|
void myfree(void *kv)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
zc_hashtable_t *a_table;
|
||||||
|
zc_hashtable_entry_t *a_entry;
|
||||||
|
|
||||||
|
a_table = zc_hashtable_new(20,
|
||||||
|
zc_hashtable_str_hash,
|
||||||
|
zc_hashtable_str_equal,
|
||||||
|
myfree, myfree);
|
||||||
|
|
||||||
|
zc_hashtable_put(a_table, "aaa", "bnbb");
|
||||||
|
zc_hashtable_put(a_table, "bbb", "bnbb");
|
||||||
|
zc_hashtable_put(a_table, "ccc", "bnbb");
|
||||||
|
|
||||||
|
zc_hashtable_put(a_table, "aaa", "123");
|
||||||
|
|
||||||
|
zc_hashtable_foreach(a_table, a_entry) {
|
||||||
|
printf("k[%s],v[%s]\n", (char*)a_entry->key, (char*)a_entry->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("getv[%s]\n", (char*)zc_hashtable_get(a_table, "ccc"));
|
||||||
|
|
||||||
|
zc_hashtable_remove(a_table, "ccc");
|
||||||
|
|
||||||
|
zc_hashtable_foreach(a_table, a_entry) {
|
||||||
|
printf("k[%s],v[%s]\n", (char*)a_entry->key, (char*)a_entry->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
zc_hashtable_remove(a_table, NULL);
|
||||||
|
zc_hashtable_del(NULL);
|
||||||
|
|
||||||
|
zc_hashtable_del(a_table);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* 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 <stdio.h>
|
||||||
|
#include "zlog.h"
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
zlog_category_t *zc;
|
||||||
|
|
||||||
|
rc = zlog_init("test_hello.conf");
|
||||||
|
if (rc) {
|
||||||
|
printf("init failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
zc = zlog_get_category("my_cat");
|
||||||
|
if (!zc) {
|
||||||
|
printf("get cat fail\n");
|
||||||
|
zlog_fini();
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
zlog_info(zc, "hello, zlog");
|
||||||
|
|
||||||
|
zlog_fini();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
[formats]
|
||||||
|
simple = "%d.%ms %m%n"
|
||||||
|
simple2 = "%d.%us %m%n"
|
||||||
|
[rules]
|
||||||
|
my_cat.* >stderr;
|
||||||
|
my_cat.* >stdout;simple
|
||||||
|
my_cat.* >stdout;simple2
|
||||||
@ -0,0 +1,112 @@
|
|||||||
|
/*
|
||||||
|
* 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 <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "zlog.h"
|
||||||
|
#include "stdlib.h"
|
||||||
|
|
||||||
|
static int ReadTotalFile( FILE * fp , char ** ptr , long * len )
|
||||||
|
{
|
||||||
|
long fileLen ;
|
||||||
|
int nret ;
|
||||||
|
char * pStart ;
|
||||||
|
|
||||||
|
*ptr = NULL;
|
||||||
|
|
||||||
|
nret = fseek( fp , 0L , SEEK_END );
|
||||||
|
if( nret )
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileLen = ftell( fp );
|
||||||
|
if( fileLen < 0 )
|
||||||
|
{
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ( pStart = calloc(1, fileLen+1) ) == NULL )
|
||||||
|
{
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
nret = fseek( fp , 0L , SEEK_SET );
|
||||||
|
if( nret )
|
||||||
|
{
|
||||||
|
free( pStart );
|
||||||
|
return -4;
|
||||||
|
}
|
||||||
|
|
||||||
|
nret = fread( pStart , fileLen , 1 , fp );
|
||||||
|
if( ferror( fp ) )
|
||||||
|
{
|
||||||
|
free( pStart );
|
||||||
|
return -5;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ptr = pStart;
|
||||||
|
*len = fileLen;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
FILE *fp;
|
||||||
|
char *dmp;
|
||||||
|
long dmp_len = 0;
|
||||||
|
int ntimes;
|
||||||
|
|
||||||
|
if (argc != 3) {
|
||||||
|
printf("useage: test_hex [file] [ntimes]\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
fp = fopen(argv[1], "r");
|
||||||
|
if (!fp) {
|
||||||
|
printf("fopen[%s] fail\n", argv[1]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ntimes = atoi(argv[2]);
|
||||||
|
|
||||||
|
zlog_category_t *zc;
|
||||||
|
|
||||||
|
rc = zlog_init("test_hex.conf");
|
||||||
|
if (rc) {
|
||||||
|
printf("init failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
zc = zlog_get_category("my_cat");
|
||||||
|
if (!zc) {
|
||||||
|
printf("get category failed\n");
|
||||||
|
zlog_fini();
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
rc = ReadTotalFile(fp, &dmp, &dmp_len);
|
||||||
|
|
||||||
|
while(ntimes--) hzlog_debug(zc, dmp, dmp_len);
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
free(dmp);
|
||||||
|
|
||||||
|
zlog_fini();
|
||||||
|
printf("hex log end\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
[rules]
|
||||||
|
*.* "hex.log";
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
[global]
|
||||||
|
buffer min = 2048
|
||||||
|
buffer max = 4096
|
||||||
|
default format = "%V %m%n"
|
||||||
|
[levels]
|
||||||
|
TEST = 40, LOG_INFO
|
||||||
|
|
||||||
|
|
||||||
|
[formats]
|
||||||
|
simple = "%m%n"
|
||||||
|
[rules]
|
||||||
|
my_cat.* >stderr;
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* 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 <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "zlog.h"
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
zlog_category_t *zc;
|
||||||
|
|
||||||
|
rc = zlog_init("test_init.conf");
|
||||||
|
if (rc) {
|
||||||
|
printf("init fail");
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
zc = zlog_get_category("my_cat");
|
||||||
|
if (!zc) {
|
||||||
|
printf("zlog_get_category fail\n");
|
||||||
|
zlog_fini();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
zlog_info(zc, "before update");
|
||||||
|
sleep(1);
|
||||||
|
rc = zlog_reload("test_init.2.conf");
|
||||||
|
if (rc) {
|
||||||
|
printf("update fail\n");
|
||||||
|
}
|
||||||
|
zlog_info(zc, "after update");
|
||||||
|
zlog_profile();
|
||||||
|
zlog_fini();
|
||||||
|
|
||||||
|
sleep(1);
|
||||||
|
zlog_init("test_init.conf");
|
||||||
|
zc = zlog_get_category("my_cat");
|
||||||
|
if (!zc) {
|
||||||
|
printf("zlog_get_category fail\n");
|
||||||
|
zlog_fini();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
zlog_info(zc, "init again");
|
||||||
|
zlog_fini();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
[ global ]
|
||||||
|
strict init = true
|
||||||
|
buffer min = 1024
|
||||||
|
buffer max = 2MB
|
||||||
|
rotate lock file= /tmp/zlog.lock
|
||||||
|
|
||||||
|
[ rules ]
|
||||||
|
my_cat.* >stderr;
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
[global]
|
||||||
|
strict init = true
|
||||||
|
buffer min = 100
|
||||||
|
buffer max = 200
|
||||||
|
default format = "%m%n"
|
||||||
|
|
||||||
|
[rules ]
|
||||||
|
*.* >stdout;
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* 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 <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "zlog.h"
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
int k;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (argc != 2) {
|
||||||
|
printf("test_leak ntime\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = zlog_init("test_leak.conf");
|
||||||
|
|
||||||
|
k = atoi(argv[1]);
|
||||||
|
while (k-- > 0) {
|
||||||
|
i = rand();
|
||||||
|
switch (i % 4) {
|
||||||
|
case 0:
|
||||||
|
rc = dzlog_init("test_leak.conf", "xxx");
|
||||||
|
dzlog_info("init, rc=[%d]", rc);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
rc = zlog_reload(NULL);
|
||||||
|
dzlog_info("reload null, rc=[%d]", rc);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
rc = zlog_reload("test_leak.2.conf");
|
||||||
|
dzlog_info("reload 2, rc=[%d]", rc);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
zlog_fini();
|
||||||
|
printf("fini\n");
|
||||||
|
// printf("zlog_finish\tj=[%d], rc=[%d]\n", j, rc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zlog_fini();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
[global]
|
||||||
|
strict init = true
|
||||||
|
buffer min = 2048
|
||||||
|
buffer max = 4096
|
||||||
|
rotate lock file = /tmp/zlog.lock
|
||||||
|
default format = "%d(%F %T).%ms %-6V (%c:%F:%L) - %m%n"
|
||||||
|
|
||||||
|
[ levels ]
|
||||||
|
TEST = 40, LOG_INFO
|
||||||
|
|
||||||
|
[rules ]
|
||||||
|
*.* >stderr;
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue