⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nlfileappender.cpp

📁 一些unix下的c/c++的util包
💻 CPP
字号:
/**
 * 附加器附加类实现
 * @file NLFileAppender.cpp
 * @date 14-Jul-2005
 * @author 胡春雨
 * @version 1.0.0: 初始版本
 */

#include "nlkit/NLFileAppender.h"
#include <dirent.h>
#include <iostream>
#include <sstream>
#include <ctype.h>
#include <unistd.h>
#include <algorithm>

using namespace std;


#define MINIMUM_ROLLING_LOG_SIZE 200*1024L		/**< 最小的循环文件大小定义 */
namespace nlkit
{
void rolloverFiles(const string& filename, unsigned int maxBackupIndex)
{
	ostringstream buffer;
	buffer << filename << "." << maxBackupIndex;
	remove(buffer.str().c_str());

	for (int i=maxBackupIndex - 1; i >= 1; i--)
	{
		ostringstream source;
		ostringstream target;

		source << filename << "." << i;
		target << filename << "." << (i+1);
		rename(source.str().c_str(), target.str().c_str());
	}
}

NLFileAppender::NLFileAppender(const string& filename, 
		const char* type, bool immediateFlush, bool withAdorn)
	: m_immediateFlush(immediateFlush), m_withAdorn(withAdorn)
{
	init(filename, type);
}

void NLFileAppender::init(const string& filename, const char* type)
{
	m_filename = filename;
	m_out = fopen(filename.c_str(), type);

	if (m_out == NULL)
	{
		getErrorHandler()->error("Unable to open file: " + filename);
		return;
	}
}

void NLFileAppender::reopen(const string& filename, const char* type)
{
	fclose(m_out);

	remove(m_filename.c_str());

	m_out = fopen(filename.c_str(), type);

	if (m_out == NULL)
	{
		getErrorHandler()->error("Unable to open file: " + filename);
		return;
	}
}

NLFileAppender::~NLFileAppender()
{
	destructorImpl();
}

void NLFileAppender::close()
{
	fclose(m_out);
	m_out = NULL;
	m_closed = true;
}

void NLFileAppender::append(const NLEvent& event)
{
	if(m_out == NULL)
	{
		getErrorHandler()->error("appender's out is not opened");
		return;
	}

	ostringstream os;
    m_layout->format(os, event);
    /*
	if (m_withAdorn)
	{
        
		os << event.getTimestamp().getFormattedTime("%Y-%m-%d %H:%M:%S.%%q");
		os << " [" << getpid() ;
        if (NULL != event.getAdornHandle())
            os << ":" << event.getAdornHandle()->message();
        os << "] " << NLLogLevelName[event.getNLLogLevel()] << " - " << event.getMessage();
        if (0 != event.getFile().size())
		{
			os << " [" << event.getFile() << ":" << event.getLine() << "]";
		}
	}
	else
	{
		os << event.getMessage();
	}

	os << endl;*/
	fprintf(m_out, "%s", os.str().c_str());

	if (m_immediateFlush)
	{
		fflush(m_out);
	}
}

NLRollingFileAppender::NLRollingFileAppender(const string& filename,
		long long maxFileSize,
		int maxBackupIndex,
		bool immediateFlush,
		bool withAdorn)
	: NLFileAppender(filename, "a", immediateFlush, withAdorn)
{
	init(maxFileSize, maxBackupIndex);
}

void NLRollingFileAppender::init(long long maxFileSize, int maxBackupIndex)
{
	m_maxFileSize = maxFileSize > (long long)MINIMUM_ROLLING_LOG_SIZE ? maxFileSize : (long long)MINIMUM_ROLLING_LOG_SIZE;
	m_maxBackupIndex = max(maxBackupIndex, 1);
}

NLRollingFileAppender::~NLRollingFileAppender()
{
	destructorImpl();
}

void NLRollingFileAppender::append(const NLEvent& event)
{
	if(m_out == NULL)
	{
		getErrorHandler()->error("appender's out is not opened");
		return;
	}

	ostringstream os;
    m_layout->format(os, event);
    /*
	if (m_withAdorn)
	{
		os << event.getTimestamp().getFormattedTime("%Y-%m-%d %H:%M:%S.%%q");
		os << " [" << getpid() ;
        if (NULL != event.getAdornHandle())
            os << ":" << event.getAdornHandle()->message();
        os << "] " << NLLogLevelName[event.getNLLogLevel()] << " - " << event.getMessage();        
		if (0 != event.getFile().size())
		{
			os << " [" << event.getFile() << ":" << event.getLine() << "]";
		}
	}
	else
	{
		os << event.getMessage();
	}
    
	os << endl;
	*/
	fprintf(m_out, "%s", os.str().c_str());

	if (m_immediateFlush)
	{
		fflush(m_out);
	}

	if (ftell(m_out) > m_maxFileSize)
	{
		rollover();
	}
}

void NLRollingFileAppender::rollover()
{
	if (m_maxBackupIndex > 0)
	{
		rolloverFiles(m_filename, m_maxBackupIndex);

		fclose(m_out);

		string target = m_filename + ".1";
		rename(m_filename.c_str(), target.c_str());

		m_out = fopen(m_filename.c_str(), "a");
	}
	else
	{
		fclose(m_out);

		m_out = fopen(m_filename.c_str(), "w");
	}
}

NLDailyRollingFileAppender::NLDailyRollingFileAppender(const string& filename,
		NLDailyRollingSchedule schedule,
		bool immediateFlush,
		int maxBackupIndex,
		bool withAdorn)
	: NLFileAppender(filename, "a", immediateFlush, withAdorn),
	  m_maxBackupIndex(maxBackupIndex)
{
	init(schedule);
}

void NLDailyRollingFileAppender::init(NLDailyRollingSchedule schedule)
{
	m_schedule = schedule;

	NLTime now = NLTime::gettimeofday();
	NLTime::setCalculateBeginTime(now, m_schedule);

	m_scheduledFilename = getFilename(now);
	m_nextRolloverTime = NLTime::calculateNextRolloverTime(now, m_schedule);
}

NLDailyRollingFileAppender::~NLDailyRollingFileAppender()
{
	destructorImpl();
}

void NLDailyRollingFileAppender::close()
{
	rollover();
	NLFileAppender::close();
}

void NLDailyRollingFileAppender::append(const NLEvent& event)
{
	if (m_out == NULL)
	{
		getErrorHandler()->error("file is not open: " + m_filename);
		return;
	}

	if (NLTime::getCalculateBeginTime(event.getTimestamp(), m_schedule) >= m_nextRolloverTime)
    {
		rollover();
	}

	ostringstream os;
    m_layout->format(os, event);
    /*
	if (m_withAdorn)
	{
		os << event.getTimestamp().getFormattedTime("%Y-%m-%d %H:%M:%S.%%q");
		os << " [" << getpid() ;
        if (NULL != event.getAdornHandle())
            os << ":" << event.getAdornHandle()->message();
        os << "] " << NLLogLevelName[event.getNLLogLevel()] << " - " << event.getMessage();        
		if (0 != event.getFile().size())
		{
			os << " [" << event.getFile() << ":" << event.getLine() << "]";
		}
	}
	else
	{
		os << event.getMessage();
	}

	os << endl;*/
	fprintf(m_out, "%s", os.str().c_str());

	if (m_immediateFlush)
	{
		fflush(m_out);
	}
}

void NLDailyRollingFileAppender::rollover()
{
	fclose(m_out);

	rolloverFiles(m_scheduledFilename, m_maxBackupIndex);
	ostringstream backupTarget;
	backupTarget << m_scheduledFilename << "." << 1;

	rename(m_scheduledFilename.c_str(), backupTarget.str().c_str());
	
	rename(m_filename.c_str(), m_scheduledFilename.c_str());

	m_out = fopen(m_filename.c_str(), "a");

	NLTime now = NLTime::gettimeofday();

	for (; now >= m_nextRolloverTime; )
	{
		m_nextRolloverTime = NLTime::calculateNextRolloverTime(m_nextRolloverTime, m_schedule);
	}

	m_nextRolloverTime = NLTime::calculateNextRolloverTime(m_nextRolloverTime, m_schedule, -1);

	m_scheduledFilename = getFilename(m_nextRolloverTime);
}

string NLDailyRollingFileAppender::getFilename(const NLTime& t) const
{
	string pattern;
	switch (m_schedule)
	{
	case MONTHLY:
		pattern = "%Y-%m";
		break;

	case WEEKLY:
		pattern = "%Y-%W";
		break;

	case DAILY:
		pattern = "%Y-%m-%d";
		break;

	case TWICE_DAILY:
		pattern = "%Y-%m-%d-%p";
		break;

	case HOURLY:
		pattern = "%Y-%m-%d-%H";
		break;

	case MINUTELY:
		pattern = "%Y-%m-%d-%H-%M";
		break;
	};

	return m_filename + "." + t.getFormattedTime(pattern, false);
}

NLParallelFileAppender::NLParallelFileAppender(const string& filename,
		NLDailyRollingSchedule schedule,
		bool immediateFlush,
		long long maxFileSize,
		int maxBackupIndex,
		bool withAdorn)
	: NLDailyRollingFileAppender(filename, schedule, immediateFlush, maxBackupIndex, withAdorn),
	  m_maxFileSize(maxFileSize),
	  m_curIdx(0)
{
	init();
}

NLParallelFileAppender::~NLParallelFileAppender()
{
	destructorImpl();
}

void NLParallelFileAppender::close()
{
	rollover(CLOSE_SWITCH);
	NLFileAppender::close();
}

void NLParallelFileAppender::rollover(switchtype type)
{
	fclose(m_out);

	switch (type)
	{
		case SIZE_SWITCH:
//		case CLOSE_SWITCH:
		{
			ostringstream newTarget;
			newTarget << m_scheduledFilename << "." << ++m_curIdx;
			m_out = ::fopen(newTarget.str().c_str(), "a");
		}
		break;

		case TIME_SWITCH:
		{
			NLTime now = NLTime::gettimeofday();

			for (; now >= m_nextRolloverTime; )
			{
				m_nextRolloverTime = NLTime::calculateNextRolloverTime(m_nextRolloverTime, m_schedule);
			}
		
			//date:2006.3.24
			//delete by mzh
			//下面的语句多减去了1个m_schedule的数值,那样m_nextRolloverTime就<=now,就会一直触发时间切换
			//m_nextRolloverTime = NLTime::calculateNextRolloverTime(m_nextRolloverTime, m_schedule, -1);

			//date:2006.3.29
			//modify by mzh,文件名称格式应取当前时间
			m_scheduledFilename = getFilename(now);
			m_out = ::fopen(m_scheduledFilename.c_str(), "a");
			m_curIdx = 0;
		}
		break;
	}
}

void NLParallelFileAppender::append(const NLEvent& event)
{
	if(m_out == NULL)
	{
		getErrorHandler()->error("file is not open: " + m_filename);
		return;
	}

	if (NLTime::getCalculateBeginTime(event.getTimestamp(), m_schedule) >= m_nextRolloverTime)
    {
		rollover(TIME_SWITCH);
	}

	ostringstream os;
    m_layout->format(os, event);
    /*
	if (m_withAdorn)
	{
		if (m_schedule < DAILY) //日志切换周期大于一天,在日志中显示日期
            os << event.getTimestamp().getFormattedTime("%Y-%m-%d %H:%M:%S.%%q");
        else
            os << event.getTimestamp().getFormattedTime("%H:%M:%S.%%Q");
		os << " [" << getpid() ;
        if (NULL != event.getAdornHandle())
            os << ":" << event.getAdornHandle()->message();
        os << "] " << NLLogLevelName[event.getNLLogLevel()] << " - " << event.getMessage();
		if (0 != event.getFile().size())
		{
			os << " [" << event.getFile() << ":" << event.getLine() << "]";
		}
	}
	else
	{
		os << event.getMessage();
	}
	os << endl;*/
	fprintf(m_out, "%s", os.str().c_str());

	if (m_immediateFlush)
	{
		fflush(m_out);
	}
	if (ftell(m_out) > m_maxFileSize)
	{
		rollover(SIZE_SWITCH);
	}
}

void NLParallelFileAppender::init()
{
	m_curIdx = getCurIdx();

	if (m_curIdx == 0)
		reopen(m_scheduledFilename, "a");
	else
	{
		ostringstream newTarget;
		newTarget << m_scheduledFilename << "." << m_curIdx;
		reopen(newTarget.str(), "a");
	}
}

int NLParallelFileAppender::getCurIdx()
{
	string dirname("");
	string filename("");
	size_t pos = m_scheduledFilename.rfind("/");
	if (pos != string::npos)
	{
		dirname = m_scheduledFilename.substr(0, pos);
		filename = m_scheduledFilename.substr(pos+1, m_scheduledFilename.size()-pos);
	}
	else
	{
		dirname = "./";
		filename = m_scheduledFilename;
	}

	DIR* dirp = opendir(dirname.c_str());
	struct dirent *dp;

	int idx = 0;
	while ((dp = readdir(dirp)) != NULL)
	{
		char *ptr;
		if ((ptr = strstr(dp->d_name, filename.c_str())) != NULL && strlen(dp->d_name) != filename.size())
		{
			char tmp[20]; bool bFlag = true;
			snprintf(tmp, sizeof(tmp), "%s", ptr+filename.size()+1);
			for (int i=0; i<strlen(tmp); ++i)
			{
				if (isdigit(tmp[i]) == 0)
				{
					bFlag = false;
					break;
				}
			}
			if (bFlag)
				idx = max(idx, atoi(tmp));
		}
	}
	closedir(dirp);

	return idx;
}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -