RolloverDescriptionPtr TimeBasedRollingPolicy::rollover()

in src/main/cpp/timebasedrollingpolicy.cpp [358:497]


RolloverDescriptionPtr TimeBasedRollingPolicy::rollover(
	const   LogString&  currentActiveFile,
	const   bool        append,
	Pool&       pool)
{
	Date now;
	log4cxx_time_t n = now.getTime();
	m_priv->nextCheck = now.getNextSecond();

	LogString buf;
	ObjectPtr obj = std::make_shared<Date>(n);
	formatFileName(obj, buf, pool);

	LogString newFileName(buf);

	if( m_priv->multiprocess ){
#if LOG4CXX_HAS_MULTIPROCESS_ROLLING_FILE_APPENDER

		if (!m_priv->bAlreadyInitialized)
		{
			if (getPatternConverterList().size())
			{
				(*(getPatternConverterList().begin()))->format(obj, m_priv->_fileNamePattern, pool);
			}
			else
			{
				m_priv->_fileNamePattern = m_priv->lastFileName;
			}

			if (!m_priv->_lock_file)
			{
				LOG4CXX_ENCODE_CHAR(mapFile, m_priv->_fileNamePattern);
				const std::string lockname = createFile(mapFile, LOCK_FILE_SUFFIX, m_priv->_mmapPool);
				apr_status_t stat = apr_file_open(&m_priv->_lock_file, lockname.c_str(), APR_CREATE | APR_READ | APR_WRITE, APR_OS_DEFAULT, m_priv->_mmapPool.getAPRPool());

				if (stat != APR_SUCCESS)
				{
					LOG4CXX_DECODE_CHAR(msg, lockname);
					msg += LOG4CXX_STR(": apr_file_open");
					LogLog::warn(helpers::Exception::makeMessage(msg, stat));
				}
			}

			initMMapFile(m_priv->lastFileName, m_priv->_mmapPool);
		}
		m_priv->bAlreadyInitialized = true;

		if (m_priv->_mmap && !isMapFileEmpty(m_priv->_mmapPool))
		{
			lockMMapFile(APR_FLOCK_SHARED);
			LogString mapLastFile(static_cast<logchar*>(m_priv->_mmap->mm));
			m_priv->lastFileName = mapLastFile;
			unLockMMapFile();
		}
		else
		{
			m_priv->_mmap = NULL;
			initMMapFile(m_priv->lastFileName, m_priv->_mmapPool);
		}
#endif
	}

	//
	//  if file names haven't changed, no rollover
	//
	if (newFileName == m_priv->lastFileName)
	{
		RolloverDescriptionPtr desc;
		return desc;
	}

	ActionPtr renameAction;
	ActionPtr compressAction;
	LogString lastBaseName(
		m_priv->lastFileName.substr(0, m_priv->lastFileName.length() - m_priv->suffixLength));
	LogString nextActiveFile(
		newFileName.substr(0, newFileName.length() - m_priv->suffixLength));

	if(getCreateIntermediateDirectories()){
		File compressedFile(m_priv->lastFileName);
		File compressedParent (compressedFile.getParent(pool));
		compressedParent.mkdirs(pool);
	}

	//
	//   if currentActiveFile is not lastBaseName then
	//        active file name is not following file pattern
	//        and requires a rename plus maintaining the same name
	if (currentActiveFile != lastBaseName)
	{
		renameAction = std::make_shared<FileRenameAction>(
					File().setPath(currentActiveFile), File().setPath(lastBaseName), true);
		nextActiveFile = currentActiveFile;
	}

	if (m_priv->suffixLength == 3)
	{
		GZCompressActionPtr comp = std::make_shared<GZCompressAction>(
					File().setPath(lastBaseName), File().setPath(m_priv->lastFileName), true);
		comp->setThrowIOExceptionOnForkFailure(m_priv->throwIOExceptionOnForkFailure);
		compressAction = comp;
	}

	if (m_priv->suffixLength == 4)
	{
		ZipCompressActionPtr comp = std::make_shared<ZipCompressAction>(
					File().setPath(lastBaseName), File().setPath(m_priv->lastFileName), true);
		comp->setThrowIOExceptionOnForkFailure(m_priv->throwIOExceptionOnForkFailure);
		compressAction = comp;
	}

	if( m_priv->multiprocess ){
#if LOG4CXX_HAS_MULTIPROCESS_ROLLING_FILE_APPENDER
		size_t byteCount = sizeof (logchar) * newFileName.size();
		if (MAX_FILE_LEN - sizeof (logchar) < byteCount)
		{
			LogString msg(newFileName + LOG4CXX_STR(": cannot exceed "));
			StringHelper::toString(MAX_FILE_LEN / sizeof (logchar), pool, msg);
			msg += LOG4CXX_STR(" characters");
			throw IllegalArgumentException(msg);
		}
		if (m_priv->_mmap && !isMapFileEmpty(m_priv->_mmapPool))
		{
			lockMMapFile(APR_FLOCK_EXCLUSIVE);
			memset(m_priv->_mmap->mm, 0, MAX_FILE_LEN);
			memcpy(m_priv->_mmap->mm, newFileName.c_str(), byteCount);
			unLockMMapFile();
		}
		else
		{
			m_priv->_mmap = NULL;
			initMMapFile(newFileName, m_priv->_mmapPool);
		}
#endif
	}else{
		m_priv->lastFileName = newFileName;
	}

	return std::make_shared<RolloverDescription>(nextActiveFile, append, renameAction, compressAction);
}