log4cplus server client模式

在多进程使用log4cplus同时向一个日志文件写的时候,官方的FAQ建议使用SoskcetAppender, 即以server client模式来写日志,保证写日志同步。

写了一个小程序,fork出一个server进程,和5个client进程来写日志,当日志大小到达4G的时候做切割。

/*
 * =====================================================================================
 *
 *       Filename:  multiprocesslog.cpp
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  11/15/2011 02:48:44 PM
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Xu Zhe Ming, 
 *        Company:  
 *
 * =====================================================================================
 */

#include <log4cplus/fileappender.h>
#include <log4cplus/socketappender.h>
#include <log4cplus/consoleappender.h>
#include <log4cplus/layout.h>
#include <time.h>
#include <log4cplus/configurator.h>
#include <iomanip>
#include <log4cplus/logger.h>
#include <log4cplus/loglevel.h>
#include <log4cplus/helpers/socket.h>
#include <stdio.h>
#include <string>

using namespace log4cplus;
using namespace std;
using namespace log4cplus::helpers;

//server端
int log_server(int port)
{
    //创建一个socket,绑定端口
    helpers::ServerSocket serverSocket(port);
    Logger debug_logger;
    Logger info_logger;

    //注意int会溢出
    long log_size = long(1024) * 1024 * 1024 * 4;

    //初始化一个debug logger,并绑定到一个文件
    {
	SharedAppenderPtr pFileAppender_normal(new RollingFileAppender(("log_file_debug") , log_size, 10));
	debug_logger = Logger::getInstance("debug_logger");
	debug_logger.addAppender(pFileAppender_normal);
    }

    //初始化一个info logger,并绑定到一个文件
    {
	SharedAppenderPtr pFileAppender_normal(new RollingFileAppender(("log_file_info") , log_size, 10));
	info_logger = Logger::getInstance("info_logger");
	info_logger.addAppender(pFileAppender_normal);
    }

    //初始化其他的logger,如warn, error, fatal
    //...

    while(1)
    {
	//accept
	helpers::Socket clientsock = serverSocket.accept();
	SocketBuffer msgSizeBuffer(sizeof(unsigned int));
	if(!clientsock.read(msgSizeBuffer))
	{
	    return 0;
	}
	unsigned int msgSize = msgSizeBuffer.readInt();
	SocketBuffer buffer(msgSize);
	//读取日志消息到buffer
	if(!clientsock.read(buffer))
	{
	    return 0;
	}
	
	//转化成event
	spi::InternalLoggingEvent event = readFromBuffer(buffer);
	int level = event.getLogLevel();
	//判断日志的level
	if(level == DEBUG_LOG_LEVEL)
	{
	    debug_logger.callAppenders(event);
	}
	else if(level == INFO_LOG_LEVEL)
	{
	    info_logger.callAppenders(event);
	}
	//...
    }

    return 0;
}

//client端
int log_client(string server_ip, int server_port)
{
    SharedAppenderPtr _append(new SocketAppender(server_ip, server_port, "ServerName"));
    Logger::getRoot().addAppender(_append);
    while(1)
    {
	int rand_num = rand();
	int remainder = rand_num % 2;
	if (remainder == 0)
	    LOG4CPLUS_INFO(Logger::getRoot(), "client logging event number ... ");
	else
	    LOG4CPLUS_DEBUG(Logger::getRoot(), "client logging odd number... ");
	//sleep(1);
    }
}


int main()
{
    
    pid_t pid = fork();
    
    //child, let's run a log server process
    if(pid == 0)
    {
	log_server(20000);
    }
    //parent, let's fork some more processes to write logs
    else
    {
	for(int i = 0; i < 5; i++)
	{
	    pid = fork();
	    //child, let's run a log client process
	    if(pid == 0)
	    {
		log_client("localhost", 20000);
	    }
	}
    }

    while(1)
    {
	sleep(1);
    }

    return 0;
}


你可能感兴趣的:(log4cplus server client模式)