Reprint please indicate the source: http://blog.csdn.net/jmppok/article/details/17375057
1. The question
When a C + + program is running in the background, logs can be logged by Log4cplus. When a C + + program is running on a remote server, we need to log on remotely to the server to view the logs. Further, if the C + + program is a parallel program or a distributed program, in order to view the running state of the program, we need to log on to n servers, tail-f Xx.log. This situation sounds very unpleasant, and in fact, many server-side developers have encountered or are suffering from this problem.
2.LoggingServer
As a replica of log4j, Log4cplus also provides Sockeappender, which can be resolved by outputting logs to a specified log server through Socketappender.
For an introduction to Log4cplus, please refer to C + + open source Log library Log4cplus
In the Log4cplus source package, there is a loggingserver directory in which a loggingserver is implemented.
When you compile Log4cplus, the directory is automatically compiled, the Loggingserver executable is generated in the directory, and you can make it yourself (you need to rely on the Log4cplus library).
Loggingserver use is as follows:
./loggingserver 9000 Log4cplus.properties
9000 indicates the listener port number (no address required, default listener native address)
Log4cplus.properties is a log4cplus configuration file, the same as the normal Log4cplus profile, Loggingserver receives the log from each socket and writes it to the file according to the profile information.
The following is an example of a simple configuration file:
Log4cplus.rootlogger=debug, STDOUT, All_msgs Log4cplus.appender.stdout=log4cplus::consoleappender Log4cplus.appender.stdout.layout=log4cplus::P atternlayout #log4cplus. appender.stdout.layout.conversionpattern=% D{%m/%d/%y%h:%m:%s} [%t]%-5p%c{2}%%%x%%-%m [%l]%n log4cplus.appender.stdout.layout.conversionpattern=[%-5p%d{%y-% m-%d%h:%m:%s}] [%l]%n%m%n%n #设置日志追加到文件尾 log4cplus.appender.all_msgs=log4cplus::rollingfileappender #设置日志文件大小 LOG4CP Lus.appender.ALL_MSGS. MAXFILESIZE=100MB #设置生成日志最大个数 Log4cplus.appender.ALL_MSGS. maxbackupindex=10 #设置输出日志路径 Log4cplus.appender.ALL_MSGS. File=log/test.log log4cplus.appender.all_msgs.layout=log4cplus::P atternlayout #设置日志打印格式 #log4cplus. Appender.all_ msgs.layout.conversionpattern=|%d:%d{%q}|%p|%t|%l|%m|%n log4cplus.appender.all_msgs.layout.conversionpattern=[% -5p%d{%y-%m-%d%h:%m:%s}] [%l]%n%m%n%n #匹配相同日志级别, only the debug log is entered in the file #log4cplus. appender.all_msgs.filters.1= Log4cplus::spi::loglevelmatchfilter #log4cplus. Appender.debug_msgs.filters.1.logLeveltomatch=debug #log4cplus. Appender.debug_msgs.filters.1.acceptonmatch=true #log4cplus. Appender.debug_ MSGS.FILTERS.2=LOG4CPLUS::SPI::D enyallfilter
Loggingserver itself is very simple, the code is as follows (of course, if you feel it is uncomfortable, you can also achieve a more cool):
Module:log4cplus//FILE:LOGGINGSERVER.CXX//created:5/2003//Author:tad E. Smith/////Copyright 2003-20
Tad E. Smith////licensed under the Apache License, Version 2.0 (the "License");
You are not to use this file except in compliance with the License. Obtain a copy of the License at////http://www.apache.org/licenses/LICENSE-2.0////unless required by a Pplicable or agreed to in writing, software//distributed under the License was distributed on ' as is ' basis,//WI
Thout warranties or CONDITIONS of any KIND, either express or implied.
The License for the specific language governing permissions and//limitations under the License. #include <cstdlib> #include <iostream> #include <log4cplus/configurator.h> #include <log4cplus/ socketappender.h> #include <log4cplus/helpers/socket.h> #include <log4cplus/thread/threads.h> # Include <log4cplus/spi/loggingevent.h> namespace Loggingserver {CLASS Clientthread:public Log4cplus::thread::abstractthread {public:clientthread (log4cplus::helpers::socket Clientsoc
k): Clientsock (clientsock) {std::cout << "Received a client connection!!!!" << Std::endl;
} ~clientthread () {std::cout << "Client connection closed." << Std::endl;
virtual void run ();
Private:log4cplus::helpers::socket Clientsock;
}; int main (int argc, char** argv) {if (ARGC < 3) {std::cout << "Usage:port config_file" << ;
Std::endl;
return 1;
int port = std::atoi (argv[1]);
Const log4cplus::tstring configfile = log4cplus_c_str_to_tstring (argv[2]);
Log4cplus::P ropertyconfigurator config (configfile);
Config.configure ();
Log4cplus::helpers::serversocket ServerSocket (port); if (!serversocket.isopen ()) {Std::cout << "could not open server socket, maybe port" << Port << "is AlreAdy in use. "<< Std::endl;
return 2; while (1) {Loggingserver::clientthread *thr = new Loggingserver::clientthread (SERVERSOCKET.ACC
EPT ());
Thr->start ();
return 0; }//////////////////////////////////////////////////////////////////////////////////Loggingserver::ClientThread
Implementation////////////////////////////////////////////////////////////////////////////////void
Loggingserver::clientthread::run () {while (1) {if (!clientsock.isopen ()) {return;
} log4cplus::helpers::socketbuffer msgsizebuffer (sizeof (unsigned int));
if (!clientsock.read (Msgsizebuffer)) {return;
} unsigned int msgsize = Msgsizebuffer.readint ();
Log4cplus::helpers::socketbuffer buffer (msgsize);
if (!clientsock.read (buffer)) {return; } log4cplus::spi::internalloggingevent event = Log4cplus::helpers::Readfrombuffer (buffer);
Log4cplus::logger Logger = log4cplus::logger::getinstance (Event.getloggername ());
Logger.callappenders (event);
}
}
3. Socketappender Configuration in Application
Loggingserver was started earlier, and the following is the configuration for each application that needs to collect its logs.
To put it bluntly, the original based on a socketappender,socketappender will automatically send the log to Loggingserver. This allows you to view log information on all servers directly on the loggingserver. Brother finally no longer worry about your running state.
Log4cplus.rootlogger=debug, STDOUT, All_msgs,remoteserver Log4cplus.appender.stdout=log4cplus::consoleappender Log4cplus.appender.stdout.layout=log4cplus::P atternlayout #log4cplus. appender.stdout.layout.conversionpattern=% D{%m/%d/%y%h:%m:%s} [%t]%-5p%c{2}%%%x%%-%m [%l]%n log4cplus.appender.stdout.layout.conversionpattern=[%-5p%d{%y-% m-%d%h:%m:%s}] [%l]%n%m%n%n #设置日志追加到文件尾 log4cplus.appender.all_msgs=log4cplus::rollingfileappender #设置日志文件大小 LOG4CP Lus.appender.ALL_MSGS. MAXFILESIZE=100MB #设置生成日志最大个数 Log4cplus.appender.ALL_MSGS. maxbackupindex=10 #设置输出日志路径 Log4cplus.appender.ALL_MSGS. File=log/test.log log4cplus.appender.all_msgs.layout=log4cplus::P atternlayout #设置日志打印格式 #log4cplus. Appender.all_ msgs.layout.conversionpattern=|%d:%d{%q}|%p|%t|%l|%m|%n log4cplus.appender.all_msgs.layout.conversionpattern=[% -5p%d{%y-%m-%d%h:%m:%s}] [%l]%n%m%n%n #匹配相同日志级别, only the debug log is entered in the file #log4cplus. appender.all_msgs.filters.1= Log4cplus::spi::loglevelmatchfilter #log4cplus. Appender.debug_msgs.Filters.1.logleveltomatch=debug #log4cplus. Appender.debug_msgs.filters.1.acceptonmatch=true # LOG4CPLUS.APPENDER.DEBUG_MSGS.FILTERS.2=LOG4CPLUS::SPI::D enyallfilter log4cplus.appender.remoteserver=log4cplus
:: Socketappender log4cplus.appender.remoteserver.host=localhost log4cplus.appender.remoteserver.port=9000
The remoteserver and last three lines of the first line above add a socketappender. Send the log to the remote Loggingserver.
Of course, there is no effect on local log records, and local records are still normal.
At the same time, we can set multiple remoetserver ... but it doesn't seem to be necessary ...
4. Higher-end atmospheric grade
Of course, we can achieve their own loggingserver, more high-end atmospheric grade.
A. Store logs from different clients separately;
B. Different levels of log storage alone;
C. Notification of mails when errors are found;
D. Implementation of a B/s log browsing tool;
E. Log warehousing;
F. Deposit in HDFs, mining with Hadoop map/reduce;
G. Access storm (Real-time flow processing framework) for its analysis;
...