void MultiprocessRollingFileAppender::subAppend()

in src/main/cpp/multiprocessrollingfileappender.cpp [476:538]


void MultiprocessRollingFileAppender::subAppend(const LoggingEventPtr& event, Pool& p)
{
	// The rollover check must precede actual writing. This is the
	// only correct behavior for time driven triggers.
	if (
		_priv->triggeringPolicy->isTriggeringEvent(
			this, event, getFile(), getFileLength()))
	{
		//
		//   wrap rollover request in try block since
		//    rollover may fail in case read access to directory
		//    is not provided.  However appender should still be in good
		//     condition and the append should still happen.
		try
		{
			_priv->_event = event;
			rolloverInternal(p);
		}
		catch (std::exception& ex)
		{
			LogLog::warn(LOG4CXX_STR("Exception during rollover attempt."));
			LogString exmsg;
			log4cxx::helpers::Transcoder::decode(ex.what(), exmsg);
			_priv->errorHandler->error(exmsg);
		}
	}

	//do re-check before every write
	//
	apr_finfo_t finfo1, finfo2;
	apr_status_t st1, st2;
	const WriterPtr writer = getWriter();
	const FileOutputStreamPtr fos = log4cxx::cast<FileOutputStream>( writer );
	if( !fos ){
		LogLog::error( LOG4CXX_STR("Can't cast writer to FileOutputStream") );
		return;
	}
	apr_file_t* _fd = fos->getFilePtr();
	st1 = apr_file_info_get(&finfo1, APR_FINFO_IDENT, _fd);

	if (st1 != APR_SUCCESS)
	{
		LogLog::warn(LOG4CXX_STR("apr_file_info_get failed"));
	}

	st2 = apr_stat(&finfo2, std::string(getFile()).c_str(), APR_FINFO_IDENT, p.getAPRPool());

	if (st2 != APR_SUCCESS)
	{
		LogString err = "apr_stat failed. file:" + getFile();
		LogLog::warn(err);
	}

	bool bAlreadyRolled = ((st1 == APR_SUCCESS) && (st2 == APR_SUCCESS)
			&& ((finfo1.device != finfo2.device) || (finfo1.inode != finfo2.inode)));

	if (bAlreadyRolled)
	{
		reopenLatestFile(p);
	}

	FileAppender::subAppend(event, p);
}