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);
}