log4cpp日志无法分卷的解决方案



我们的项目采用log4cpp作为日志输出模块,但在使用中发现,如果是一个Services,或者是在Windows Server版本上,会出现日志无法正常分割的现象。即日志一直往一个文件里持续写,即使超过规定的文件大小,也不会分卷。

log4cpp中分割日志的核心算法为:(假设允许的最大文件个数为4)

1.关闭xxx.log.

2.删除 xxx.log.4

3.是一个loop, 将xxx.log.3--->xxx.log.4,xxx.log.2--->xxx.log.3,xxx.log.1----->xxx.log.2

4.将xxx.log--->xxx.log.1

5.打开xxx.log.

相关代码为:

void RollingFileAppender::rollOver() {
      ::close(_fd); // 1
      if (_maxBackupIndex > 0) {
           std::ostringstream oldName;
           oldName << _fileName << "." << _maxBackupIndex << std::ends;
           ::remove(oldName.str().c_str());   //2

           size_t n = _fileName.length() + 1;
           for(unsigned int i = _maxBackupIndex; i > 1; i--) {  //3
                 std::string newName = oldName.str();
                 oldName.seekp(n);
                 oldName << i-1 << std::ends;
                 ::rename(oldName.str().c_str(), newName.c_str());
            }

           ::rename(_fileName.c_str(), oldName.str().c_str()); //4
      }
      _fd = ::open(_fileName.c_str(), _flags, _mode);//5
}

void RollingFileAppender::rollOver() {
      ::close(_fd); // 1
      if (_maxBackupIndex > 0) {
           std::ostringstream oldName;
           oldName << _fileName << "." << _maxBackupIndex << std::ends;
           ::remove(oldName.str().c_str());   //2  

           size_t n = _fileName.length() + 1;
           for(unsigned int i = _maxBackupIndex; i > 1; i--) {  //3
                 std::string newName = oldName.str();
                 oldName.seekp(n);
                 oldName << i-1 << std::ends;
                 ::rename(oldName.str().c_str(), newName.c_str());
            }  

           ::rename(_fileName.c_str(), oldName.str().c_str()); //4
      }
      _fd = ::open(_fileName.c_str(), _flags, _mode);//5
}

日志文件无法分割(目前发现只在win server版本无法work),原因出在步骤1,4,5上,

关闭文件后,随后将文件重命名,会导致重命名失败。通过打印错误码得知,错误码为32,意思为:文件句柄被占用。

解决方案为,往两个不同的文件里中写日志,不再只往一个文件名里写日志,交替写日志,交替关闭文件。write(A),close(B)---->Write(B),Close(A),----->Write(A),Close(B).

void RollingFileAppender::rollOver() {
        ::close(_fd);
        if (_maxBackupIndex > 0) {
            std::ostringstream oldName;
            oldName << _fileName << "." << _maxBackupIndex << std::ends;
            ::remove(oldName.str().c_str());
			size_t n = _fileName.length() + 1;
            for(unsigned int i = _maxBackupIndex; i > 1; i--) {
            	std::string newName = oldName.str();
				oldName.seekp(n);

                oldName << i-1 << std::ends;
                ::rename(oldName.str().c_str(), newName.c_str());
            }
if(_bUsingTempFile)
            ::rename(_fileNameTmp.c_str(), oldName.str().c_str());
else
            ::rename(_fileName.c_str(), oldName.str().c_str());
        }
if(_bUsingTempFile)
        _fd = ::open(_fileName.c_str(), _flags, _mode);
else
		_fd = ::open(_fileNameTmp.c_str(), _flags, _mode);
		_bUsingTempFile = !_bUsingTempFile;
    }

修改后的代码为:

void RollingFileAppender::rollOver() {
        ::close(_fd);
        if (_maxBackupIndex > 0) {
            std::ostringstream oldName;
            oldName << _fileName << "." << _maxBackupIndex << std::ends;
            ::remove(oldName.str().c_str());
            size_t n = _fileName.length() + 1;
            for(unsigned int i = _maxBackupIndex; i > 1; i--) {
                std::string newName = oldName.str();
                oldName.seekp(n);  

                oldName << i-1 << std::ends;
                ::rename(oldName.str().c_str(), newName.c_str());
            }
if(_bUsingTempFile)
            ::rename(_fileNameTmp.c_str(), oldName.str().c_str());
else
            ::rename(_fileName.c_str(), oldName.str().c_str());
        }
if(_bUsingTempFile)
        _fd = ::open(_fileName.c_str(), _flags, _mode);
else
        _fd = ::open(_fileNameTmp.c_str(), _flags, _mode);
        _bUsingTempFile = !_bUsingTempFile;
    }
时间: 2024-10-30 01:40:09

log4cpp日志无法分卷的解决方案的相关文章

