in src/main/cpp/multiprocessrollingfileappender.cpp [209:456]
bool MultiprocessRollingFileAppender::rolloverInternal(Pool& p)
{
//
// can't roll without a policy
//
if (_priv->rollingPolicy != NULL)
{
{
LogString fileName(getFile());
RollingPolicyBasePtr basePolicy = log4cxx::cast<RollingPolicyBase>(_priv->rollingPolicy);
apr_time_t n = apr_time_now();
ObjectPtr obj = std::make_shared<Date>(n);
LogString fileNamePattern;
if (basePolicy)
{
if (basePolicy->getPatternConverterList().size())
{
(*(basePolicy->getPatternConverterList().begin()))->format(obj, fileNamePattern, p);
fileName = std::string(fileNamePattern);
}
}
bool bAlreadyRolled = true;
char szDirName[MAX_FILE_LEN] = {'\0'};
char szBaseName[MAX_FILE_LEN] = {'\0'};
char szUid[MAX_FILE_LEN] = {'\0'};
memcpy(szDirName, fileName.c_str(), fileName.size() > MAX_FILE_LEN ? MAX_FILE_LEN : fileName.size());
memcpy(szBaseName, fileName.c_str(), fileName.size() > MAX_FILE_LEN ? MAX_FILE_LEN : fileName.size());
apr_uid_t uid;
apr_gid_t groupid;
apr_status_t stat = apr_uid_current(&uid, &groupid, p.getAPRPool());
if (stat == APR_SUCCESS)
{
#ifdef WIN32
snprintf(szUid, MAX_FILE_LEN, "%p", uid);
#else
snprintf(szUid, MAX_FILE_LEN, "%u", (unsigned int)uid);
#endif
}
log4cxx::filesystem::path path = szDirName;
const auto lockname = path.parent_path() / (path.filename().string() + szUid + ".lock");
apr_file_t* lock_file;
stat = apr_file_open(&lock_file, lockname.string().c_str(), APR_CREATE | APR_READ | APR_WRITE, APR_OS_DEFAULT, p.getAPRPool());
if (stat != APR_SUCCESS)
{
LogString err = LOG4CXX_STR("lockfile return error: open lockfile failed. ");
err += (strerror(errno));
LogLog::warn(err);
bAlreadyRolled = false;
lock_file = NULL;
}
else
{
stat = apr_file_lock(lock_file, APR_FLOCK_EXCLUSIVE);
if (stat != APR_SUCCESS)
{
LogString err = LOG4CXX_STR("apr_file_lock: lock failed. ");
err += (strerror(errno));
LogLog::warn(err);
bAlreadyRolled = false;
}
else
{
if (_priv->_event)
{
_priv->triggeringPolicy->isTriggeringEvent(this, _priv->_event, getFile(), getFileLength());
}
}
}
if (bAlreadyRolled)
{
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 false;
}
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"));
}
LogString fname = getFile();
st2 = apr_stat(&finfo2, fname.c_str(), APR_FINFO_IDENT, p.getAPRPool());
if (st2 != APR_SUCCESS)
{
LogLog::warn(LOG4CXX_STR("apr_stat failed."));
}
bAlreadyRolled = ((st1 == APR_SUCCESS) && (st2 == APR_SUCCESS)
&& ((finfo1.device != finfo2.device) || (finfo1.inode != finfo2.inode)));
}
if (!bAlreadyRolled)
{
try
{
RolloverDescriptionPtr rollover1(_priv->rollingPolicy->rollover(this->getFile(), this->getAppend(), p));
if (rollover1 != NULL)
{
if (rollover1->getActiveFileName() == getFile())
{
closeWriter();
bool success = true;
if (rollover1->getSynchronous() != NULL)
{
success = false;
try
{
success = rollover1->getSynchronous()->execute(p);
}
catch (std::exception& ex)
{
LogLog::warn(LOG4CXX_STR("Exception on rollover"));
LogString exmsg;
log4cxx::helpers::Transcoder::decode(ex.what(), exmsg);
_priv->errorHandler->error(exmsg, ex, 0);
}
}
if (success)
{
if (rollover1->getAppend())
{
_priv->fileLength = File().setPath(rollover1->getActiveFileName()).length(p);
}
else
{
_priv->fileLength = 0;
}
//
// async action not yet implemented
//
ActionPtr asyncAction(rollover1->getAsynchronous());
if (asyncAction != NULL)
{
asyncAction->execute(p);
}
setFileInternal(
rollover1->getActiveFileName(), rollover1->getAppend(),
_priv->bufferedIO, _priv->bufferSize, p);
}
else
{
setFileInternal(
rollover1->getActiveFileName(), true, _priv->bufferedIO, _priv->bufferSize, p);
}
}
else
{
closeWriter();
setFileInternal(rollover1->getActiveFileName());
// Call activateOptions to create any intermediate directories(if required)
FileAppender::activateOptionsInternal(p);
OutputStreamPtr os(new FileOutputStream(
rollover1->getActiveFileName(), rollover1->getAppend()));
WriterPtr newWriter(createWriter(os));
setWriterInternal(newWriter);
bool success = true;
if (rollover1->getSynchronous() != NULL)
{
success = false;
try
{
success = rollover1->getSynchronous()->execute(p);
}
catch (std::exception& ex)
{
LogLog::warn(LOG4CXX_STR("Exception during rollover"));
LogString exmsg;
log4cxx::helpers::Transcoder::decode(ex.what(), exmsg);
_priv->errorHandler->error(exmsg, ex, 0);
}
}
if (success)
{
if (rollover1->getAppend())
{
_priv->fileLength = File().setPath(rollover1->getActiveFileName()).length(p);
}
else
{
_priv->fileLength = 0;
}
//
// async action not yet implemented
//
ActionPtr asyncAction(rollover1->getAsynchronous());
if (asyncAction != NULL)
{
asyncAction->execute(p);
}
}
writeHeader(p);
}
releaseFileLock(lock_file);
return true;
}
}
catch (std::exception& ex)
{
LogLog::warn(LOG4CXX_STR("Exception during rollover"));
LogString exmsg;
log4cxx::helpers::Transcoder::decode(ex.what(), exmsg);
_priv->errorHandler->error(exmsg, ex, 0);
}
}
else
{
reopenLatestFile(p);
}
releaseFileLock(lock_file);
}
}
return false;
}