|
|
#LyX 2.3 created this file. For more info see http://www.lyx.org/
|
|
|
\lyxformat 544
|
|
|
\begin_document
|
|
|
\begin_header
|
|
|
\save_transient_properties true
|
|
|
\origin unavailable
|
|
|
\textclass extbook
|
|
|
\use_default_options true
|
|
|
\begin_modules
|
|
|
theorems-ams
|
|
|
eqs-within-sections
|
|
|
figs-within-sections
|
|
|
\end_modules
|
|
|
\maintain_unincluded_children false
|
|
|
\language english
|
|
|
\language_package default
|
|
|
\inputencoding auto
|
|
|
\fontencoding global
|
|
|
\font_roman "default" "default"
|
|
|
\font_sans "default" "default"
|
|
|
\font_typewriter "default" "default"
|
|
|
\font_math "auto" "auto"
|
|
|
\font_default_family default
|
|
|
\use_non_tex_fonts false
|
|
|
\font_sc false
|
|
|
\font_osf false
|
|
|
\font_sf_scale 100 100
|
|
|
\font_tt_scale 100 100
|
|
|
\use_microtype false
|
|
|
\use_dash_ligatures true
|
|
|
\graphics default
|
|
|
\default_output_format default
|
|
|
\output_sync 0
|
|
|
\bibtex_command default
|
|
|
\index_command default
|
|
|
\paperfontsize 12
|
|
|
\spacing single
|
|
|
\use_hyperref true
|
|
|
\pdf_title "zlog Users Guide EN"
|
|
|
\pdf_author "Hardy Simpson"
|
|
|
\pdf_bookmarks true
|
|
|
\pdf_bookmarksnumbered true
|
|
|
\pdf_bookmarksopen true
|
|
|
\pdf_bookmarksopenlevel 1
|
|
|
\pdf_breaklinks true
|
|
|
\pdf_pdfborder true
|
|
|
\pdf_colorlinks true
|
|
|
\pdf_backref false
|
|
|
\pdf_pdfusetitle true
|
|
|
\papersize default
|
|
|
\use_geometry true
|
|
|
\use_package amsmath 1
|
|
|
\use_package amssymb 1
|
|
|
\use_package cancel 1
|
|
|
\use_package esint 1
|
|
|
\use_package mathdots 1
|
|
|
\use_package mathtools 1
|
|
|
\use_package mhchem 1
|
|
|
\use_package stackrel 1
|
|
|
\use_package stmaryrd 1
|
|
|
\use_package undertilde 1
|
|
|
\cite_engine basic
|
|
|
\cite_engine_type default
|
|
|
\biblio_style plain
|
|
|
\use_bibtopic false
|
|
|
\use_indices false
|
|
|
\paperorientation portrait
|
|
|
\suppress_date false
|
|
|
\justification true
|
|
|
\use_refstyle 0
|
|
|
\use_minted 0
|
|
|
\index 索引
|
|
|
\shortcut idx
|
|
|
\color #008000
|
|
|
\end_index
|
|
|
\secnumdepth 3
|
|
|
\tocdepth 3
|
|
|
\paragraph_separation indent
|
|
|
\paragraph_indentation default
|
|
|
\is_math_indent 0
|
|
|
\math_numbering_side default
|
|
|
\quotes_style english
|
|
|
\dynamic_quotes 0
|
|
|
\papercolumns 1
|
|
|
\papersides 1
|
|
|
\paperpagestyle default
|
|
|
\tracking_changes false
|
|
|
\output_changes false
|
|
|
\html_math_output 0
|
|
|
\html_css_as_file 0
|
|
|
\html_be_strict false
|
|
|
\end_header
|
|
|
|
|
|
\begin_body
|
|
|
|
|
|
\begin_layout Title
|
|
|
zlog
|
|
|
\begin_inset Foot
|
|
|
status collapsed
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
A single spark can start a prairie fire – Mao Zedong
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
User's Guide
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Author
|
|
|
Hardy Simpson
|
|
|
\begin_inset Foot
|
|
|
status collapsed
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
This Guide is for zlog v1.2.*
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\begin_inset Foot
|
|
|
status collapsed
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
If you have comments or error corrections, post
|
|
|
\begin_inset CommandInset href
|
|
|
LatexCommand href
|
|
|
name "a issue"
|
|
|
target "https://github.com/HardySimpson/zlog/issues/new"
|
|
|
literal "false"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
on github, or write email to
|
|
|
\begin_inset CommandInset href
|
|
|
LatexCommand href
|
|
|
name "HardySimpson1984@gmail.com"
|
|
|
target "HardySimpson1984@gmail.com"
|
|
|
type "mailto:"
|
|
|
literal "false"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
\begin_inset CommandInset toc
|
|
|
LatexCommand tableofcontents
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Chapter
|
|
|
What is zlog?
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
zlog is a reliable, high-performance, thread safe, flexible, clear-model,
|
|
|
pure C logging library.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Actually, in the C world there was NO good logging library for applications
|
|
|
like logback in java or log4cxx in c++.
|
|
|
printf can work, but can not be redirected easily nor be reformatted.
|
|
|
syslog is slow and is designed for system use.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
So I wrote zlog.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
It is faster, safer and more powerful than log4c.
|
|
|
So it can be widely used.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
zlog has these features:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Itemize
|
|
|
syslog model, better than log4j model
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Itemize
|
|
|
log format customization
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Itemize
|
|
|
multiple output, include static file path, dynamic file path, stdout, stderr,
|
|
|
syslog, user-defined ouput
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Itemize
|
|
|
runtime with manual or automatic refresh of configuration (done safely)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Itemize
|
|
|
high-performance, 250'000 logs/second on my laptop, about 1000 times faster
|
|
|
than syslog(3) with rsyslogd
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Itemize
|
|
|
user-defined log level
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Itemize
|
|
|
safely rotate log file under multiple-process or multiple-thread conditions
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Itemize
|
|
|
accurate to microseconds
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Itemize
|
|
|
dzlog, a default category log API for easy use
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Itemize
|
|
|
MDC, a log4j style key-value map
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Itemize
|
|
|
self debuggable, can output zlog's self debug and error log at runtime
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Itemize
|
|
|
Does not depend on any other 3rd party library, just base on POSIX system
|
|
|
(including pthread) and a C99 compliant vsnprintf.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Links:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Homepage:
|
|
|
\begin_inset CommandInset href
|
|
|
LatexCommand href
|
|
|
name "http://hardysimpson.github.com/zlog"
|
|
|
target "http://hardysimpson.github.com/zlog"
|
|
|
literal "false"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Downloads:
|
|
|
\begin_inset CommandInset href
|
|
|
LatexCommand href
|
|
|
target "https://github.com/HardySimpson/zlog/releases"
|
|
|
literal "false"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Author's Email:
|
|
|
\begin_inset CommandInset href
|
|
|
LatexCommand href
|
|
|
name "HardySimpson1984@gmail.com"
|
|
|
target "HardySimpson1984@gmail.com"
|
|
|
type "mailto:"
|
|
|
literal "false"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Section
|
|
|
Compatibility Notes
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Enumerate
|
|
|
zlog is based on POSIX-compatible systems.
|
|
|
I have just GNU/linux and AIX environments to compile, test and run zlog.
|
|
|
Still, I think zlog will work well on FreeBSD, NetBSD, OpenBSD, OpenSolaris,
|
|
|
Mac OS X etc.
|
|
|
Test runs of zlog on any system are welcome.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Enumerate
|
|
|
zlog uses a feature of C99 compliant vsnprintf.
|
|
|
That is, if the buffer size of destination is not long enough, vsnprintf
|
|
|
will return the number of characters (not including the trailing '
|
|
|
\backslash
|
|
|
0') which would have been written to the final string if enough space had
|
|
|
been available.
|
|
|
If the vsnprintf on your system does not work like that, zlog can not know
|
|
|
the right buffer size when a single log is longer than the buffer.
|
|
|
Fortunately, glibc 2.1, libc on AIX, and libc on freebsd work correctly,
|
|
|
while glibc 2.0 does not.
|
|
|
In this case, user should crack zlog himself with a C99 compliant vsnprintf.
|
|
|
I suggest
|
|
|
\begin_inset CommandInset href
|
|
|
LatexCommand href
|
|
|
name "ctrio"
|
|
|
target "http://sourceforge.net/projects/ctrio/"
|
|
|
literal "false"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
, or
|
|
|
\begin_inset CommandInset href
|
|
|
LatexCommand href
|
|
|
name "C99-snprintf"
|
|
|
target "http://www.jhweiss.de/software/snprintf.html"
|
|
|
literal "false"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
.
|
|
|
The file buf.c should be cracked, good luck!
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Enumerate
|
|
|
Some people offer versions of zlog for other platforms.
|
|
|
Thanks!
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Standard
|
|
|
auto tools version:
|
|
|
\begin_inset CommandInset href
|
|
|
LatexCommand href
|
|
|
target "https://github.com/bmanojlovic/zlog"
|
|
|
literal "false"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
cmake verion:
|
|
|
\begin_inset CommandInset href
|
|
|
LatexCommand href
|
|
|
target "https://github.com/lisongmin/zlog"
|
|
|
literal "false"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
windows version:
|
|
|
\begin_inset CommandInset href
|
|
|
LatexCommand href
|
|
|
target "https://github.com/lopsd07/WinZlog"
|
|
|
literal "false"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Section
|
|
|
zlog 1.2 Release Notes
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Enumerate
|
|
|
zlog 1.2 provides these features:
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Enumerate
|
|
|
support for pipeline.
|
|
|
Now zlog can send ouput log through programs like cronolog
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Enumerate
|
|
|
Full rotation support, see
|
|
|
\begin_inset CommandInset ref
|
|
|
LatexCommand ref
|
|
|
reference "sec:Rotation"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Enumerate
|
|
|
Other code compatible details, bug fixes.
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Enumerate
|
|
|
zlog 1.2 is binary compatible with zlog 1.0.
|
|
|
The differences are:
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Enumerate
|
|
|
All zlog macros like ZLOG_INFO are shifted to lowercase versions, zlog_info.
|
|
|
This big change is because I think it is easier for people to type.
|
|
|
If you are using a previous version of zlog, please use a script to substitute
|
|
|
all macros, and re-compile your program.
|
|
|
Here is an example:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
sed -i -e 's/
|
|
|
\backslash
|
|
|
b
|
|
|
\backslash
|
|
|
w*ZLOG
|
|
|
\backslash
|
|
|
w*
|
|
|
\backslash
|
|
|
b/
|
|
|
\backslash
|
|
|
L&
|
|
|
\backslash
|
|
|
E/g' aa.c
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Enumerate
|
|
|
Auto tools compile is abandoned.
|
|
|
Auto tools is ugly so I dropped it.
|
|
|
A simple makefile is in use, which requires gcc and gnu make.
|
|
|
If this makefile does not work in your environment, you will need to write
|
|
|
a suitable makefile for yourself.
|
|
|
It should be quite easy for a geek.
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Chapter
|
|
|
What zlog is not
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
The goal of zlog is to be a simple, fast log library for applications.
|
|
|
It does not support output like sending the log to another machine through
|
|
|
the net or saving it to database.
|
|
|
It will not parse content of log and filter them.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
The reason is obvious: the library is called by an application, so all time
|
|
|
taken by the log library is part of the application's time.
|
|
|
And database inserting or log content parsing takes a long time.
|
|
|
These will slow down the application.
|
|
|
These operation should be done in a different process or on a different
|
|
|
machine.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
If you want all these features, I recommend rsyslog, zLogFabric, Logstash.
|
|
|
These have independent processes to receive logs from another process or
|
|
|
machine, and to parse and store logs.
|
|
|
These functions are separated from the user application.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Now
|
|
|
\begin_inset CommandInset ref
|
|
|
LatexCommand ref
|
|
|
reference "sec:User-defined-Output"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
is supported by zlog.
|
|
|
Just one output function need to be implemented: to transfer the log to
|
|
|
the other process or machine.
|
|
|
The work of category matching and log generating is left with the zlog
|
|
|
library.
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
One possibility is to write a zlog-redis client.
|
|
|
It send logs to redis on local or remote machines by user defined output.
|
|
|
Then other processes can read logs from redis and write to disk.
|
|
|
What do you think about this idea? I will be happy to discuss it with you.
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Chapter
|
|
|
Hello World
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Section
|
|
|
Build and Installation zlog
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Download:
|
|
|
\begin_inset CommandInset href
|
|
|
LatexCommand href
|
|
|
target "https://github.com/HardySimpson/zlog/archive/latest-stable.tar.gz"
|
|
|
literal "false"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ tar -zxvf zlog-latest-stable.tar.gz
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ cd zlog-latest-stable/
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ make
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ sudo make install
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
or
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ sudo make PREFIX=/usr/local/ install
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
PREFIX indicates where zlog is installed.
|
|
|
After installation, change system settings to make sure your program can
|
|
|
find the zlog library
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ sudo vi /etc/ld.so.conf
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
/usr/local/lib
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ sudo ldconfig
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Before running a real program, make sure libzlog.so is in the directory where
|
|
|
the system's dynamic lib loader can find it.
|
|
|
The commands mentioned above are for linux.
|
|
|
Other systems will need a similar set of actions.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Itemize
|
|
|
Beside the normal make, these are also available:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ make 32bit # 32bit version on 64bit machine, libc6-dev-i386 is needed
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ make noopt # without gcc optimization
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ make doc # lyx and hevea is needed
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ make test # test code, which is also good example for zlog
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Itemize
|
|
|
makefile of zlog is written in gnu make style.
|
|
|
So if your platform is not linux, install a gnu make and gcc before trying
|
|
|
to build zlog.
|
|
|
Another way is to write a makefile in your platform's make style.
|
|
|
This should be quite easy as zlog is not complicated.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Section
|
|
|
Call and Link zlog in User's application
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
To use zlog, add one line to the source c file or cpp file:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
#include "zlog.h"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
zlog needs the pthread library.
|
|
|
The link command is:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ cc -c -o app.o app.c -I/usr/local/include
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
# -I[where zlog.h is put]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ cc -o app app.o -L/usr/local/lib -lzlog -lpthread
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
# -L[where libzlog.so]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Section
|
|
|
Hello World Example
|
|
|
\begin_inset CommandInset label
|
|
|
LatexCommand label
|
|
|
name "sec:Hello-World-Example"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
This example can be found in $(top_builddir)/test/test_hello.c, test_hello.conf
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Enumerate
|
|
|
Write a new c source file:
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
$ vi test_hello.c
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
#include <stdio.h>
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
#include "zlog.h"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
int main(int argc, char** argv)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
{
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
int rc;
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_category_t *c;
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
rc = zlog_init("test_hello.conf");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
if (rc) {
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
printf("init failed
|
|
|
\backslash
|
|
|
n");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
return -1;
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
}
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
c = zlog_get_category("my_cat");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
if (!c) {
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
printf("get cat fail
|
|
|
\backslash
|
|
|
n");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_fini();
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
return -2;
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
}
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_info(c, "hello, zlog");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_fini();
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
return 0;
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
}
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Enumerate
|
|
|
Write a configuration file in the same path as test_hello.c:
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
$ vi test_hello.conf
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
[formats]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
simple = "%m%n"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
[rules]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
my_cat.DEBUG >stdout; simple
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Enumerate
|
|
|
Compile and run it:
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
$ cc -c -o test_hello.o test_hello.c -I/usr/local/include
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ cc -o test_hello test_hello.o -L/usr/local/lib -lzlog
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ ./test_hello
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
hello, zlog
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Section
|
|
|
Simpler Hello World Example
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
This example can be found in $(top_builddir)/test/test_default.c, test_default.con
|
|
|
f.
|
|
|
The source code is
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
#include <stdio.h>
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
#include "zlog.h"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
int main(int argc, char** argv)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
{
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
int rc;
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
rc = dzlog_init("test_default.conf", "my_cat");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
if (rc) {
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
printf("init failed
|
|
|
\backslash
|
|
|
n");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
return -1;
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
}
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
dzlog_info("hello, zlog");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_fini();
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
return 0;
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
}
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
The configure file test_default.conf is the same as test_hello.conf, and the
|
|
|
output of test_default is the same as that of test_hello.
|
|
|
The difference is that test_default uses the dzlog API, which has a default
|
|
|
|
|
|
\emph on
|
|
|
zlog_category_t
|
|
|
\emph default
|
|
|
inside and is easier to use.
|
|
|
See
|
|
|
\begin_inset CommandInset ref
|
|
|
LatexCommand ref
|
|
|
reference "sec:dzlog-API"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
for more details.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Chapter
|
|
|
Syslog model
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Section
|
|
|
Category, Rule and Format
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
In zlog, there are 3 important concepts: category, rule and format.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Category specifies 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.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Format describes detail log patterns, such as: with or without time stamp,
|
|
|
source file, source line.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Rule consists 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.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
So when this sentence in the source file is executed:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_category_t *c;
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
c = zlog_get_category("my_cat");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_info(c, "hello, zlog");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
zlog library uses the category name "my_cat" to match one rule in the configurat
|
|
|
ion file.
|
|
|
That is
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
[rules]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
my_cat.DEBUG >stdout; simple
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Then the library will check if level is correct to decide whether the log
|
|
|
will be output or not.
|
|
|
As INFO>=DEBUG the log will be output, and as the rule says, it will be
|
|
|
sent to stdout (standard output) in the format of simple, which is described
|
|
|
as
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
[formats]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
simple = "%m%n"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Lastly, zlog will show the zlog_info() content on the screen
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
hello, zlog
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
That's the whole story.
|
|
|
The only thing a user need to do is to write the messages.
|
|
|
Where the log will be output, or in which format, is done by zlog library.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Section
|
|
|
Differences between syslog model and log4j model
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Does zLog have anything to do with syslog? Until now, the model is more
|
|
|
like log4j.
|
|
|
As in log4j, there are concepts of logger, appender and layout.
|
|
|
The difference is that in log4j, each logger in source code must correspond
|
|
|
to one logger in the configuration file and has just one definite level.
|
|
|
One-to-one relationship is the only choice for log4j, log4cxx, log4cpp,
|
|
|
log4cplus log4net and etc...
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
But the log4j model is NOT flexible, they invent filters to make up for
|
|
|
it, and that make things more worse.
|
|
|
So let's get back to syslog model, which has an excellent design.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Continuing our example from the last section, if the zlog configuration
|
|
|
file has 2 rules:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
[rules]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
my_cat.DEBUG >stdout; simple
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
my_cat.INFO >stdout;
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Then they will generate 2 log outputs to stdout:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
hello, zlog
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
2012-05-29 10:41:36 INFO [11288:test_hello.c:41] hello, zlog
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
You see that one category in the source code corresponds to two rules in
|
|
|
the configuration file.
|
|
|
Maybe log4j's user will say, "That's good, but 2 appender for one logger
|
|
|
will do the same thing".
|
|
|
So, let's see the next example of configure file:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
[rules]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
my_cat.WARN "/var/log/aa.log"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
my_cat.DEBUG "/var/log/bb.log"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
And the source code is:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_info(c, "info, zlog");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_debug(c, "debug, zlog");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Then, in aa.log, there is just one log
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
2012-05-29 10:41:36 INFO [11288:test_hello.c:41] info, zlog
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
But in bb.log, there will be two
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
2012-05-29 10:41:36 INFO [11288:test_hello.c:41] info, zlog
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
2012-05-29 10:41:36 DEBUG [11288:test_hello.c:42] debug, zlog
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
From this example, you see the difference.
|
|
|
Log4j can not do it easily.
|
|
|
In zlog, one category may correspond to mutiple rules, and rules can have
|
|
|
different level, output, and format combinations.
|
|
|
The user has an easy, clear way to filter and multi-ouput all logs on demand.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Section
|
|
|
Expand syslog model
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
You can see that category in zlog is more like facility in syslog.
|
|
|
Unfortunately, facility in sylog is an int, and the value of facility must
|
|
|
be chosen from a limited system-defined range.
|
|
|
zlog does better, making it a string variable.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
In syslog, there is a special wildcard "*", which matches all facilities.
|
|
|
It does the same thing in zlog.
|
|
|
"*" matches all categories.
|
|
|
That is a convenient way to make all errors generated by multiple components
|
|
|
in your system redirect to one log file.
|
|
|
Just write in the configuration file like this:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
[rules]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
*.error "/var/log/error.log"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
A unique feature of zlog is sub-category matching.
|
|
|
If your source code has:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
c = zlog_get_category("my_cat");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
And the configuration file has rules :
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
[rules]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
my_cat.* "/var/log/my_cat.log"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
my_.NOTICE "/var/log/my.log"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
These 2 rules match category "c" with the name "my_cat".
|
|
|
The wildcard "_" is the way to represent a super category.
|
|
|
"my_" is a super category for "my_cat" and "my_dog".
|
|
|
There is also another wildcard "!".
|
|
|
See
|
|
|
\begin_inset CommandInset ref
|
|
|
LatexCommand ref
|
|
|
reference "subsec:Category-Matching"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
for more detail.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Chapter
|
|
|
Configure File
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Most actions of zlog library are dependent upon the configuration file:
|
|
|
where to output the log, how to rotate the log files, how to format the
|
|
|
output, etc.
|
|
|
The configuration file uses a domain specific language to control the library
|
|
|
actions.
|
|
|
Here is an example of zlog.conf:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
# comments
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
[global]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
strict init = true
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
reload conf period = 1M
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
buffer min = 1024
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
buffer max = 2MB
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
rotate lock file = /tmp/zlog.lock
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
default format = "%d.%ms %-6V (%c:%F:%L) - %m%n"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
file perms = 600
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
fsync period = 1K
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
[levels]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
TRACE = 10
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
CRIT = 130, LOG_CRIT
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
[formats]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
simple = "%m%n"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
normal = "%d(%F %T) %m%n"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
[rules]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
default.* >stdout; simple
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
*.* "%12.2E(HOME)/log/%c.log", 1MB*12; simple
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
my_.INFO >stderr;
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
my_cat.!ERROR "/var/log/aa.log"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
my_dog.=DEBUG >syslog, LOG_LOCAL0; simple
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
my_mice.* $user_define;
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
[] means a section's beginning, and the order of sections is fixed, using
|
|
|
the sequence global-levels-formats-rules.
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Note on units: when memory size or large number is needed, it is possible
|
|
|
to specify it in the usual form of 1k 5GB 4M and so forth:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
# 1k => 1000 bytes
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
# 1kb => 1024 bytes
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
# 1m => 1000000 bytes
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
# 1mb => 1024*1024 bytes
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
# 1g => 1000000000 bytes
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
# 1gb => 1024*1024*1024 byte
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
units are case insensitive so 1GB 1Gb 1gB are all the same.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Section
|
|
|
Global
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Global section begins with [global].
|
|
|
This section can be omitted.The syntax is
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
(key) = (value)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Itemize
|
|
|
strict init
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Standard
|
|
|
If "strict init = true
|
|
|
\begin_inset Quotes erd
|
|
|
\end_inset
|
|
|
|
|
|
, zlog_init() will check syntax of all formats and rules strictly, and any
|
|
|
error will cause zlog_init() to fail and return -1.
|
|
|
When "strict init = false
|
|
|
\begin_inset Quotes erd
|
|
|
\end_inset
|
|
|
|
|
|
, zlog_init() will ignore syntax errors for formats and rules.
|
|
|
The default is true.
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Itemize
|
|
|
reload conf period
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Standard
|
|
|
This parameter causes the zlog library to reload the configuration file
|
|
|
automatically after a period, which is measured by number of log times
|
|
|
per process.
|
|
|
When the number reaches the value, it calls zlog_reload() internally.
|
|
|
The number is reset to zero at the last zlog_reload() or zlog_init().
|
|
|
As zlog_reload() is atomic, if zlog_reload() fails, zlog still runs with
|
|
|
the current configuration.
|
|
|
So reloading automatically the configuration is safe.
|
|
|
The default is 0, which means never reload automatically.
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Itemize
|
|
|
buffer min
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Itemize
|
|
|
buffer max
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Standard
|
|
|
zlog allocates a log buffer in each thread.
|
|
|
"buffer min" indicates size of buffer malloc'ed at init time.
|
|
|
While logging, if one single log's content is longer than buffer size now,
|
|
|
zlog will expand buffer automatically until "buffer max".
|
|
|
Then, if the size is still longer than "buffer max", the log content will
|
|
|
be truncated.
|
|
|
If "buffer max" is 0, it means buffer size is unlimited, and each time
|
|
|
zlog will expand buffer by twice its size, until the process uses all available
|
|
|
memory.
|
|
|
The value of these 2 parameters can appended with unit KB, MB or GB suffix,
|
|
|
where 1024 equals 1KB.
|
|
|
As default, "buffer min" is 1K and "buffer max" is 2MB.
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Itemize
|
|
|
rotate lock file
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Standard
|
|
|
This specifies a lock file for rotating a log safely in multi-process situations.
|
|
|
zlog will open the file at zlog_init() with the permission of read-write.
|
|
|
The pseudo-code for rotating a log file is:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
write(log_file, a_log)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
if (log_file > 1M)
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
if (pthread_mutex_lock succ && fcntl_lock(lock_file) succ)
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
if (log_file > 1M) rotate(log_file);
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
fcntl_unlock(lock_file);
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
pthread_mutex_unlock;
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\end_deeper
|
|
|
\begin_layout Standard
|
|
|
mutex_lock is for multi-thread and fcntl_lock is for multi-process.
|
|
|
fcntl_lock is the POSIX advisory record locking.
|
|
|
See man 3 fcntl for details.
|
|
|
The lock is system-wide, and when a process dies unexpectedly, the operating
|
|
|
system releases all locks owned by the process.
|
|
|
That's why I chose fcntl lock for rotating log safely.
|
|
|
The process needs read-write permisson for lock_file to lock it.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
By default, rotate lock file = self.
|
|
|
This way, zlog does not create any lock file and sets the configuration
|
|
|
file as the lock file.
|
|
|
As fcntl is advisory, it does not really forbid programmers to change and
|
|
|
store the configuration file.
|
|
|
Generally speaking, one log file will not be rotated by processes run by
|
|
|
different operating system users, so using the configuration file as lock
|
|
|
file is safe.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
If you choose another path as lock file, for example, /tmp/zlog.lock, zlog
|
|
|
will create it at zlog_init().
|
|
|
Make sure your program has permission to create and read-write the file.
|
|
|
If processes run by different operating system users need to write and
|
|
|
rotate the same log file, make sure that each program has permission to
|
|
|
create and read-write the same lock file.
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Itemize
|
|
|
default format
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Standard
|
|
|
This parameter is used by rules without format specified.
|
|
|
The default is
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
"%d %V [%p:%F:%L] %m%n"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
It will yield output like this:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
2012-02-14 17:03:12 INFO [3758:test_hello.c:39] hello, zlog
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Itemize
|
|
|
file perms
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Standard
|
|
|
This specifies all log file permissions when they are created.
|
|
|
Note that it is affected by user's umask.
|
|
|
The final file permission will be "file perms" & ~umask.
|
|
|
The default is 600, which just allows user read and write.
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Itemize
|
|
|
fsync period
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Standard
|
|
|
After a number of log times per rule (to file only), zlog will call fsync(3)
|
|
|
after write() to tell the Operating System to write data to disk immediately
|
|
|
from any internal system buffers.
|
|
|
The number is incremented by each rule and will be reset to 0 after zlog_reload
|
|
|
().
|
|
|
Note that when the file's path is generated dynamically or is rotated,
|
|
|
zlog does not guarantee fsync() touch all files.
|
|
|
It just does fsync() against the file descriptors that have have seen write()
|
|
|
prior to the boundary time.
|
|
|
It offers a balance between speed and data safety.
|
|
|
An example:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ time ./test_press_zlog 1 10 100000
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
real 0m1.806s
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
user 0m3.060s
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
sys 0m0.270s
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ wc -l press.log
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
1000000 press.log
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ time ./test_press_zlog 1 10 100000 #fsync period = 1K
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
real 0m41.995s
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
user 0m7.920s
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
sys 0m0.990s
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ time ./test_press_zlog 1 10 100000 #fsync period = 10K
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
real 0m6.856s
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
user 0m4.360s
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
sys 0m0.550s
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
If you want extreme safety but do not care about speed, use synchronous
|
|
|
file I/O, see
|
|
|
\begin_inset CommandInset ref
|
|
|
LatexCommand ref
|
|
|
reference "ite:synchronous-I/O-file"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
.The defualt is 0, which means let the operating system flush the output
|
|
|
buffer when it wants.
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Section
|
|
|
Levels
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
This section begins with [levels] and allows the user to define application
|
|
|
levels.
|
|
|
You should match these values with user-defined macros in the source file.
|
|
|
This section can be omitted.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
The syntax is
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
(level string) = (level int), (syslog level, optional)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
level int should in [1,253], higher numbers mean more important.
|
|
|
syslog level is optional, if not set, use LOG_DEBUG
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
see
|
|
|
\begin_inset CommandInset ref
|
|
|
LatexCommand ref
|
|
|
reference "sec:User-defined-Level"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
for more details.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Section
|
|
|
Formats
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
This section begins with [formats], where the user can define preferred
|
|
|
log patterns.
|
|
|
The syntax is
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
(name) = "(actual formats)"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
It is easy to understand, (name) will be used in the next section [rules].
|
|
|
The format (name) consists of letters and digits plus underscore "_".
|
|
|
The (actual format) should be put in double quotes.
|
|
|
It can be built up with conversion patterns, as described below.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Section
|
|
|
Conversion pattern
|
|
|
\begin_inset CommandInset label
|
|
|
LatexCommand label
|
|
|
name "sec:Conversion-pattern"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
The conversion pattern is closely related to the conversion pattern of the
|
|
|
C printf function.
|
|
|
A conversion pattern is composed of literal text and format control expressions
|
|
|
called conversion specifiers.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Conversion pattern is used in both filepath of rule and pattern of format.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
You are free to insert any literal text within the conversion pattern.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Each conversion specifier starts with a percent sign (%) and is followed
|
|
|
by optional format modifiers and a conversion character.
|
|
|
The conversion character specifies the type of data, e.g.
|
|
|
category, level, date, thread id.
|
|
|
The format modifiers control such things as field width, padding, left
|
|
|
and right justification.
|
|
|
The following is a simple example.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Let the conversion pattern be
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
"%d(%m-%d %T) %-5V [%p:%F:%L] %m%n".
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Then the statement
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_info(c, "hello, zlog");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
would yield the output
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
02-14 17:17:42 INFO [4935:test_hello.c:39] hello, zlog
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Note that there is no explicit separator between text and conversion specifiers.
|
|
|
The pattern parser knows when it has reached the end of a conversion specifier
|
|
|
when it reads a conversion character.
|
|
|
In the example above the conversion specifier %-5p means the level of the
|
|
|
logging event should be left justified to a width of five characters.
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Subsection
|
|
|
Conversion Characters
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
The recognized conversion characters are
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
\begin_inset Tabular
|
|
|
<lyxtabular version="3" rows="22" columns="3">
|
|
|
<features islongtable="true" longtabularalignment="center">
|
|
|
<column alignment="center" valignment="top" width="10text%">
|
|
|
<column alignment="left" valignment="top" width="50text%">
|
|
|
<column alignment="left" valignment="top" width="40text%">
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
conversion char
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
effect
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
example
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%c
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Used to output the category of the logging event.
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
aa_bb
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%d()
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Used to output the date of the logging event.
|
|
|
The date conversion specifier may be followed by a date format specifier
|
|
|
enclosed between parentheses.
|
|
|
For example, %d(%F) or %d(%m-%d %T).
|
|
|
If no date format specifier is given then %d(%F %T) format is assumed.
|
|
|
The date format specifier permits the same syntax as the strftime(2).
|
|
|
see
|
|
|
\begin_inset CommandInset ref
|
|
|
LatexCommand ref
|
|
|
reference "subsec:Time-Character"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
for more detail.
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%d(%F) 2011-12-01
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%d(%m-%d %T) 12-01 17:17:42
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%d(%T.ms) 17:17:42.035
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%d 2012-02-14 17:03:12
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%d() 2012-02-14 17:03:12
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%E()
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Value of environment variables
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%E(LOGNAME) simpson
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%ms
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The millisecond, 3-digit integer string
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
comes from gettimeofday(2)
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
013
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%us
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The microsecond, 6-digit integer string
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
comes from gettimeofday(2)
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
002323
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%F
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Used to output the file name where the logging request was issued.
|
|
|
The file name comes from __FILE__ macro.
|
|
|
Some compilers supply __FILE__ as the absolute path.
|
|
|
Use %f to strip path and keep the file name.
|
|
|
Some compilers have an option to control this feature.
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
test_hello.c
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
or, under some compiler
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
/home/zlog/src/test/test_hello.c
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%f
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Used to output the source file name, the string after the last '/' of $F.
|
|
|
It will cause a little performance loss in each log event.
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
test_hello.c
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%H
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Used to output the hostname of system, which is from gethostname(2)
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
zlog-dev
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%k
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Used to output the kernel thread id.
|
|
|
On Linux, that's the LWP using syscall(SYS_gettid) and on OSX, pthread_threadid
|
|
|
_np.
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
2136
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%L
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Used to output the line number from where the logging request was issued,
|
|
|
which comes from __LINE__ macro
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
135
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%m
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Used to output the application supplied message associated with the logging
|
|
|
event.
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
hello, zlog
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%M
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Used to output the MDC (mapped diagnostic context) associated with the thread
|
|
|
that generated the logging event.
|
|
|
The M conversion character must be followed by the key for the map placed
|
|
|
between parenthesis, as in %M(clientNumber) where clientNumber is the key.
|
|
|
The value in the MDC corresponding to the key will be output.See
|
|
|
\begin_inset CommandInset ref
|
|
|
LatexCommand ref
|
|
|
reference "sec:MDC"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
for more detail.
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%M(clientNumber) 12345
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%n
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Outputs unix newline character, zLog does not support the MS-Windows line
|
|
|
separator at this time.
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
|
|
\backslash
|
|
|
n
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%p
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Used to output the id of the process that generated the logging event, which
|
|
|
comes from getpid().
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
2134
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%U
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Used to output the function name where the logging request was issued.
|
|
|
It comes from __func__(C99) or __FUNCTION__(gcc) macro, with the support
|
|
|
of the compiler.
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
main
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%V
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Used to output the level of the logging event, uppercase.
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
INFO
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%v
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Used to output the level of the logging event, lowercase.
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
info
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%t
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Used to output the hexadecimal form of the thread id that generated the
|
|
|
logging event, which comes from pthread_self().
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
"%x",(unsigned int) pthread_t
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
ba01e700
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%T
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Equivalent to %t, but the long form
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
"%lu", (unsigned long) pthread_t
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
140633234859776
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%%
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
the sequence %% outputs a single percent sign.
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%[other char]
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
parsed as a wrong syntax, will cause zlog_init() fail
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
</lyxtabular>
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Subsection
|
|
|
Format Modifier
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
By default, the relevant information is output as-is.
|
|
|
However, with the aid of format modifiers it is possible to change the
|
|
|
minimum field width, the maximum field width, and justification.
|
|
|
It will cause a little performance loss in each log event.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
The optional format modifier is placed between the percent sign and the
|
|
|
conversion character.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
The first optional format modifier is the left justification flag which
|
|
|
is just the minus (-) character.
|
|
|
Then comes the optional minimum field width modifier.
|
|
|
This is a decimal constant that represents the minimum number of characters
|
|
|
to output.
|
|
|
If the data item requires fewer characters, it is padded on either the
|
|
|
left or the right until the minimum width is reached.
|
|
|
The default is to pad on the left (right justify) but you can specify right
|
|
|
padding with the left justification flag.
|
|
|
The padding character is space.
|
|
|
If the data item is larger than the minimum field width, the field is expanded
|
|
|
to accommodate the data.
|
|
|
The value is never truncated.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
This behavior can be changed using the maximum field width modifier which
|
|
|
is designated by a period followed by a decimal constant.
|
|
|
If the data item is longer than the maximum field, then the extra characters
|
|
|
are removed from the beginning of the data item and not from the end.
|
|
|
For example, if the maximum field width is eight and the data item is ten
|
|
|
characters long, then the last two characters of the data item are dropped.
|
|
|
This behavior equals the printf function in C where truncation is done
|
|
|
from the end.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Below are various format modifier examples for the category conversion specifier.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
\begin_inset Tabular
|
|
|
<lyxtabular version="3" rows="7" columns="5">
|
|
|
<features tabularvalignment="middle">
|
|
|
<column alignment="center" valignment="top" width="9text%">
|
|
|
<column alignment="center" valignment="top" width="8text%">
|
|
|
<column alignment="center" valignment="top" width="8text%">
|
|
|
<column alignment="center" valignment="top" width="8text%">
|
|
|
<column alignment="center" valignment="top" width="60text%">
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
format modifier
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
left justify
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
minimum width
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
maximum width
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
comment
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%20c
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
false
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
20
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
none
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Left pad with spaces if the category name is less than 20 characters long.
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%-20c
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
true
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
20
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
none
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Right pad with spaces if the category name is less than 20 characters long.
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%020c
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
false
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
20
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
none
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Left pad with 0's if the category name is less than 20 characters long.
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%.30c
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
NA
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
none
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
30
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Truncate from the end if the category name is longer than 30 characters.
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%20.30c
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
false
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
20
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
30
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Left pad with spaces if the category name is shorter than 20 characters.
|
|
|
However, if category name is longer than 30 characters, then truncate from
|
|
|
the end.
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%-20.30c
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
true
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
20
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
30
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Right pad with spaces if the category name is shorter than 20 characters.
|
|
|
However, if category name is longer than 30 characters, then truncate from
|
|
|
the end.
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
</lyxtabular>
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Subsection
|
|
|
Time Character
|
|
|
\begin_inset CommandInset label
|
|
|
LatexCommand label
|
|
|
name "subsec:Time-Character"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Here is the Time Character support by Conversion Character
|
|
|
\emph on
|
|
|
d.
|
|
|
|
|
|
\emph default
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
All Character is supported by strftime(3) in library.
|
|
|
The Character supported on my linux system are
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
\begin_inset Tabular
|
|
|
<lyxtabular version="3" rows="42" columns="3">
|
|
|
<features islongtable="true" longtabularalignment="center">
|
|
|
<column alignment="center" valignment="top" width="10text%">
|
|
|
<column alignment="left" valignment="top" width="60text%">
|
|
|
<column alignment="left" valignment="top" width="20text%">
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
character
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
effect
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
example
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%a
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The abbreviated weekday name according to the current locale.
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Wed
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%A
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The full weekday name according to the current locale.
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Wednesday
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%b
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The abbreviated month name according to the current locale.
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Mar
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%B
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The full month name according to the current locale.
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
March
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%c
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The preferred date and time representation for the current locale.
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Thu Feb 16 14:16:35 2012
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%C
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The century number (year/100) as a 2-digit integer.
|
|
|
(SU)
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
20
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%d
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The day of the month as a decimal number (range 01 to 31).
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
06
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%D
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Equivalent to %m/%d/%y.
|
|
|
(for Americans only.
|
|
|
Americans should note that in other countries %d/%m/%y is more common.
|
|
|
This means that in an international context this format is ambiguous and
|
|
|
should not be used.) (SU)
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
02/16/12
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%e
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Like %d, the day of the month as a decimal number, but a leading zero is
|
|
|
replaced by a space.
|
|
|
(SU)
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
6
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%F
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Equivalent to %Y-%m-%d (the ISO 8601 date format).
|
|
|
(C99)
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
2012-02-16
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%G
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The ISO 8601 week-based year (see NOTES) with century as a decimal number.
|
|
|
The 4-digit year corresponding to the ISO week number (see %V).
|
|
|
This has the same format and value as %Y, except that if the ISO week number
|
|
|
belongs to the previous or next year, that year is used instead.
|
|
|
(TZ)
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
2012
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%g
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Like %G, but without century, that is, with a 2-digit year (00-99).
|
|
|
(TZ)
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
12
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%h
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Equivalent to %b.
|
|
|
(SU)
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Feb
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%H
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The hour as a decimal number using a 24-hour clock (range 00 to 23).
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
14
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%I
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The hour as a decimal number using a 12-hour clock (range 01 to 12).
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
02
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%j
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The day of the year as a decimal number (range 001 to 366).
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
047
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%k
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The hour (24-hour clock) as a decimal number (range 0 to 23); single digits
|
|
|
are preceded by a blank.
|
|
|
(See also %H.) (TZ)
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
15
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%l
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The hour (12-hour clock) as a decimal number (range 1 to 12); single digits
|
|
|
are preceded by a blank.
|
|
|
(See also %I.) (TZ)
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
3
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%m
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The month as a decimal number (range 01 to 12).
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
02
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%M
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The minute as a decimal number (range 00 to 59).
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
11
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%n
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
A newline character.
|
|
|
(SU)
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
|
|
\backslash
|
|
|
n
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%p
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Either "AM" or "PM" according to the given time value, or the corresponding
|
|
|
strings for the current locale.
|
|
|
Noon is treated as "PM" and midnight as "AM".
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
PM
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%P
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
Like %p but in lowercase: "am" or "pm" or a corresponding string for the
|
|
|
current locale.
|
|
|
(GNU)
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
pm
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%r
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The time in a.m.
|
|
|
or p.m.
|
|
|
notation.
|
|
|
In the POSIX locale this is equivalent to %I:%M:%S %p.
|
|
|
(SU)
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
03:11:54 PM
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%R
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The time in 24-hour notation (%H:%M).
|
|
|
(SU) For a version including the seconds, see %T below.
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
15:11
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%s
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The number of seconds since the Epoch, that is, since 1970-01-01 00:00:00
|
|
|
UTC.
|
|
|
(TZ)
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
1329376487
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%S
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The second as a decimal number (range 00 to 60).
|
|
|
(The range is up to 60 to allow for occasional leap seconds.)
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
54
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%t
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
A tab character.
|
|
|
(SU)
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%T
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The time in 24-hour notation (%H:%M:%S).
|
|
|
(SU)
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
15:14:47
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%u
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The day of the week as a decimal, range 1 to 7, Monday being 1.
|
|
|
See also %w.
|
|
|
(SU)
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
4
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%U
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The week number of the current year as a decimal number, range 00 to 53,
|
|
|
starting with the first Sun‐ day as the first day of week 01.
|
|
|
See also %V and %W.
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
07
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%V
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The ISO 8601 week number (see NOTES) of the current year as a decimal number,
|
|
|
range 01 to 53, where week 1 is the first week that has at least 4 days
|
|
|
in the new year.
|
|
|
See also %U and %W.
|
|
|
(SU)
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
07
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%w
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The day of the week as a decimal, range 0 to 6, Sunday being 0.
|
|
|
See also %u.
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
4
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%W
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The week number of the current year as a decimal number, range 00 to 53,
|
|
|
starting with the first Mon‐ day as the first day of week 01.
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
07
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%x
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The preferred date representation for the current locale without the time.
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
02/16/12
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%X
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The preferred time representation for the current locale without the date.
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
15:14:47
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%y
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The year as a decimal number without a century (range 00 to 99).
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
12
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%Y
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The year as a decimal number including the century.
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
2012
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%z
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The time-zone as hour offset from GMT.
|
|
|
Required to emit RFC 822-conformant dates (using "%a, %d %b %Y %H:%M:%S
|
|
|
%z").
|
|
|
(GNU)
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
+0800
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%Z
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
The timezone or name or abbreviation.
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
CST
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%%
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
A literal '%' character.
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
%
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
</lyxtabular>
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Section
|
|
|
Rules
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
This section begins with [rules].
|
|
|
It decides how log actions are filtered, formatted and output.
|
|
|
This section can be omitted, but there will result in no log output.
|
|
|
The syntax is
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
(category).(level) (output), (option,optional); (format name, optional)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
When zlog_init() is called, all rules will be read into memory.
|
|
|
When zlog_get_category() is called, mutiple rules will be assigned to each
|
|
|
category, in the way
|
|
|
\begin_inset CommandInset ref
|
|
|
LatexCommand ref
|
|
|
reference "subsec:Category-Matching"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
describes.
|
|
|
When logging is performed, the level between matched rules and INFO will
|
|
|
be checked to decide whether this single log will be output through the
|
|
|
rule.
|
|
|
When zlog_reload() is called, the configuration file will be re-read into
|
|
|
memory, including rules.
|
|
|
All category rules will be re-calculated.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Subsection
|
|
|
Level Matching
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
There are six default levels in zlog, "DEBUG", "INFO", "NOTICE", "WARN",
|
|
|
"ERROR" and "FATAL".
|
|
|
As in all other log libraries, aa.DEBUG means all logs of level greater
|
|
|
than or equal to DEBUG will be output.
|
|
|
Still, there are more expressions.
|
|
|
Levels in the configuration file are not case sensitive; both capital or
|
|
|
lowercase are accepted.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
\begin_inset Tabular
|
|
|
<lyxtabular version="3" rows="5" columns="2">
|
|
|
<features tabularvalignment="middle">
|
|
|
<column alignment="center" valignment="top">
|
|
|
<column alignment="center" valignment="top">
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
example expression
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
meaning
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
*
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
all [source level]
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
aa.debug
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
[source level]>=debug
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
aa.=debug
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
[source level]==debug
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
aa.!debug
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
[source level]!=debug
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
</lyxtabular>
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
The level strings can be defined by the user.
|
|
|
See
|
|
|
\begin_inset CommandInset ref
|
|
|
LatexCommand ref
|
|
|
reference "sec:User-defined-Level"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Subsection
|
|
|
Category Matching
|
|
|
\begin_inset CommandInset label
|
|
|
LatexCommand label
|
|
|
name "subsec:Category-Matching"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Category Matching is simple.
|
|
|
The name of the category is made up of letters, digits, and/or the underscore
|
|
|
"_".
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
\begin_inset Tabular
|
|
|
<lyxtabular version="3" rows="5" columns="4">
|
|
|
<features tabularvalignment="middle">
|
|
|
<column alignment="left" valignment="top" width="20text%">
|
|
|
<column alignment="left" valignment="top" width="15col%">
|
|
|
<column alignment="left" valignment="top" width="25col%">
|
|
|
<column alignment="left" valignment="top" width="20col%">
|
|
|
<row>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
summarize
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
category string from configure file
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
category matches
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
category not matches
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
* matches all
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
*.*
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
aa, aa_bb, aa_cc, xx, yy ...
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
NONE
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
string end with underline matches super-category and sub-categories
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
aa_.*
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
aa, aa_bb, aa_cc, aa_bb_cc
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
xx, yy
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
string not ending with underline accurately matches category
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
aa.*
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
aa
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
aa_bb, aa_cc, aa_bb_cc
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
! matches category that has no rule matched
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
!.*
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
xx
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
aa(as it matches rules above)
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
</lyxtabular>
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Subsection
|
|
|
Output Action
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
zlog supports various output methods.
|
|
|
The syntax is
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
(output action), (output option); (format name, optional)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
\begin_inset Tabular
|
|
|
<lyxtabular version="3" rows="8" columns="3">
|
|
|
<features tabularvalignment="middle">
|
|
|
<column alignment="left" valignment="top">
|
|
|
<column alignment="center" valignment="top">
|
|
|
<column alignment="left" valignment="top" width="30text%">
|
|
|
<row>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
output
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
output action
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
output option
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
to standard out
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
>stdout
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
no meaning
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
to standard error
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
>stderr
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
no meaning
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
to syslog
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
>syslog
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
syslog facility, can be: LOG_USER(default), LOG_LOCAL[0-7]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
This is required.
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
pipeline output
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
| cat
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
no meaning
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
to file
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
"(file path)"
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
rotation.
|
|
|
see
|
|
|
\begin_inset CommandInset ref
|
|
|
LatexCommand ref
|
|
|
reference "sec:Rotation"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
for detail
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
10MB * 3 ~ "press.#r.log"
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
synchronous I/O file
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
-"(file path)"
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
<row>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
user-defined output
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
$name
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
<cell alignment="left" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
|
|
|
\begin_inset Text
|
|
|
|
|
|
\begin_layout Plain Layout
|
|
|
"path" (dynamic or static) of record function
|
|
|
\end_layout
|
|
|
|
|
|
\end_inset
|
|
|
</cell>
|
|
|
</row>
|
|
|
</lyxtabular>
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Itemize
|
|
|
stdout, stderr, syslog
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Standard
|
|
|
As the above table describes, only the syslog action has a meaningful output
|
|
|
option and it must be set.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Warning: NEVER use >stdout or >stderr when your program is a daemon process.
|
|
|
A daemon process always closes its first file descriptor, and when >stdout
|
|
|
is set, zlog will output a log like this
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
write(STDOUT_FILENO, zlog_buf_str(a_thread->msg_buf), zlog_buf_len(a_thread->msg
|
|
|
_buf))
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
What will happen then? The log will be written to the file whose fd is now
|
|
|
1.
|
|
|
I have received mail from someone who said zlog as a daemon wrote logs
|
|
|
to the configuration file.
|
|
|
So remember, daemon processes should not set any rule output to stdout,
|
|
|
or stderr.
|
|
|
It will generate undefined behavior.
|
|
|
If you still want output logs to console when stdout is closed, use "/dev/tty"
|
|
|
instead.
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Itemize
|
|
|
pipeline output
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
*.* | /usr/bin/cronolog /www/logs/example_%Y%m%d.log ; normal
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
This is an example of how zlog pipelines its output to cronolog.
|
|
|
The implementation is simple.
|
|
|
popen("/usr/bin/cronolog /www/logs/example_%Y%m%d.log","w") is called at
|
|
|
zlog_init(), and forward logs will be written to the open descriptor in
|
|
|
the "normal" format.
|
|
|
Writing through pipeline and cronnolog is faster than dynamic file of zlog,
|
|
|
as there is no need to open and close file descripter each time when logs
|
|
|
are written to a pipe.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
[rules]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
*.* "press%d(%Y%m%d).log"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ time ./test_press_zlog 1 10 100000
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
real 0m4.240s
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
user 0m2.500s
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
sys 0m5.460s
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
[rules]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
*.* | /usr/bin/cronolog press%Y%m%d.log
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ time ./test_press_zlog 1 10 100000
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
real 0m1.911s
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
user 0m1.980s
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
sys 0m1.470s
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
There are some limitations when using pipeline output:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Itemize
|
|
|
POSIX.1-2001 says that write(2)s of less than PIPE_BUF bytes must be atomic,
|
|
|
On Linux, PIPE_BUF is 4096 bytes.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Itemize
|
|
|
When a single log is longer than PIPE_BUF, and multiple processes write
|
|
|
logs through one pipe (parent calls zlog_init(), and forks many child processes
|
|
|
), log interlacing will occur.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Itemize
|
|
|
Unrelated multiple processes can start multiple cronolog processes and write
|
|
|
to the same log file.
|
|
|
Even if a single log is not longer than PIPE_BUF, multiple cronologs will
|
|
|
cause log interlace.
|
|
|
As cronologs read log continuously, it doesn't know where is the split
|
|
|
between log entries.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
In summary, pipeline to a single log file:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Itemize
|
|
|
Single process writing, no limitation for length of one log.
|
|
|
Multi-threads in one process, atomic writing is already assured by zlog.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Itemize
|
|
|
Related multiple processes, the length of one log should not longer than
|
|
|
PIPE_BUF.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Itemize
|
|
|
Unrelated multiple processes, no matter how long a single log is, will cause
|
|
|
interlace and is not safe.
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Itemize
|
|
|
file
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Itemize
|
|
|
file path
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Standard
|
|
|
can be absolute file path or relative file path.
|
|
|
It is quoted by double quotation marks.
|
|
|
|
|
|
\emph on
|
|
|
Conversion pattern
|
|
|
\emph default
|
|
|
can be used in file path.
|
|
|
If the file path is "%E(HOME)/log/out.log" and the program environment $HOME
|
|
|
is /home/harry, then the log file will be /home/harry/log/output.log.
|
|
|
See
|
|
|
\begin_inset CommandInset ref
|
|
|
LatexCommand ref
|
|
|
reference "sec:Conversion-pattern"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
for more details.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
file of zlog is powerful, for example
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Enumerate
|
|
|
output to named pipe(FIFO), which must be created by mkfifo(1) before use
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
*.* "/tmp/pipefile"
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Enumerate
|
|
|
output to null, do nothing at all
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
*.* "/dev/null"
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Enumerate
|
|
|
output to console, in any case
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
*.* "/dev/tty"
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Enumerate
|
|
|
output a log to each tid, in the directory where the process running
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
*.* "%T.log"
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Enumerate
|
|
|
output to file with pid name, every day, in $HOME/log directory, rotate
|
|
|
log at 1GB, keep 5 log files
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
*.* "%E(HOME)/log/aa.%p.%d(%F).log",1GB * 5
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Enumerate
|
|
|
each category of aa_ super category, output log with category name
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
aa_.* "/var/log/%c.log"
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Itemize
|
|
|
rotate action
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Standard
|
|
|
controls log file size and count.
|
|
|
zlog rotates the log file when the file exceeds this value.
|
|
|
For example, let the action be
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
"%E(HOME)/log/out.log",1M*3
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
and after out.log is filled to 1M, the rotation is
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
out.log -> out.log.1
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
out.log(new create)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
If the new log is full again, the rotation is
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
out.log.1 -> out.log.2
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
out.log -> out.log.1
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
out.log(new create)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
The next rotation will delete the oldest log, as *3 means just allows 3
|
|
|
file exist
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
unlink(out.log.2)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
out.log.1 -> out.log.2
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
out.log -> out.log.1
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
out.log(new create)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
So the oldest log has the biggest serial number.
|
|
|
If *3 is not specified, it means rotation will continue and no old log
|
|
|
will be deleted.
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Itemize
|
|
|
synchronous I/O file
|
|
|
\begin_inset CommandInset label
|
|
|
LatexCommand label
|
|
|
name "ite:synchronous-I/O-file"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Standard
|
|
|
Putting a minus sign '-' sets the synchronous I/O option.
|
|
|
log file is opened with O_SYNC and every single log action will wait until
|
|
|
the Operating System writes data to disk.
|
|
|
It is painfully slow:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ time ./test_press_zlog 100 1000
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
real 0m0.732s
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
user 0m1.030s
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
sys 0m1.080s
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ time ./test_press_zlog 100 1000 # synchronous I/O open
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
real 0m20.646s
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
user 0m2.570s
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
sys 0m6.950s
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\end_deeper
|
|
|
\begin_layout Itemize
|
|
|
format name
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Standard
|
|
|
It is optional.
|
|
|
If not set, use zlog default format in global setting, which is:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
[global]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
default format = "%d %V [%p:%F:%L] %m%n"
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Itemize
|
|
|
see
|
|
|
\begin_inset CommandInset ref
|
|
|
LatexCommand ref
|
|
|
reference "sec:User-defined-Output"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
for more details for $.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Section
|
|
|
Rotation
|
|
|
\begin_inset CommandInset label
|
|
|
LatexCommand label
|
|
|
name "sec:Rotation"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Why rotation? I have see more than once in a production environment, that
|
|
|
the hard disk is full of logs and causes the system to stop working, or
|
|
|
a single log file is too big to open or grep.
|
|
|
Several ways to rotate and archive log files are possible:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Enumerate
|
|
|
Split log by date or time.
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Standard
|
|
|
For example, generate one log file per day.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
aa.2012-08-02.log
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
aa.2012-08-03.log
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
aa.2012-08-04.log
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
In this case, the system administrator knows how much log will be produced
|
|
|
one day.
|
|
|
The sys admin is able to search log files based on the day.
|
|
|
The best way to make this split is to let the zlog library do it.
|
|
|
Another choice is using cronosplit to analyse the content of log file and
|
|
|
split it.
|
|
|
A bad way is using crontab+logrotate to daily move log files, which is
|
|
|
not accurate, some logs will be put into the file for the previous day.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Using zlog, there is no need for external rotate action to complete the
|
|
|
job.
|
|
|
Setting time in the log file name works:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
*.* "aa.%d(%F).log"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
or using cronolog for faster performace:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
*.* | cronolog aa.%F.log
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Enumerate
|
|
|
Split log by size.
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Standard
|
|
|
Always suitable for development use.
|
|
|
In this case, the program generates a lot of logs in a short period.
|
|
|
But the text editor might not be able to open big files quickly.
|
|
|
Although the split can be done using split tools afterwards, this requires
|
|
|
extra steps.
|
|
|
So a good way is to let the logging library do the rotation.
|
|
|
There are two ways of rotation, as nlog describes, Sequence and Rolling.
|
|
|
In case of Sequence:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
aa.log (new)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
aa.log.2 (less new)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
aa.log.1
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
aa.log.0 (old)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
And in case of Rolling:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
aa.log (new)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
aa.log.0 (less new)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
aa.log.1
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
aa.log.2 (old)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
It's hard to say which one is most suitable.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
If only some of the newest logs are useful to developers, logging library
|
|
|
should do the cleanup work and delete the old log files.
|
|
|
Some external tools can't find out which files are older.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
The simplest rotation configuration for zlog is:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
*.* "aa.log", 10MB
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
It is Rolling.
|
|
|
When aa.log is larger than 10MB, zlog will rename file like this:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
aa.log.2 -> aa.log.3
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
aa.log.1 -> aa.log.2
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
aa.log.0 -> aa.log.1
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
aa.log -> aa.log.0
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
The configuration can be more complex:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
*.* "aa.log", 10MB * 0 ~ "aa.log.#r"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
The 1st argument after the file name says when rotation will be triggered,
|
|
|
in size.
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
The 2nd argument after the file name says how many archive files will be
|
|
|
kept, (0 means keep all).
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
The 3rd argument after the file name shows the archive file name.
|
|
|
#r is a sequence number for archive files.
|
|
|
r is short for Rolling, and #s is short for sequence.
|
|
|
Archive file name must contain one of #r or #s.
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Enumerate
|
|
|
Split log by size, and add time tag to archive file.
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
aa.log
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
aa.log-20070305.00.log
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
aa.log-20070501.00.log
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
aa.log-20070501.01.log
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
aa.log-20071008.00.log
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
In this case, the log file is not usually viewed frequently, and is likely
|
|
|
checked once a day.
|
|
|
Of course, when one day's log is more than 100MB, you should consider storing
|
|
|
in two files and add postfix numbers.
|
|
|
For example if the date is used as part of the pattern (like 20070501):
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
The configuration of zlog is:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
*.* "aa.log", 100MB ~ "aa-%d(%Y%m%d).#2s.log"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
Do rotation every 100MB.
|
|
|
The archive file name also supports conversion strings.
|
|
|
#2s means the sequence number is at least 2 bytes wide.
|
|
|
Sequence from 00.
|
|
|
That's the most complex way to archive in zlog.
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Enumerate
|
|
|
Compress, move and delete old archive.
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Standard
|
|
|
Compress should not be done by the logging library, because compress need
|
|
|
time and CPU.
|
|
|
The mission of the logging library is to cooperate with compress programs.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
For the 3 ways to split logs, way 1 and way 3 are easy to manage.
|
|
|
It is easy to find old log file by name or by modify time.
|
|
|
And then compress, move and delete old log files by crontab and shell.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
For second way, compress is useless, delete is needed and zlog already supports
|
|
|
it.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
If you really want to rotate and compress log file at the same time, I suggest
|
|
|
logrotate.
|
|
|
It is an independent program and will not confuse the situation.
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Enumerate
|
|
|
zlog support for external tools like logrotate.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
The rotation support of zlog is very powerful, still there are several cases
|
|
|
zlog can not handle.
|
|
|
Like rotation by time, before or after rotation call some user-defined
|
|
|
shells.
|
|
|
That will make zlog too complex.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Under these circumstances, consider using external tools like logrotate.
|
|
|
On linux, the problem is that when a tool renames the log file, the working
|
|
|
process which uses an inode to reference the file will not automatically
|
|
|
reopen the new file.
|
|
|
The standard way is send a signal to the program and let it reopen the
|
|
|
file.
|
|
|
For syslogd the command is:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
kill -SIGHUP `cat /var/run/syslogd.pid`
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
For zlog as a library, it is not good to receive signals.
|
|
|
zlog provide zlog_reload(), which reloads the configuration file and reopens
|
|
|
all log files.
|
|
|
So if you write a program and want to reopen a log file manually, you can
|
|
|
write some code to do the job like this: after receiving a signal or command
|
|
|
from client, call zlog_reload().
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Section
|
|
|
Configure File Tools
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ zlog-chk-conf -h
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
Useage: zlog-chk-conf [conf files]...
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
-q, suppress non-error message
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
-h, show help message
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
zlog-chk-conf tries to read configuration files, check their syntax, and
|
|
|
output to screen whether it is correct or not.
|
|
|
I suggest using this tool each time you create or change a configuration
|
|
|
file.
|
|
|
It will output like this
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ ./zlog-chk-conf zlog.conf
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
03-08 15:35:44 ERROR (10595:rule.c:391) sscanf [aaa] fail, category or level
|
|
|
is null
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
03-08 15:35:44 ERROR (10595:conf.c:155) zlog_rule_new fail [aaa]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
03-08 15:35:44 ERROR (10595:conf.c:258) parse configure file[zlog.conf] line[126]
|
|
|
fail
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
03-08 15:35:44 ERROR (10595:conf.c:306) zlog_conf_read_config fail
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
03-08 15:35:44 ERROR (10595:conf.c:366) zlog_conf_build fail
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
03-08 15:35:44 ERROR (10595:zlog.c:66) conf_file[zlog.conf], init conf fail
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
03-08 15:35:44 ERROR (10595:zlog.c:131) zlog_init_inner[zlog.conf] fail
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
---[zlog.conf] syntax error, see error message above
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
This example tells you that [aaa] is not a correct rule and that line 126
|
|
|
in the configuration file is wrong.
|
|
|
Later failure reports result from that fundamental failure.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Chapter
|
|
|
zlog API
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
All zlog APIs are thread safe.
|
|
|
To use them, you just need to
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
#include "zlog.h"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Section
|
|
|
initialize and finish
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Labeling
|
|
|
\labelwidthstring 00.00.0000
|
|
|
SYNOPSIS
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
int zlog_init(const char *
|
|
|
\bar under
|
|
|
confpath
|
|
|
\bar default
|
|
|
);
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
int zlog_reload(const char *
|
|
|
\bar under
|
|
|
confpath
|
|
|
\bar default
|
|
|
);
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
void zlog_fini(void);
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Labeling
|
|
|
\labelwidthstring 00.00.0000
|
|
|
DESCRIPTION
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Standard
|
|
|
zlog_init() reads configuration from the file
|
|
|
\bar under
|
|
|
confpath
|
|
|
\bar default
|
|
|
.
|
|
|
If
|
|
|
\bar under
|
|
|
confpath
|
|
|
\bar default
|
|
|
is NULL, it looks for the environment variable ZLOG_CONF_PATH to find the
|
|
|
configuration file.
|
|
|
If $ZLOG_CONF_PATH is NULL also, all logs will be output to stdout with
|
|
|
an internal format.
|
|
|
Only the first call to zlog_init() per process is effective, subsequent
|
|
|
calls will fail and do nothing.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
zlog_reload() is designed to reload the configuration file.
|
|
|
From the
|
|
|
\bar under
|
|
|
confpath
|
|
|
\bar default
|
|
|
it re-calculates the category-rule relationships, rebuilds thread buffers,
|
|
|
and resets user-defined output function rules.
|
|
|
It can be called at runtime when the configuration file is changed or you
|
|
|
wish to use another configuration file.
|
|
|
It can be called any number of times.
|
|
|
If
|
|
|
\bar under
|
|
|
confpath
|
|
|
\bar default
|
|
|
is NULL, it reloads the last configuration file that zlog_init() or zlog_reload
|
|
|
() specified.
|
|
|
If zlog_reload() failed, the current configuration in memory will remain
|
|
|
unchanged.
|
|
|
So zlog_reload() is atomic.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
zlog_fini() releases all zlog API
|
|
|
\emph on
|
|
|
|
|
|
\emph default
|
|
|
memory and closes opened files.
|
|
|
It can be called any number of times.
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Labeling
|
|
|
\labelwidthstring 00.00.0000
|
|
|
RETURN VALUE
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Standard
|
|
|
On success , zlog_init() and zlog_reload() return zero.
|
|
|
On error, zlog_init() and zlog_reload() return -1, and a detailed error
|
|
|
log will be recorded to the log file indicated by ZLOG_PROFILE_ERROR.
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Section
|
|
|
category operation
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Labeling
|
|
|
\labelwidthstring 00.00.0000
|
|
|
SYNOPSIS
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
typedef struct zlog_category_s zlog_category_t;
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_category_t *zlog_get_category(const char *
|
|
|
\bar under
|
|
|
cname
|
|
|
\bar default
|
|
|
);
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Labeling
|
|
|
\labelwidthstring 00.00.0000
|
|
|
DESCRIPTION
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Standard
|
|
|
zlog_get_category() gets a category from zlog's category_table for a future
|
|
|
log action.
|
|
|
If the category cname does not exist it will be created.
|
|
|
Then zlog goes through all rules as determined by the configuration.
|
|
|
It returns a pointer to matched rules corresponding to
|
|
|
\bar under
|
|
|
cname
|
|
|
\bar default
|
|
|
.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
This is how category string in rules matches
|
|
|
\bar under
|
|
|
cname
|
|
|
\bar default
|
|
|
:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Enumerate
|
|
|
* matches all
|
|
|
\bar under
|
|
|
cname
|
|
|
\bar default
|
|
|
.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Enumerate
|
|
|
category string which ends with underscore "_" matches super-category and
|
|
|
sub-categories.
|
|
|
For example, "aa_" matches
|
|
|
\bar under
|
|
|
cname
|
|
|
\bar default
|
|
|
like "aa", "aa_", "aa_bb", "aa_bb_cc".
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Enumerate
|
|
|
category string which does not end with underscore "_"matches
|
|
|
\bar under
|
|
|
cname
|
|
|
\bar default
|
|
|
accurately.
|
|
|
For example, "aa_bb" matches only a
|
|
|
\bar under
|
|
|
cname
|
|
|
\bar default
|
|
|
of "aa_bb".
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Enumerate
|
|
|
! matches
|
|
|
\bar under
|
|
|
cname
|
|
|
\bar default
|
|
|
that has no rule matched.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
The rules for each category will be automatically re-calculated when zlog_reload
|
|
|
() is called.
|
|
|
No need to worry about category's memory release,
|
|
|
\emph on
|
|
|
|
|
|
\emph default
|
|
|
zlog_fini() will clean up at the end.
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Labeling
|
|
|
\labelwidthstring 00.00.0000
|
|
|
RETURN VALUE
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Standard
|
|
|
On success, return the address of zlog_category_t.
|
|
|
On error, return NULL, and a detailed error log will be recorded to the
|
|
|
log file indicated by ZLOG_PROFILE_ERROR.
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Section
|
|
|
log functions and macros
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Labeling
|
|
|
\labelwidthstring 00.00.0000
|
|
|
SYNOPSIS
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
void zlog(zlog_category_t *
|
|
|
\bar under
|
|
|
category
|
|
|
\bar default
|
|
|
,
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
const char *
|
|
|
\bar under
|
|
|
file
|
|
|
\bar default
|
|
|
, size_t
|
|
|
\bar under
|
|
|
filelen
|
|
|
\bar default
|
|
|
,
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
const char *
|
|
|
\bar under
|
|
|
func
|
|
|
\bar default
|
|
|
, size_t
|
|
|
\bar under
|
|
|
funclen
|
|
|
\bar default
|
|
|
,
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
long
|
|
|
\bar under
|
|
|
line
|
|
|
\bar default
|
|
|
, int
|
|
|
\bar under
|
|
|
level
|
|
|
\bar default
|
|
|
,
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
const char *
|
|
|
\bar under
|
|
|
format
|
|
|
\bar default
|
|
|
, ...);
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
void vzlog(zlog_category_t *
|
|
|
\bar under
|
|
|
category
|
|
|
\bar default
|
|
|
,
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
const char *
|
|
|
\bar under
|
|
|
file
|
|
|
\bar default
|
|
|
, size_t
|
|
|
\bar under
|
|
|
filelen
|
|
|
\bar default
|
|
|
,
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
const char *
|
|
|
\bar under
|
|
|
func
|
|
|
\bar default
|
|
|
, size_t
|
|
|
\bar under
|
|
|
funclen
|
|
|
\bar default
|
|
|
,
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
long
|
|
|
\bar under
|
|
|
line
|
|
|
\bar default
|
|
|
, int
|
|
|
\bar under
|
|
|
level
|
|
|
\bar default
|
|
|
,
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
const char *
|
|
|
\bar under
|
|
|
format
|
|
|
\bar default
|
|
|
, va_list
|
|
|
\bar under
|
|
|
args
|
|
|
\bar default
|
|
|
);
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
void hzlog(zlog_category_t *
|
|
|
\bar under
|
|
|
category
|
|
|
\bar default
|
|
|
,
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
const char *
|
|
|
\bar under
|
|
|
file
|
|
|
\bar default
|
|
|
, size_t
|
|
|
\bar under
|
|
|
filelen
|
|
|
\bar default
|
|
|
,
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
const char *
|
|
|
\bar under
|
|
|
func
|
|
|
\bar default
|
|
|
, size_t
|
|
|
\bar under
|
|
|
funclen
|
|
|
\bar default
|
|
|
,
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
long
|
|
|
\bar under
|
|
|
line
|
|
|
\bar default
|
|
|
, int
|
|
|
\bar under
|
|
|
level
|
|
|
\bar default
|
|
|
,
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
const void *
|
|
|
\bar under
|
|
|
buf
|
|
|
\bar default
|
|
|
, size_t
|
|
|
\bar under
|
|
|
buflen
|
|
|
\bar default
|
|
|
);
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Labeling
|
|
|
\labelwidthstring 00.00.0000
|
|
|
DESCRIPTION
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Standard
|
|
|
These 3 functions are the real log functions producing user messages, which
|
|
|
correspond to %m is configuration file entries.
|
|
|
|
|
|
\bar under
|
|
|
category
|
|
|
\bar default
|
|
|
comes from zlog_get_category() described above.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
zlog() and vzlog()
|
|
|
\emph on
|
|
|
|
|
|
\emph default
|
|
|
produce output according to a
|
|
|
\bar under
|
|
|
format
|
|
|
\bar default
|
|
|
like printf(3) and vprintf(3).
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
vzlog()
|
|
|
\emph on
|
|
|
|
|
|
\emph default
|
|
|
is equivalent to zlog(), except that it is called with a va_list instead
|
|
|
of a variable number of arguments.
|
|
|
vzlog() invokes the va_copy macro, the value of
|
|
|
\bar under
|
|
|
args
|
|
|
\bar default
|
|
|
remain unchanged after the call.
|
|
|
See stdarg(3).
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
hzlog()
|
|
|
\emph on
|
|
|
|
|
|
\emph default
|
|
|
is a little different, it produce output like this, the hexadecimal representati
|
|
|
on of
|
|
|
\bar under
|
|
|
buf
|
|
|
\emph on
|
|
|
\bar default
|
|
|
|
|
|
\emph default
|
|
|
and output len is
|
|
|
\bar under
|
|
|
buf_len
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
hex_buf_len=[5365]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDE
|
|
|
F
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
0000000001 23 21 20 2f 62 69 6e 2f 62 61 73 68 0a 0a 23 20 #! /bin/bash..#
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
0000000002 74 65 73 74 5f 68 65 78 20 2d 20 74 65 6d 70 6f test_hex
|
|
|
- tempo
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
0000000003 72 61 72 79 20 77 72 61 70 70 65 72 20 73 63 72 rary wrapper
|
|
|
scr
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
The parameter
|
|
|
\bar under
|
|
|
file
|
|
|
\bar default
|
|
|
and
|
|
|
\bar under
|
|
|
line
|
|
|
\bar default
|
|
|
are usually filled by the __FILE__ and __LINE__ macros.
|
|
|
These indicate where the log event happened.
|
|
|
The parameter
|
|
|
\bar under
|
|
|
func
|
|
|
\bar default
|
|
|
is filled with __func__ or __FUNCTION__, if the compiler supports it, otherwise
|
|
|
it will be filled with "<unknown>".
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
|
|
|
\bar under
|
|
|
level
|
|
|
\emph on
|
|
|
\bar default
|
|
|
|
|
|
\emph default
|
|
|
is an int in the current level list, which defaults to:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
typedef enum {
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
ZLOG_LEVEL_DEBUG = 20,
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
ZLOG_LEVEL_INFO = 40,
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
ZLOG_LEVEL_NOTICE = 60,
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
ZLOG_LEVEL_WARN = 80,
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
ZLOG_LEVEL_ERROR = 100,
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
ZLOG_LEVEL_FATAL = 120
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
} zlog_level;
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Each fuction has its macros for easy use.
|
|
|
For example,
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
#define zlog_fatal(cat, format, args...)
|
|
|
\backslash
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog(cat, __FILE__, sizeof(__FILE__)-1,
|
|
|
\backslash
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
__func__, sizeof(__func__)-1, __LINE__,
|
|
|
\backslash
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
ZLOG_LEVEL_FATAL, format, ##args)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
The full list of macros is:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
/* zlog macros */
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
/* zlog macros */
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_fatal(cat, format, ...)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_error(cat, format, ...)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_warn(cat, format, ...)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_notice(cat, format, ...)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_info(cat, format, ...)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_debug(cat, format, ...)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
/* vzlog macros */
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
vzlog_fatal(cat, format, args)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
vzlog_error(cat, format, args)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
vzlog_warn(cat, format, args)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
vzlog_notice(cat, format, args)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
vzlog_info(cat, format, args)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
vzlog_debug(cat, format, args)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
/* hzlog macros */
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
hzlog_fatal(cat, buf, buf_len)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
hzlog_error(cat, buf, buf_len)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
hzlog_warn(cat, buf, buf_len)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
hzlog_notice(cat, buf, buf_len)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
hzlog_info(cat, buf, buf_len)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
hzlog_debug(cat, buf, buf_len)
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Labeling
|
|
|
\labelwidthstring 00.00.0000
|
|
|
RETURN VALUE
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Standard
|
|
|
These functions return nothing.
|
|
|
But if anything wrong happens, a detailed error log will be recorded to
|
|
|
the log file indicated by ZLOG_PROFILE_ERROR.
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Section
|
|
|
MDC operation
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Labeling
|
|
|
\labelwidthstring 00.00.0000
|
|
|
SYNOPSIS
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
int zlog_put_mdc(const char *
|
|
|
\bar under
|
|
|
key
|
|
|
\bar default
|
|
|
, const char *
|
|
|
\bar under
|
|
|
value
|
|
|
\bar default
|
|
|
);
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
char *zlog_get_mdc(const char *
|
|
|
\bar under
|
|
|
key
|
|
|
\bar default
|
|
|
);
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
void zlog_remove_mdc(const char *
|
|
|
\bar under
|
|
|
key
|
|
|
\bar default
|
|
|
);
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
void zlog_clean_mdc(void);
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Labeling
|
|
|
\labelwidthstring 00.00.0000
|
|
|
DESCRIPTION
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Standard
|
|
|
MDC (Mapped Diagnostic Context) is a thread key-value map, and has nothing
|
|
|
to do with category.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
|
|
|
\bar under
|
|
|
key
|
|
|
\bar default
|
|
|
and
|
|
|
\bar under
|
|
|
value
|
|
|
\bar default
|
|
|
are all strings, which should be no longer than MAXLEN_PATH(1024).
|
|
|
If the input is longer than MAXLEN_PATH(1024), the input will be truncated.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
One thing you should remember is that the map bonds to a thread, thus if
|
|
|
you set a key-value pair in one thread, it will not affect other threads.
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Labeling
|
|
|
\labelwidthstring 00.00.0000
|
|
|
RETURN VALUE
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Standard
|
|
|
zlog_put_mdc() returns 0 for success, -1 for fail.
|
|
|
zlog_get_mdc() returns a pointer to
|
|
|
\bar under
|
|
|
value
|
|
|
\bar default
|
|
|
for success, NULL for fail or key not exist.
|
|
|
If anything wrong happens, a detailed error log will be recorded to the
|
|
|
log file indicated by ZLOG_PROFILE_ERROR.
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Section
|
|
|
dzlog API
|
|
|
\begin_inset CommandInset label
|
|
|
LatexCommand label
|
|
|
name "sec:dzlog-API"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Labeling
|
|
|
\labelwidthstring 00.00.0000
|
|
|
SYNOPSIS
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
int dzlog_init(const char *
|
|
|
\bar under
|
|
|
confpath
|
|
|
\bar default
|
|
|
, const char *
|
|
|
\bar under
|
|
|
cname
|
|
|
\bar default
|
|
|
);
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
int dzlog_set_category(const char *
|
|
|
\bar under
|
|
|
cname
|
|
|
\bar default
|
|
|
);
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
void dzlog(const char *
|
|
|
\bar under
|
|
|
file
|
|
|
\bar default
|
|
|
, size_t
|
|
|
\bar under
|
|
|
filelen
|
|
|
\bar default
|
|
|
,
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
const char *
|
|
|
\bar under
|
|
|
func
|
|
|
\bar default
|
|
|
, size_t
|
|
|
\bar under
|
|
|
funclen
|
|
|
\bar default
|
|
|
,
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
long
|
|
|
\bar under
|
|
|
line
|
|
|
\bar default
|
|
|
, int
|
|
|
\bar under
|
|
|
level
|
|
|
\bar default
|
|
|
,
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
const char *
|
|
|
\bar under
|
|
|
format
|
|
|
\bar default
|
|
|
, ...);
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
void vdzlog(const char *
|
|
|
\bar under
|
|
|
file
|
|
|
\bar default
|
|
|
, size_t
|
|
|
\bar under
|
|
|
filelen
|
|
|
\bar default
|
|
|
,
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
const char *
|
|
|
\bar under
|
|
|
func
|
|
|
\bar default
|
|
|
, size_t
|
|
|
\bar under
|
|
|
funclen
|
|
|
\bar default
|
|
|
,
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
long
|
|
|
\bar under
|
|
|
line
|
|
|
\bar default
|
|
|
, int
|
|
|
\bar under
|
|
|
level
|
|
|
\bar default
|
|
|
,
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
const char *
|
|
|
\bar under
|
|
|
format
|
|
|
\bar default
|
|
|
, va_list
|
|
|
\bar under
|
|
|
args
|
|
|
\bar default
|
|
|
);
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
void hdzlog(const char *
|
|
|
\bar under
|
|
|
file
|
|
|
\bar default
|
|
|
, size_t
|
|
|
\bar under
|
|
|
filelen
|
|
|
\bar default
|
|
|
,
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
const char *
|
|
|
\bar under
|
|
|
func
|
|
|
\bar default
|
|
|
, size_t
|
|
|
\bar under
|
|
|
funclen
|
|
|
\bar default
|
|
|
,
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
long
|
|
|
\bar under
|
|
|
line
|
|
|
\bar default
|
|
|
, int
|
|
|
\bar under
|
|
|
level
|
|
|
\bar default
|
|
|
,
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
const void *
|
|
|
\bar under
|
|
|
buf
|
|
|
\bar default
|
|
|
, size_t
|
|
|
\bar under
|
|
|
buflen
|
|
|
\bar default
|
|
|
);
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Labeling
|
|
|
\labelwidthstring 00.00.0000
|
|
|
DESCRIPTION
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Standard
|
|
|
dzlog consists of simple functions that omit
|
|
|
\emph on
|
|
|
zlog_category_t
|
|
|
\emph default
|
|
|
.
|
|
|
It uses a default category internally and puts the category under lock
|
|
|
protection.
|
|
|
It is thread safe also.
|
|
|
Omitting the category means that users need not create, save, or transfer
|
|
|
|
|
|
\emph on
|
|
|
zlog_category_t
|
|
|
\emph default
|
|
|
variables.
|
|
|
Still, you can get and use other category values at the same time through
|
|
|
the normal API for flexibility.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
dzlog_init() is just as zlog_init(), but needs a
|
|
|
\bar under
|
|
|
cname
|
|
|
\bar default
|
|
|
for the internal default category.
|
|
|
zlog_reload() and zlog_fini() can be used as before, to refresh conf_file,
|
|
|
or release all.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
dzlog_set_category()
|
|
|
\emph on
|
|
|
|
|
|
\emph default
|
|
|
is designed for changing the default category.
|
|
|
The last default category is replaced by the new one.
|
|
|
Don't worry about releasing memory since all category allocations will
|
|
|
be cleaned up at zlog_fini().
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Macros are defined in zlog.h.
|
|
|
They are the general way in simple logging.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
dzlog_fatal(format, ...)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
dzlog_error(format, ...)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
dzlog_warn(format, ...)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
dzlog_notice(format, ...)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
dzlog_info(format, ...)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
dezlog_debug(format, ...)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
vdzlog_fatal(format, args)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
vdzlog_error(format, args)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
vdzlog_warn(format, args)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
vdzlog_notice(format, args)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
vdzlog_info(format, args)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
vdzlog_debug(format, args)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
hdzlog_fatal(buf, buf_len)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
hdzlog_error(buf, buf_len)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
hdzlog_warn(buf, buf_len)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
hdzlog_noticebuf, buf_len)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
hdzlog_info(buf, buf_len)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
hdzlog_debug(buf, buf_len)
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Labeling
|
|
|
\labelwidthstring 00.00.0000
|
|
|
RETURN VALUE
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Standard
|
|
|
On success, dzlog_init() and dzlog_set_category() return zero.
|
|
|
On error, dzlog_init() and dzlog_set_category() return -1, and a detailed
|
|
|
error log will be recorded to the log file indicated by ZLOG_PROFILE_ERROR.
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Section
|
|
|
User-defined Output
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Labeling
|
|
|
\labelwidthstring 00.00.0000
|
|
|
SYNOPSIS
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
typedef struct zlog_msg_s {
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
char *buf;
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
size_t len;
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
char *path;
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
} zlog_msg_t;
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
typedef int (*zlog_record_fn)(zlog_msg_t *
|
|
|
\bar under
|
|
|
msg
|
|
|
\bar default
|
|
|
);
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
int zlog_set_record(const char *
|
|
|
\bar under
|
|
|
rname
|
|
|
\bar default
|
|
|
, zlog_record_fn
|
|
|
\bar under
|
|
|
record
|
|
|
\bar default
|
|
|
);
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Labeling
|
|
|
\labelwidthstring 00.00.0000
|
|
|
DESCRIPTION
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Standard
|
|
|
zlog allows a user to define an output function.
|
|
|
The output function bonds to a special kind of rule in configuration file.
|
|
|
A typical rule is:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
*.* $name, "record path %c %d"; simple
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
zlog_set_record() does the bonding operation.
|
|
|
Rules with the $
|
|
|
\bar under
|
|
|
rname
|
|
|
\bar default
|
|
|
will be output through user-defined function
|
|
|
\bar under
|
|
|
record
|
|
|
\bar default
|
|
|
.
|
|
|
The callback function has the type of zlog_record_fn.
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
The members of struct zlog_msg_t are decribed below:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
|
|
|
\bar under
|
|
|
path
|
|
|
\bar default
|
|
|
comes from the second parameter of rule after $name, which is generated
|
|
|
dynamically like the file path.
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
|
|
|
\bar under
|
|
|
buf
|
|
|
\bar default
|
|
|
and
|
|
|
\bar under
|
|
|
len
|
|
|
\bar default
|
|
|
are zlog formatted log message and its length.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
All settings of zlog_set_record() are kept available after zlog_reload().
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Labeling
|
|
|
\labelwidthstring 00.00.0000
|
|
|
RETURN VALUE
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Standard
|
|
|
On success, zlog_set_record() returns zero.
|
|
|
On error, it returns -1, and a detailed error log will be recorded to the
|
|
|
log file indicated by ZLOG_PROFILE_ERROR.
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Section
|
|
|
debug and profile
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Labeling
|
|
|
\labelwidthstring 00.00.0000
|
|
|
SYNOPSIS
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
void zlog_profile(void);
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Labeling
|
|
|
\labelwidthstring 00.00.0000
|
|
|
DESCRIPTION
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Standard
|
|
|
environment variable ZLOG_PROFILE_ERROR indicates zlog's error log path.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
environment variable ZLOG_PROFILE_DEBUG indicates zlog's debug log path.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
zlog_profile() prints all information in memory to zlog's error log file
|
|
|
at runtime.
|
|
|
You can compare it to the configuration file to find possible errors.
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Chapter
|
|
|
Advanced Usage
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Section
|
|
|
MDC
|
|
|
\begin_inset CommandInset label
|
|
|
LatexCommand label
|
|
|
name "sec:MDC"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
What is MDC? In log4j it is short for Mapped Diagnostic Context.
|
|
|
That sounds like a complicated terminology.
|
|
|
MDC is just a key-value map.
|
|
|
Once you set it by function, the zlog library will print it to file every
|
|
|
time a log event happens, or become part of log file path.
|
|
|
Let's see an example in $(top_builddir)/test/test_mdc.c.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ cat test_mdc.c
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
#include <stdio.h>
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
#include <stdlib.h>
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
#include <sys/types.h>
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
#include <unistd.h>
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
#include <string.h>
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
#include "zlog.h"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
int main(int argc, char** argv)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
{
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
int rc;
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_category_t *zc;
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
rc = zlog_init("test_mdc.conf");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
if (rc) {
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
printf("init failed
|
|
|
\backslash
|
|
|
n");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
return -1;
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
}
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zc = zlog_get_category("my_cat");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
if (!zc) {
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
printf("get cat fail
|
|
|
\backslash
|
|
|
n");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_fini();
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
return -2;
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
}
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_info(zc, "1.hello, zlog");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_put_mdc("myname", "Zhang");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_info(zc, "2.hello, zlog");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_put_mdc("myname", "Li");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_info(zc, "3.hello, zlog");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_fini();
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
return 0;
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
}
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
The configure file is
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ cat test_mdc.conf
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
[formats]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
mdc_format= "%d.%ms %-6V (%c:%F:%L) [%M(myname)] - %m%n"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
[rules]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
*.* >stdout; mdc_format
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
And the output is
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ ./test_mdc
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
2012-03-12 09:26:37.740 INFO (my_cat:test_mdc.c:47) [] - 1.hello, zlog
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
2012-03-12 09:26:37.740 INFO (my_cat:test_mdc.c:51) [Zhang] - 2.hello, zlog
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
2012-03-12 09:26:37.740 INFO (my_cat:test_mdc.c:55) [Li] - 3.hello, zlog
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
You can see zlog_put_mdc() function sets the map with key "myname" and value
|
|
|
"Zhang", and in configuration file
|
|
|
\emph on
|
|
|
%M(myname)
|
|
|
\emph default
|
|
|
indicates where the value shows in each log.
|
|
|
The second time, value of key "myname" is overwritten to "Li", and the
|
|
|
log changes also.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
When should MDC be used? That mainly depends on when a user need to separate
|
|
|
same log action with different scenarios.
|
|
|
For example, in .c
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_put_mdc("customer_name", get_customer_name_from_db() );
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_info("get in");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_info("pick product");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_info("pay");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_info("get out");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
in .conf
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
&format "%M(customer_name) %m%n"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
When the program processes two customers at the same time, the output could
|
|
|
be:
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
Zhang get in
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
Li get in
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
Zhang pick product
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
Zhang pay
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
Li pick product
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
Li pay
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
Zhang get out
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
Li get out
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Now you can distinguish one customer from another, by using grep afterwards
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ grep Zhang aa.log > Zhang.log
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ grep Li aa.log >Li.log
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Or, another way is to seperate them to different log file when log action
|
|
|
is taken.
|
|
|
In .conf
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
*.* "mdc_%M(customer_name).log";
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
It will produce 3 logs
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
mdc_.log mdc_Zhang.log mdc_Li.log
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
That's a quick way, if you know what you are doing.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
In MDC, the map belongs to a thread and each thread has it's own map.
|
|
|
In one thread zlog_mdc_put() will not affect other thread's map.
|
|
|
Still, if you want to distinguish one thread from another, using the %t
|
|
|
conversion character is enough.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Section
|
|
|
Profile zlog Itself
|
|
|
\begin_inset CommandInset label
|
|
|
LatexCommand label
|
|
|
name "sec:Profile-zlog-Itself"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Until this point we have assumed that the zlog library never fails.
|
|
|
It helps the application to write log entries and to debug the application.
|
|
|
But if zlog itself has some problem, how can we find out? Other programs
|
|
|
debug through the log library so how can a log library debug itself? The
|
|
|
answer is the same, zlog library has its own log.
|
|
|
This profile log is usually closed, and can be opened by setting environment
|
|
|
variables.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ export ZLOG_PROFILE_DEBUG=/tmp/zlog.debug.log
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ export ZLOG_PROFILE_ERROR=/tmp/zlog.error.log
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
profile log has just 2 levels, debug and error.
|
|
|
After setting them, run test_hello program in
|
|
|
\begin_inset CommandInset ref
|
|
|
LatexCommand ref
|
|
|
reference "sec:Hello-World-Example"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
, and the debug log will be
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ more zlog.debug.log
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
03-13 09:46:56 DEBUG (7503:zlog.c:115) ------zlog_init start, compile time[Mar
|
|
|
13 2012 11:28:56]------
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
03-13 09:46:56 DEBUG (7503:spec.c:825) spec:[0x7fdf96b7c010][%d(%F %T)][%F
|
|
|
%T 29][]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
03-13 09:46:56 DEBUG (7503:spec.c:825) spec:[0x7fdf96b52010][ ][ 0][]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
......
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
03-13 09:52:40 DEBUG (8139:zlog.c:291) ------zlog_fini end------
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
zlog.error.log is not created, as no error occurs.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
As you can see, debug log shows how zlog is inited and finished, but no
|
|
|
debug log is written when zlog_info() is executed.
|
|
|
That's for efficency.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
If there is anything wrong with zlog library, all will show in zlog.error.log.
|
|
|
For example, using a wrong printf syntax in zlog()
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_info(zc, "%l", 1);
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Then run the program, the zlog.error.log should be
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ cat zlog.error.log
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
03-13 10:04:58 ERROR (10102:buf.c:189) vsnprintf fail, errno[0]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
03-13 10:04:58 ERROR (10102:buf.c:191) nwrite[-1], size_left[1024], format[%l]
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
03-13 10:04:58 ERROR (10102:spec.c:329) zlog_buf_vprintf maybe fail or overflow
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
03-13 10:04:58 ERROR (10102:spec.c:467) a_spec->gen_buf fail
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
03-13 10:04:58 ERROR (10102:format.c:160) zlog_spec_gen_msg fail
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
03-13 10:04:58 ERROR (10102:rule.c:265) zlog_format_gen_msg fail
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
03-13 10:04:58 ERROR (10102:category.c:164) hzb_log_rule_output fail
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
03-13 10:04:58 ERROR (10102:zlog.c:632) zlog_output fail, srcfile[test_hello.c],
|
|
|
srcline[41]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Now, you could find the reason why the expected log doesn't generate, and
|
|
|
fix the wrong printf syntax.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Runtime profiling causes a loss of efficency.
|
|
|
Normally, I keep ZLOG_PROFILE_ERROR on and ZLOG_PROFILE_DEBUG off in my
|
|
|
environment.
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
There is another way to profile the zlog library.
|
|
|
zlog_init() reads the configuration file into memory.
|
|
|
Throughout all log actions, the configure structure remains unchanged.
|
|
|
There is possibility that this memory is damaged by other functions in
|
|
|
an application, or the memory doesn't equal what the configuration file
|
|
|
describes.
|
|
|
So there is a function to show this memory at runtime and print it to ZLOG_PROF
|
|
|
ILE_ERROR.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
see $(top_builddir)/test/test_profile.c
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ cat test_profile.c
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
#include <stdio.h>
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
#include "zlog.h"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
int main(int argc, char** argv)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
{
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
int rc;
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
rc = dzlog_init("test_profile.conf", "my_cat");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
if (rc) {
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
printf("init failed
|
|
|
\backslash
|
|
|
n");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
return -1;
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
}
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
dzlog_info("hello, zlog");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_profile();
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_fini();
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
return 0;
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
}
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
zlog_profile() is the function.
|
|
|
The configuration file is simple
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ cat test_profile.conf
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
[formats]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
simple = "%m%n"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
[rules]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
my_cat.* >stdout; simple
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Then zlog.error.log is
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ cat /tmp/zlog.error.log
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
06-01 11:21:26 WARN (7063:zlog.c:783) ------zlog_profile start------
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
06-01 11:21:26 WARN (7063:zlog.c:784) init_flag:[1]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
06-01 11:21:26 WARN (7063:conf.c:75) -conf[0x2333010]-
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
06-01 11:21:26 WARN (7063:conf.c:76) --global--
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
06-01 11:21:26 WARN (7063:conf.c:77) ---file[test_profile.conf],mtime[2012-06-01
|
|
|
11:20:44]---
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
06-01 11:21:26 WARN (7063:conf.c:78) ---strict init[1]---
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
06-01 11:21:26 WARN (7063:conf.c:79) ---buffer min[1024]---
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
06-01 11:21:26 WARN (7063:conf.c:80) ---buffer max[2097152]---
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
06-01 11:21:26 WARN (7063:conf.c:82) ---default_format---
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
06-01 11:21:26 WARN (7063:format.c:48) ---format[0x235ef60][default = %d(%F
|
|
|
%T) %V [%p:%F:%L] %m%n(0x233b810)]---
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
06-01 11:21:26 WARN (7063:conf.c:85) ---file perms[0600]---
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
06-01 11:21:26 WARN (7063:conf.c:87) ---rotate lock file[/tmp/zlog.lock]---
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
06-01 11:21:26 WARN (7063:rotater.c:48) --rotater[0x233b7d0][0x233b7d0,/tmp/zlog.
|
|
|
lock,4]--
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
06-01 11:21:26 WARN (7063:level_list.c:37) --level_list[0x2335490]--
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
06-01 11:21:26 WARN (7063:level.c:37) ---level[0x23355c0][0,*,*,1,6]---
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
06-01 11:21:26 WARN (7063:level.c:37) ---level[0x23375e0][20,DEBUG,debug,5,7]---
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
06-01 11:21:26 WARN (7063:level.c:37) ---level[0x2339600][40,INFO,info,4,6]---
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
06-01 11:21:26 WARN (7063:level.c:37) ---level[0x233b830][60,NOTICE,notice,6,5]-
|
|
|
--
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
06-01 11:21:26 WARN (7063:level.c:37) ---level[0x233d850][80,WARN,warn,4,4]---
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
06-01 11:21:26 WARN (7063:level.c:37) ---level[0x233fc80][100,ERROR,error,5,3]--
|
|
|
-
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Section
|
|
|
User-defined Level
|
|
|
\begin_inset CommandInset label
|
|
|
LatexCommand label
|
|
|
name "sec:User-defined-Level"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
Here are all the steps to define your own levels.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Enumerate
|
|
|
Define levels in the configuration file.
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
$ cat $(top_builddir)/test/test_level.conf
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
[global]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
default format = "%V %v %m%n"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
[levels]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
TRACE = 30, LOG_DEBUG
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
[rules]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
my_cat.TRACE >stdout;
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
The internal default levels are (no need to write them in the conf file):
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
DEBUG = 20, LOG_DEBUG
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
INFO = 40, LOG_INFO
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
NOTICE = 60, LOG_NOTICE
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
WARN = 80, LOG_WARNING
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
ERROR = 100, LOG_ERR
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
FATAL = 120, LOG_ALERT
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
UNKNOWN = 254, LOG_ERR
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
In zlog, an integer(30) and a level string(TRACE) represent a level.
|
|
|
Note that this integer must be in [1,253], any other number is illegal.
|
|
|
Higher numbers are more important.
|
|
|
TRACE is more important than DEBUG(30>20), and less important than INFO(30<40).
|
|
|
After the definition, TRACE can be used in rule of configure file.
|
|
|
This sentence
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
my_cat.TRACE >stdout;
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
means that level >= TRACE, which is TRACE, INFO, NOTICE, WARN, ERROR, FATAL
|
|
|
will be written to standard output.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
The conversion charactor %V of format string generates the uppercase value
|
|
|
of the level string and %v generates the lowercase value of the level string.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
In the level definition LOG_DEBUG means when using >syslog in a rule, all
|
|
|
TRACE log will output as syslog' s LOG_DEBUG level.
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Enumerate
|
|
|
Using the new log level in source file, the direct way is like this
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
zlog(cat, __FILE__, sizeof(__FILE__)-1,
|
|
|
\backslash
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
__func__, sizeof(__func__)-1,__LINE__,
|
|
|
\backslash
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
30, "test %d", 1);
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
For easy use, create a .h file
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
$ cat $(top_builddir)/test/test_level.h
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
#ifndef __test_level_h
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
#define __test_level_h
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
#include "zlog.h"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
enum {
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
ZLOG_LEVEL_TRACE = 30,
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
/* must equals conf file setting */
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
};
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
#define zlog_trace(cat, format, ...)
|
|
|
\backslash
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog(cat, __FILE__, sizeof(__FILE__)-1,
|
|
|
\backslash
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
__func__, sizeof(__func__)-1, __LINE__,
|
|
|
\backslash
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
ZLOG_LEVEL_TRACE, format, ## __VA_ARGS__)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
#endif
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Enumerate
|
|
|
Then zlog_trace can be used int .c file
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
$ cat $(top_builddir)/test/test_level.c
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
#include <stdio.h>
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
#include "test_level.h"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
int main(int argc, char** argv)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
{
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
int rc;
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_category_t *zc;
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
rc = zlog_init("test_level.conf");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
if (rc) {
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
printf("init failed
|
|
|
\backslash
|
|
|
n");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
return -1;
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
}
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zc = zlog_get_category("my_cat");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
if (!zc) {
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
printf("get cat fail
|
|
|
\backslash
|
|
|
n");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_fini();
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
return -2;
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
}
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_trace(zc, "hello, zlog - trace");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_debug(zc, "hello, zlog - debug");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_info(zc, "hello, zlog - info");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_fini();
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
return 0;
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
}
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Enumerate
|
|
|
Now we can see the output
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
$ ./test_level
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
TRACE trace hello, zlog - trace
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
INFO info hello, zlog - info
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
That's just what we expect.
|
|
|
The configuration file only allows >=TRACE ouput to screen.
|
|
|
And %V and %v work as well.
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Section
|
|
|
User-defined Output
|
|
|
\begin_inset CommandInset label
|
|
|
LatexCommand label
|
|
|
name "sec:User-defined-Output"
|
|
|
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
The goal of user-defined output is that zlog gives up some rights.
|
|
|
zlog is only responsible for generating path and message dynamically as
|
|
|
per the user's configuration, but leaves the log output, rotate and cleanup
|
|
|
actions for the user to specify.
|
|
|
You can do what ever you want by setting a function to special rules.
|
|
|
Here are the steps to define your own output function.
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Enumerate
|
|
|
Define output in rules of configure file.
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
$ cat test_record.conf
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
[formats]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
simple = "%m%n"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
[rules]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
my_cat.* $myoutput, " mypath %c %d";simple
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Enumerate
|
|
|
Set an output function for myoutput, then use it
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
#include <stdio.h>
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
#include "zlog.h"
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
int output(zlog_msg_t *msg)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
{
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
printf("[mystd]:[%s][%s][%ld]
|
|
|
\backslash
|
|
|
n", msg->path, msg->buf, (long)msg->len);
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
return 0;
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
}
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
int main(int argc, char** argv)
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
{
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
int rc;
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_category_t *zc;
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
rc = zlog_init("test_record.conf");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
if (rc) {
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
printf("init failed
|
|
|
\backslash
|
|
|
n");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
return -1;
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
}
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_set_record("myoutput", output);
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zc = zlog_get_category("my_cat");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
if (!zc) {
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
printf("get cat fail
|
|
|
\backslash
|
|
|
n");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_fini();
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
return -2;
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
}
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_info(zc, "hello, zlog");
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
zlog_fini();
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
return 0;
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
}
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Enumerate
|
|
|
Now we can see how the user-defined output() works
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout LyX-Code
|
|
|
$ ./test_record
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
[mystd]:[ mypath my_cat 2012-07-19 11:01:12][hello, zlog
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout LyX-Code
|
|
|
][12]
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
As you can see, msglen is 12, and msg is formatted by zlog to contain a
|
|
|
newline character.
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Enumerate
|
|
|
There are many other things you can do with user-defined output functions.
|
|
|
As one user(flw@newsmth.net) provided:
|
|
|
\begin_inset Separator latexpar
|
|
|
\end_inset
|
|
|
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_deeper
|
|
|
\begin_layout Enumerate
|
|
|
Log name is foo.log
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Enumerate
|
|
|
If foo.log is larger than 100M, then generate a new logfile which contains
|
|
|
all the contents of foo.log.
|
|
|
And zlog truncates foo.log to 0 and re-appends to it when the next log happens.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Enumerate
|
|
|
When the time is over 5 minutes after last logging, even if foo.log is not
|
|
|
larger than 100M, zlog still jumps to a new file.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Enumerate
|
|
|
The new file name should be defined by your own needs.
|
|
|
For example add device number as prefix and time string as postfix.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Enumerate
|
|
|
You might compress the new log file to save disk space and network bandwidth.
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Standard
|
|
|
I wish him good luck trying to write such a function for multi-process or
|
|
|
multi-thread cases!
|
|
|
\end_layout
|
|
|
|
|
|
\end_deeper
|
|
|
\begin_layout Chapter
|
|
|
Epilog
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Verse
|
|
|
Here's to alcohol, the cause of – and solution to – all life’s problems.
|
|
|
|
|
|
\end_layout
|
|
|
|
|
|
\begin_layout Right Address
|
|
|
Homer Simpson
|
|
|
\end_layout
|
|
|
|
|
|
\end_body
|
|
|
\end_document
|