log4cpp日志不能是溶液子体积

 我们的项目用途log4cpp由于日志输出模块,但在使用中发现,假设Services,或者是在Windows Server版本号.不会有一个正常的日志切削现象.该日志已被写入到文件中,持续,即使超过规定的文件大小.也不会分卷. log4cpp中切割日志的核心算法为:(如果同意的最大文件个数为4) 1.关闭xxx.log. 2.删除 xxx.log.4 3.是一个loop, 将xxx.log.3--->xxx.log.4,xxx.log.2--->xxx.log.3,xxx.log.1---

Jenkins日志文件过大解决方案

一.写定时任务删除日志文件 # crontab -e * * * * */1 rm -rf /var/log/jenkins/* 二.修改jenkins日志的级别 解决方案1:使用java.util.logging:创建一个文件logging.properties,您可以在其中定义日志级别和ConsoleHandler.然后通过添加系统属性-Djava.util.logging.config.file = <pathTo> /logging.properties将此文件传递给JVM . 像下面

使用Slf4j集成Log4j2构建项目日志系统的完美解决方案

一.背景 最近因为公司项目性能需要,我们考虑把以前基于的log4j的日志系统重构成基于Slf4j和log4j2的日志系统,因为,使用slf4j可以很好的保证我们的日志系统具有良好的兼容性,兼容当前常见几种日志系统,而使用log4j2而不是log4j是因为Log4j 1.x 在高并发情况下出现死锁导致cpu使用率异常飙升,而Log4j2.0基于LMAX Disruptor的异步日志在多线程环境下性能会远远优于Log4j 1.x和logback(官方数据是10倍以上). 关于slf4j的原理以及优点

出现“System.Data.SqlClient.SqlError: 尚未备份数据库的日志尾部”错误的解决方案

Sql Server2008数据库在还原时出现如下错误信息:System.Data.SqlClient.SqlError: 尚未备份数据库<数据库名称>的日志尾部.如果该日志包含您不希望丢失的工作,请使用 BACKUP LOG WITH NORECOVERY 备份该日志.请使用 RESTORE 语句的 WITH REPLACE 或 WITH STOPAT 子句来只覆盖该日志的内容. (Microsoft.SqlServer.Smo) 经过网上查阅的资料,有两种方法可以解决,只需要在还原的时候使

pomelo配置logger时日志无法输出到日志文件的问题解决方案

在使用pomelo的过程中发现log4js的日志无法输出到日志文件,解决办法如下: 1.删除工程目录下 ./node_modules/pomelo/node_modules/pomelo-logger 文件夹 2.修改工程目录下 ./node_modules/pomelo/package.json 文件,找到dependencies中的pomelo-logger,并删除改行 同时还发现,pomelo-admin中的日志也是无法输出到日志文件,解决办法类似: 1.删除工程目录下 ./node_mo

log4cpp 日志库

说明 log4cpp编译安装的路径是/opt/log4cpp 问题:如何正确引入动态库 1.修改/etc/ld.so.conf文件,将/opt/log4cpp/lib添加到文件末尾,该文件主要被ldconfig指令用来搜索可共享的动态链接库 2.执行ldconfig,根据修改的文件内容,创建出动态装入程序所需的连接和缓存文件,提供给系统动态库调用 手动: g++ test.cpp -I/opt/log4cpp/include -L/opt/log4cpp/lib/ -llog4cpp -lpth

ELK+Filebeat 集中式日志解决方案详解

原文:ELK+Filebeat 集中式日志解决方案详解 链接:https://www.ibm.com/developerworks/cn/opensource/os-cn-elk-filebeat/index.html?ca=drs- ELK Stack 简介 ELK 不是一款软件,而是 Elasticsearch.Logstash 和 Kibana 三种软件产品的首字母缩写.这三者都是开源软件,通常配合使用,而且又先后归于 Elastic.co 公司名下,所以被简称为 ELK Stack.根据

Zookeeper 日志输出到指定文件夹

最近在研究Zookeeper Storm Kafka, 顺便在本地搭了一套集群, 遇到了Zookeeper日志问题输出路径的问题, 发现zookeeper设置log4j.properties不能解决日志路径问题, 发现解决方案如下: 1. 修改log4j.properties, 这个大家都应该会改, 红色加粗处是我修改的, 但是改了这边还是不生效 # Define some default values that can be overridden by system properties zo

LISTENER.LOG日志大小不能超过2GB

oracle 11G  windows 2008系统  造成了监听死锁 报TNS-00505: 操作超时 最后分析 发现 LISTENER.LOG日志大小超过2GB 解决方案: cd$ORACLE_HOME/network/log lsnrctlset log_status off mvlistener.log listener.bak lsnrctlset log_status on 以下是我在gdimall2上的一个操作记录: 首先改变监听的日志记录状态: $lsnrctlset log_s