某公司的应用程序的日志系统使用了log4cxx,我以前没有用个,现在摸索一下怎么使用。因为不同人的主机环境不一样,所以,我在模式的过程中也出现了各种其他的问题,现在将自己出现的问题总结一下。以备后续参考。
下载软件
需要三个,分别是apr、apr-util和log4cxx。以下是下载路径。
https://apr.apache.org/download.cgi
https://logging.apache.org/log4cxx/latest_stable/download.html
编译apr-1.7.0.tar.gz
解压缩apr-1.7.0.tar.gz
进入apr-1.7.0目录
./configure --prefix=$HOME
--prefix的参数的意思把目标的库文件安装到指定的目录
我这个是docker的容器,提示如下错误
rm: cannot remove 'libtoolT': No such file or directory
先安装一些原来系统中没有的工具
yum install autoconf automake libtool
然后再次运行上述configure,有的镜像就没有错误提示了,有的还有。如果还有,将configure文件中的RM='$RM'修改为 RM='$RM -f ',这个相当于是,如果删除失败,就不管他了。然后输入
make && make install
程序也能编译成功,此时会在$HOME/lib中放入编译好的库文件libapr-1.so等
编译apr-util-1.6.1.tar.gz
解压缩apr-util-1.6.1.tar.gz
进入apr-util-1.6.1.tar目录
./configure --prefix=$HOME -with-apr=$HOME
make
此时,程序会报错,提示信息如下:
apr_xml.c:35:19: fatal error: expat.h: No such file or directory
说明操作系统又缺少一个工具,安装它:
yum install expat-devel
make install
此时会在$HOME/lib中放入编译好的库文件libaprutil-1.so等
编译apache-log4cxx-0.11.0.tar.gz
解压缩apache-log4cxx-0.11.0.tar.gz
进入apache-log4cxx-0.11.0.tar
./configure --with-charset=utf-8 --with-apr=${HOME} --with-apr-util=${HOME}
会有如下错误
missing aclocal-1.16 -I ………… aclocal-1.16: command not found
可以输入 autoreconf -ivf 来解决
make && make install
然后就可以看到我们编译好的文件了,一共有两份。这个没有放到$HOME/lib中的原因就是上面的configure中没有添加--prefix的路径指定
sh-4.2# find / -name "*liblog4cxx*" -exec ls -l {} ;
-rw-r--r-- 1 root root 38329992 Apr 9 13:54 /usr/local/lib/liblog4cxx.a
-rw-r--r-- 1 root root 1039 Apr 9 13:54 /usr/local/lib/pkgconfig/liblog4cxx.pc
lrwxrwxrwx 1 root root 20 Apr 9 13:54 /usr/local/lib/liblog4cxx.so -> liblog4cxx.so.11.0.0
lrwxrwxrwx 1 root root 20 Apr 9 13:54 /usr/local/lib/liblog4cxx.so.11 -> liblog4cxx.so.11.0.0
-rwxr-xr-x 1 root root 14307728 Apr 9 13:54 /usr/local/lib/liblog4cxx.so.11.0.0
-rwxr-xr-x 1 root root 1039 Apr 9 13:54 /usr/local/lib/liblog4cxx.la
-rw-r--r-- 1 root root 1039 Apr 9 13:45 /root/download/apache-log4cxx-0.11.0/liblog4cxx.pc
-rw-r--r-- 1 root root 1029 Aug 6 2020 /root/download/apache-log4cxx-0.11.0/liblog4cxx.pc.in
-rw-r--r-- 1 root root 38329992 Apr 9 13:54 /root/download/apache-log4cxx-0.11.0/src/main/cpp/.libs/liblog4cxx.a
lrwxr-xr-x 1 root root 16 Apr 9 13:54 /root/download/apache-log4cxx-0.11.0/src/main/cpp/.libs/liblog4cxx.la -> ../liblog4cxx.la
-rw-r--r-- 1 root root 1039 Apr 9 13:54 /root/download/apache-log4cxx-0.11.0/src/main/cpp/.libs/liblog4cxx.lai
lrwxr-xr-x 1 root root 20 Apr 9 13:53 /root/download/apache-log4cxx-0.11.0/src/main/cpp/.libs/liblog4cxx.so -> liblog4cxx.so.11.0.0
lrwxr-xr-x 1 root root 20 Apr 9 13:53 /root/download/apache-log4cxx-0.11.0/src/main/cpp/.libs/liblog4cxx.so.11 -> liblog4cxx.so.11.0.0
-rwxr-xr-x 1 root root 14307728 Apr 9 13:53 /root/download/apache-log4cxx-0.11.0/src/main/cpp/.libs/liblog4cxx.so.11.0.0
-rw-r--r-- 1 root root 1038 Apr 9 13:54 /root/download/apache-log4cxx-0.11.0/src/main/cpp/liblog4cxx.la
写个代码来测试
在使用之前,按照c++开发的惯例,先把apache-log4cxx-0.11.0/src/main里面的include目录单独复制出来一份,放到我的工程的根目录下。如果不想复制也可以的,需要在编译的时候自行指定好include的路径。这两个方法的区别就是在编写代码的时候#include指令,需要用双引号或者尖括号。
这段代码参考了其他网友的。
#include "log4cxx/logger.h" #include "log4cxx/logstring.h" #include "log4cxx/propertyconfigurator.h" using namespace log4cxx; int main(int argc, char *argv[]) { // 读取配置文件 PropertyConfigurator::configure("log4cxx.properties"); // 建立两个logger LoggerPtr logger1 = Logger::getLogger(argv[0]); LOG4CXX_TRACE(logger1, "跟踪"); LOG4CXX_WARN(logger1, "警告"); LOG4CXX_DEBUG(logger1, "调试"); LOG4CXX_ASSERT(logger1, false, "断言"); LOG4CXX_FATAL(logger1, "致命"); return 0; }
编写日志文件,文件名称是log4cxx.properties
#设置rootlogger为DEBUG级别,使用了ca和fa两个Appender log4j.rootLogger=DEBUG,ca, fa #对Appender fa进行设置: #这是一个文件类型的Appender, #其输出文件(File)为./output.log, #输出方式(Append)为覆盖方式, #输出格式(layout)为PatternLayout log4j.appender.fa=org.apache.log4j.FileAppender log4j.appender.fa.File=./output.log log4j.appender.fa.Append=true log4j.appender.fa.layout=org.apache.log4j.PatternLayout log4j.appender.fa.layout.ConversionPattern=%d [%t] %-5p %c %l - %m%n #对Appender ca进行设置: #这是一个控制台类型的Appender #输出格式(layout)为PatternLayout log4j.appender.ca=org.apache.log4j.ConsoleAppender log4j.appender.ca.layout=org.apache.log4j.PatternLayout log4j.appender.ca.layout.ConversionPattern=%d [%t] %-5p %c %l - %m%n
在我的docker中的rhel7.3中,下面的命令是无法连接通过的。
sh-4.2# g++ log4cxx_main.cpp -o log4cxx_main -Wall -O3 -g3 -L /usr/local/lib/ -llog4cxx
/root/lib/libaprutil-1.so.0: undefined reference to `XML_ErrorString'
/root/lib/libaprutil-1.so.0: undefined reference to `XML_SetUserData'
/root/lib/libaprutil-1.so.0: undefined reference to `XML_ParserFree'
/root/lib/libaprutil-1.so.0: undefined reference to `XML_SetElementHandler'
/root/lib/libaprutil-1.so.0: undefined reference to `XML_SetCharacterDataHandler'
/root/lib/libaprutil-1.so.0: undefined reference to `XML_GetErrorCode'
/root/lib/libaprutil-1.so.0: undefined reference to `XML_SetEntityDeclHandler'
/root/lib/libaprutil-1.so.0: undefined reference to `XML_StopParser'
/root/lib/libaprutil-1.so.0: undefined reference to `XML_ParserCreate'
/root/lib/libaprutil-1.so.0: undefined reference to `XML_Parse'
我们把各种其他的库引用起来,它缺少对其他库的引用。实际上,libexpat是不在我单独自己指定的/root/lib中的,他是yum install expat-devel来安装后自己放到/lib64下的。可以通过ldconfig -p | grep expat这个命令来查找到。以下是完整的编译命令,而不管apr什么的它实际用不用:
g++ log4cxx_main.cpp -o log4cxx_main -Wall -O3 -g3 -L /usr/local/lib/ -llog4cxx -L/root/lib -lapr-1 -laprutil-1 -lexpat
修改运行库
因为我把apr和apr-uitl放在了自己指定的/root/lib中,把log4cxx放到了默认的/usr/local/lib/,所以要把这两个路径追加到运行库环境中,或者直接修改环境变量文件。
LD_LIBRARY_PATH=/usr/local/lib/:/root/lib:${LD_LIBRARY_PATH}
export LD_LIBRARY_PATH
运行程序
sh-4.2# ./log4cxx_main
2021-04-10 00:03:36,315 [0x7f1e42de4740] WARN ./log4cxx_main log4cxx_main.cpp(16) - 警告
2021-04-10 00:03:36,318 [0x7f1e42de4740] DEBUG ./log4cxx_main log4cxx_main.cpp(17) - 调试
2021-04-10 00:03:36,321 [0x7f1e42de4740] ERROR ./log4cxx_main log4cxx_main.cpp(18) - 断言
2021-04-10 00:03:36,323 [0x7f1e42de4740] FATAL ./log4cxx_main log4cxx_main.cpp(19) - 致命
此时,目录中有个output.log的日志文件,初次运行的时候,内容与上面一样。我的目录中的文件是:
sh-4.2# ls -lrt
total 156
drwxr-xr-x 7 1000 1000 224 Apr 9 13:45 include
-rw-r--r-- 1 root root 541 Apr 9 23:24 log4cxx_main.cpp
-rwxr-xr-x 1 root root 145152 Apr 9 23:24 log4cxx_main
-rw-r--r-- 1 root root 826 Apr 9 23:32 log4cxx.properties
-rw-r--r-- 1 root root 368 Apr 10 00:04 output.log