1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-01-18 04:58:51 +02:00

Add _FMT() logging macro variants.

Using the same macros for formatted and unformatted logging had several disadvantages.

First, the compiler was unable to verify the format string against the parameters.

Second, legitimate % characters in messages were being interpreted as format characters with garbage output ensuing.

Add _FMT() variants and update all call sites to use the correct variant.
This commit is contained in:
David Steele 2019-11-22 13:33:26 -05:00
parent 99edcca55b
commit 0c05df4582
21 changed files with 308 additions and 166 deletions

View File

@ -275,9 +275,9 @@ cmdArchiveGet(void)
// Log whether or not the file was found
if (result == 0)
LOG_INFO("found %s in the archive", strPtr(walSegment));
LOG_INFO_FMT("found %s in the archive", strPtr(walSegment));
else
LOG_INFO("unable to find %s in the archive", strPtr(walSegment));
LOG_INFO_FMT("unable to find %s in the archive", strPtr(walSegment));
}
MEM_CONTEXT_TEMP_END();
@ -335,7 +335,7 @@ cmdArchiveGetAsync(void)
if (strLstSize(jobData.walSegmentList) < 1)
THROW(ParamInvalidError, "at least one wal segment is required");
LOG_INFO(
LOG_INFO_FMT(
"get %u WAL file(s) from archive: %s%s",
strLstSize(jobData.walSegmentList), strPtr(strLstGet(jobData.walSegmentList, 0)),
strLstSize(jobData.walSegmentList) == 1 ?
@ -367,19 +367,19 @@ cmdArchiveGetAsync(void)
// Get the archive file
if (varIntForce(protocolParallelJobResult(job)) == 0)
{
LOG_DETAIL_PID(processId, "found %s in the archive", strPtr(walSegment));
LOG_DETAIL_PID_FMT(processId, "found %s in the archive", strPtr(walSegment));
}
// If it does not exist write an ok file to indicate that it was checked
else
{
LOG_DETAIL_PID(processId, "unable to find %s in the archive", strPtr(walSegment));
LOG_DETAIL_PID_FMT(processId, "unable to find %s in the archive", strPtr(walSegment));
archiveAsyncStatusOkWrite(archiveModeGet, walSegment, NULL);
}
}
// Else the job errored
else
{
LOG_WARN_PID(
LOG_WARN_PID_FMT(
processId,
"could not get %s from the archive (will be retried): [%d] %s", strPtr(walSegment),
protocolParallelJobErrorCode(job), strPtr(protocolParallelJobErrorMessage(job)));

View File

@ -340,7 +340,7 @@ cmdArchivePush(void)
}
// Log success
LOG_INFO("pushed WAL file '%s' to the archive asynchronously", strPtr(archiveFile));
LOG_INFO_FMT("pushed WAL file '%s' to the archive asynchronously", strPtr(archiveFile));
}
else
{
@ -371,7 +371,7 @@ cmdArchivePush(void)
LOG_WARN(strPtr(warning));
// Log success
LOG_INFO("pushed WAL file '%s' to the archive", strPtr(archiveFile));
LOG_INFO_FMT("pushed WAL file '%s' to the archive", strPtr(archiveFile));
}
}
}
@ -463,7 +463,7 @@ cmdArchivePushAsync(void)
if (strLstSize(jobData.walFileList) == 0)
THROW(AssertError, "no WAL files to process");
LOG_INFO(
LOG_INFO_FMT(
"push %u WAL file(s) to archive: %s%s", strLstSize(jobData.walFileList), strPtr(strLstGet(jobData.walFileList, 0)),
strLstSize(jobData.walFileList) == 1 ?
"" : strPtr(strNewFmt("...%s", strPtr(strLstGet(jobData.walFileList, strLstSize(jobData.walFileList) - 1)))));
@ -517,13 +517,13 @@ cmdArchivePushAsync(void)
// The job was successful
if (protocolParallelJobErrorCode(job) == 0)
{
LOG_DETAIL_PID(processId, "pushed WAL file '%s' to the archive", strPtr(walFile));
LOG_DETAIL_PID_FMT(processId, "pushed WAL file '%s' to the archive", strPtr(walFile));
archiveAsyncStatusOkWrite(archiveModePush, walFile, varStr(protocolParallelJobResult(job)));
}
// Else the job errored
else
{
LOG_WARN_PID(
LOG_WARN_PID_FMT(
processId,
"could not push WAL file '%s' to the archive (will be retried): [%d] %s", strPtr(walFile),
protocolParallelJobErrorCode(job), strPtr(protocolParallelJobErrorMessage(job)));

View File

@ -91,7 +91,7 @@ checkStandby(const DbGetResult dbGroup, unsigned int pgPathDefinedTotal)
// If backup from standby is true then warn when a standby not found
else if (cfgOptionBool(cfgOptBackupStandby))
{
LOG_WARN("option '%s' is enabled but standby is not properly configured", cfgOptionName(cfgOptBackupStandby));
LOG_WARN_FMT("option '%s' is enabled but standby is not properly configured", cfgOptionName(cfgOptBackupStandby));
}
FUNCTION_LOG_RETURN_VOID();
@ -137,7 +137,7 @@ checkPrimary(const DbGetResult dbGroup)
if (walSegmentFile != NULL)
{
LOG_INFO(
LOG_INFO_FMT(
"WAL segment %s successfully archived to '%s'", strPtr(walSegment),
strPtr(storagePathP(storageRepo(), strNewFmt(STORAGE_REPO_ARCHIVE "/%s/%s", strPtr(archiveId),
strPtr(walSegmentFile)))));

View File

@ -27,7 +27,7 @@ cmdStart(void)
}
else
{
LOG_WARN("stop file does not exist%s",
LOG_WARN_FMT("stop file does not exist%s",
(cfgOptionTest(cfgOptStanza) ? strPtr(strNewFmt(" for stanza %s", strPtr(cfgOptionStr(cfgOptStanza)))) : ""));
}
}

View File

@ -61,7 +61,7 @@ cmdStop(void)
// If we cannot open the lock file for any reason then warn and continue to next file
if ((fileHandle = open(strPtr(lockFile), O_RDONLY, 0)) == -1)
{
LOG_WARN( "unable to open lock file %s", strPtr(lockFile));
LOG_WARN_FMT( "unable to open lock file %s", strPtr(lockFile));
continue;
}
@ -83,9 +83,9 @@ cmdStop(void)
if (processId != NULL && strSize(processId) > 0)
{
if (kill(cvtZToInt(strPtr(processId)), SIGTERM) != 0)
LOG_WARN("unable to send term signal to process %s", strPtr(processId));
LOG_WARN_FMT("unable to send term signal to process %s", strPtr(processId));
else
LOG_INFO("sent term signal to process %s", strPtr(processId));
LOG_INFO_FMT("sent term signal to process %s", strPtr(processId));
}
else
{
@ -97,7 +97,7 @@ cmdStop(void)
}
else
{
LOG_WARN(
LOG_WARN_FMT(
"stop file already exists for %s",
cfgOptionTest(cfgOptStanza) ? strPtr(strNewFmt("stanza %s", strPtr(cfgOptionStr(cfgOptStanza)))) : "all stanzas");
}

View File

@ -131,7 +131,8 @@ expireDiffBackup(InfoBackup *infoBackup)
}
// If the message contains a comma, then prepend "set:"
LOG_INFO("expire diff backup %s%s", (strChr(backupExpired, ',') != -1 ? "set: " : ""), strPtr(backupExpired));
LOG_INFO_FMT(
"expire diff backup %s%s", (strChr(backupExpired, ',') != -1 ? "set: " : ""), strPtr(backupExpired));
}
}
}
@ -187,7 +188,8 @@ expireFullBackup(InfoBackup *infoBackup)
}
// If the message contains a comma, then prepend "set:"
LOG_INFO("expire full backup %s%s", (strChr(backupExpired, ',') != -1 ? "set: " : ""), strPtr(backupExpired));
LOG_INFO_FMT(
"expire full backup %s%s", (strChr(backupExpired, ',') != -1 ? "set: " : ""), strPtr(backupExpired));
}
}
}
@ -206,7 +208,7 @@ logExpire(ArchiveExpired *archiveExpire, String *archiveId)
if (archiveExpire->start != NULL)
{
// Force out any remaining message
LOG_DETAIL(
LOG_DETAIL_FMT(
"remove archive: archiveId = %s, start = %s, stop = %s", strPtr(archiveId), strPtr(archiveExpire->start),
strPtr(archiveExpire->stop));
@ -236,7 +238,7 @@ removeExpiredArchive(InfoBackup *infoBackup)
// cfgLoadUpdateOption based on certain rules.
if (archiveRetention == 0)
{
LOG_INFO("option '%s' is not set - archive logs will not be expired", cfgOptionName(cfgOptRepoRetentionArchive));
LOG_INFO_FMT("option '%s' is not set - archive logs will not be expired", cfgOptionName(cfgOptRepoRetentionArchive));
}
else
{
@ -358,7 +360,7 @@ removeExpiredArchive(InfoBackup *infoBackup)
String *fullPath = storagePathP(
storageRepo(), strNewFmt(STORAGE_REPO_ARCHIVE "/%s", strPtr(archiveId)));
storagePathRemoveP(storageRepoWrite(), fullPath, .recurse = true);
LOG_INFO("remove archive path: %s", strPtr(fullPath));
LOG_INFO_FMT("remove archive path: %s", strPtr(fullPath));
}
// Continue to next directory
@ -394,7 +396,7 @@ removeExpiredArchive(InfoBackup *infoBackup)
// forever.
else
{
LOG_INFO(
LOG_INFO_FMT(
"full backup total < %u - using oldest full backup for %s archive retention", archiveRetention,
strPtr(archiveId));
strLstAdd(localBackupArchiveRetentionList, strLstGet(localBackupRetentionList, 0));
@ -461,7 +463,7 @@ removeExpiredArchive(InfoBackup *infoBackup)
else
archiveExpireMax = strDup(archiveRange.start);
LOG_DETAIL(
LOG_DETAIL_FMT(
"archive retention on backup %s, archiveId = %s, start = %s%s",
strPtr(backupData->backupLabel), strPtr(archiveId), strPtr(archiveRange.start),
archiveRange.stop != NULL ?
@ -565,7 +567,7 @@ removeExpiredArchive(InfoBackup *infoBackup)
// Log if no archive was expired
if (archiveExpire.total == 0)
{
LOG_DETAIL("no archive to remove, archiveId = %s", strPtr(archiveId));
LOG_DETAIL_FMT("no archive to remove, archiveId = %s", strPtr(archiveId));
}
// Log if there is more to log
else
@ -606,7 +608,7 @@ removeExpiredBackup(InfoBackup *infoBackup)
{
if (!strLstExists(currentBackupList, strLstGet(backupList, backupIdx)))
{
LOG_INFO("remove expired backup %s", strPtr(strLstGet(backupList, backupIdx)));
LOG_INFO_FMT("remove expired backup %s", strPtr(strLstGet(backupList, backupIdx)));
storagePathRemoveP(
storageRepoWrite(), strNewFmt(STORAGE_REPO_BACKUP "/%s", strPtr(strLstGet(backupList, backupIdx))),

View File

@ -90,7 +90,7 @@ restorePathValidate(void)
if ((cfgOptionBool(cfgOptDelta) || cfgOptionBool(cfgOptForce)) &&
!storageExistsP(storagePg(), PG_FILE_PGVERSION_STR) && !storageExistsP(storagePg(), BACKUP_MANIFEST_FILE_STR))
{
LOG_WARN(
LOG_WARN_FMT(
"--delta or --force specified but unable to find '" PG_FILE_PGVERSION "' or '" BACKUP_MANIFEST_FILE "' in '%s' to"
" confirm that this is a valid $PGDATA directory. --delta and --force have been disabled and if any files"
" exist in the destination directories the restore will be aborted.",
@ -217,7 +217,7 @@ restoreManifestMap(Manifest *manifest)
if (!strEq(targetBase->path, pgPath))
{
LOG_INFO("remap data directory to '%s'", strPtr(pgPath));
LOG_INFO_FMT("remap data directory to '%s'", strPtr(pgPath));
manifestTargetUpdate(manifest, targetBase->name, pgPath, NULL);
}
@ -280,7 +280,7 @@ restoreManifestMap(Manifest *manifest)
// Remap tablespace if a mapping was found
if (tablespacePath != NULL)
{
LOG_INFO("map tablespace '%s' to '%s'", strPtr(target->name), strPtr(tablespacePath));
LOG_INFO_FMT("map tablespace '%s' to '%s'", strPtr(target->name), strPtr(tablespacePath));
manifestTargetUpdate(manifest, target->name, tablespacePath, NULL);
manifestLinkUpdate(manifest, strNewFmt(MANIFEST_TARGET_PGDATA "/%s", strPtr(target->name)), tablespacePath);
@ -328,7 +328,7 @@ restoreManifestMap(Manifest *manifest)
// Remap link if a mapping was found
if (linkPath != NULL)
{
LOG_INFO("map link '%s' to '%s'", strPtr(link), strPtr(linkPath));
LOG_INFO_FMT("map link '%s' to '%s'", strPtr(link), strPtr(linkPath));
manifestLinkUpdate(manifest, target->name, linkPath);
// If the link is a file separate the file name from the path to update the target
@ -358,10 +358,10 @@ restoreManifestMap(Manifest *manifest)
else if (!linkAll)
{
if (target->file != NULL)
LOG_WARN("file link '%s' will be restored as a file at the same location", strPtr(link));
LOG_WARN_FMT("file link '%s' will be restored as a file at the same location", strPtr(link));
else
{
LOG_WARN(
LOG_WARN_FMT(
"contents of directory link '%s' will be restored in a directory at the same location",
strPtr(link));
}
@ -444,7 +444,7 @@ Check ownership of items in the manifest
const String *owner = strLstGet(type##List, ownerIdx); \
\
if (type##Name() == NULL || !strEq(type##Name(), owner)) \
LOG_WARN("unknown " #type " '%s' in backup manifest mapped to current " #type, strPtr(owner)); \
LOG_WARN_FMT("unknown " #type " '%s' in backup manifest mapped to current " #type, strPtr(owner)); \
} \
} \
while (0)
@ -488,10 +488,10 @@ restoreManifestOwner(Manifest *manifest)
if (userNull || groupNull)
{
if (userNull)
LOG_WARN("unknown user in backup manifest mapped to '%s'", strPtr(pathInfo.user));
LOG_WARN_FMT("unknown user in backup manifest mapped to '%s'", strPtr(pathInfo.user));
if (groupNull)
LOG_WARN("unknown group in backup manifest mapped to '%s'", strPtr(pathInfo.group));
LOG_WARN_FMT("unknown group in backup manifest mapped to '%s'", strPtr(pathInfo.group));
memContextSwitch(MEM_CONTEXT_OLD());
@ -580,7 +580,7 @@ restoreCleanOwnership(
{
// If this is a newly created file/link/path then there's no need to log updated permissions
if (!new)
LOG_DETAIL("update ownership for '%s'", strPtr(pgPath));
LOG_DETAIL_FMT("update ownership for '%s'", strPtr(pgPath));
THROW_ON_SYS_ERROR_FMT(
lchown(strPtr(pgPath), expectedUserId, expectedGroupId) == -1, FileOwnerError, "unable to set ownership for '%s'",
@ -606,7 +606,7 @@ restoreCleanMode(const String *pgPath, mode_t manifestMode, const StorageInfo *i
// Update mode if not as expected
if (manifestMode != info->mode)
{
LOG_DETAIL("update mode for '%s' to %04o", strPtr(pgPath), manifestMode);
LOG_DETAIL_FMT("update mode for '%s' to %04o", strPtr(pgPath), manifestMode);
THROW_ON_SYS_ERROR_FMT(
chmod(strPtr(pgPath), manifestMode) == -1, FileOwnerError, "unable to set mode for '%s'", strPtr(pgPath));
@ -676,7 +676,7 @@ restoreCleanInfoListCallback(void *data, const StorageInfo *info)
}
else
{
LOG_DETAIL("remove invalid file '%s'", strPtr(pgPath));
LOG_DETAIL_FMT("remove invalid file '%s'", strPtr(pgPath));
storageRemoveP(storageLocalWrite(), pgPath, .errorOnMissing = true);
}
@ -691,7 +691,7 @@ restoreCleanInfoListCallback(void *data, const StorageInfo *info)
{
if (!strEq(manifestLink->destination, info->linkDestination))
{
LOG_DETAIL("remove link '%s' because destination changed", strPtr(pgPath));
LOG_DETAIL_FMT("remove link '%s' because destination changed", strPtr(pgPath));
storageRemoveP(storageLocalWrite(), pgPath, .errorOnMissing = true);
}
else
@ -699,7 +699,7 @@ restoreCleanInfoListCallback(void *data, const StorageInfo *info)
}
else
{
LOG_DETAIL("remove invalid link '%s'", strPtr(pgPath));
LOG_DETAIL_FMT("remove invalid link '%s'", strPtr(pgPath));
storageRemoveP(storageLocalWrite(), pgPath, .errorOnMissing = true);
}
@ -733,7 +733,7 @@ restoreCleanInfoListCallback(void *data, const StorageInfo *info)
}
else
{
LOG_DETAIL("remove invalid path '%s'", strPtr(pgPath));
LOG_DETAIL_FMT("remove invalid path '%s'", strPtr(pgPath));
storagePathRemoveP(storageLocalWrite(), pgPath, .errorOnMissing = true, .recurse = true);
}
@ -743,7 +743,7 @@ restoreCleanInfoListCallback(void *data, const StorageInfo *info)
// Special file types cannot exist in the manifest so just delete them
case storageTypeSpecial:
{
LOG_DETAIL("remove special file '%s'", strPtr(pgPath));
LOG_DETAIL_FMT("remove special file '%s'", strPtr(pgPath));
storageRemoveP(storageLocalWrite(), pgPath, .errorOnMissing = true);
break;
}
@ -822,7 +822,7 @@ restoreCleanBuild(Manifest *manifest)
// Don't log check for the same path twice. There can be multiple links to files in the same path, but logging it more
// than once makes the logs noisy and looks like a bug.
if (!strLstExists(pathChecked, cleanData->targetPath))
LOG_DETAIL("check '%s' exists", strPtr(cleanData->targetPath));
LOG_DETAIL_FMT("check '%s' exists", strPtr(cleanData->targetPath));
StorageInfo info = storageInfoP(storageLocal(), cleanData->targetPath, .ignoreMissing = true, .followLink = true);
strLstAdd(pathChecked, cleanData->targetPath);
@ -879,7 +879,7 @@ restoreCleanBuild(Manifest *manifest)
if (manifestFileFindDefault(manifest, STRDEF(MANIFEST_TARGET_PGDATA "/" PG_FILE_TABLESPACEMAP), NULL) != NULL &&
manifestData(manifest)->pgVersion >= PG_VERSION_TABLESPACE_MAP)
{
LOG_DETAIL("skip '" PG_FILE_TABLESPACEMAP "' -- tablespace links will be created based on mappings");
LOG_DETAIL_FMT("skip '" PG_FILE_TABLESPACEMAP "' -- tablespace links will be created based on mappings");
manifestFileRemove(manifest, STRDEF(MANIFEST_TARGET_PGDATA "/" PG_FILE_TABLESPACEMAP));
}
@ -888,7 +888,7 @@ restoreCleanBuild(Manifest *manifest)
strEq(cfgOptionStr(cfgOptType), RECOVERY_TYPE_PRESERVE_STR) &&
manifestFileFindDefault(manifest, STRDEF(MANIFEST_TARGET_PGDATA "/" PG_FILE_POSTGRESQLAUTOCONF), NULL) != NULL)
{
LOG_DETAIL("skip '" PG_FILE_POSTGRESQLAUTOCONF "' -- recovery type is preserve");
LOG_DETAIL_FMT("skip '" PG_FILE_POSTGRESQLAUTOCONF "' -- recovery type is preserve");
manifestFileRemove(manifest, STRDEF(MANIFEST_TARGET_PGDATA "/" PG_FILE_POSTGRESQLAUTOCONF));
}
@ -898,7 +898,8 @@ restoreCleanBuild(Manifest *manifest)
// so the file does not return, zombie-like, in the case of a host crash.
if (storageExistsP(storagePg(), STRDEF(PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL)))
{
LOG_DETAIL("remove '" PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL "' so cluster will not start if restore does not complete");
LOG_DETAIL_FMT(
"remove '" PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL "' so cluster will not start if restore does not complete");
storageRemoveP(storagePgWrite(), STRDEF(PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL));
storagePathSyncP(storagePgWrite(), PG_PATH_GLOBAL_STR);
}
@ -916,7 +917,7 @@ restoreCleanBuild(Manifest *manifest)
// Only log when doing a delta restore because otherwise the targets should be empty. We'll still run the clean
// to fix permissions/ownership on the target paths.
if (delta)
LOG_INFO("remove invalid files/links/paths from '%s'", strPtr(cleanData->targetPath));
LOG_INFO_FMT("remove invalid files/links/paths from '%s'", strPtr(cleanData->targetPath));
// Clean the target
storageInfoListP(
@ -970,7 +971,7 @@ restoreCleanBuild(Manifest *manifest)
// Create the link if it is missing. If it exists it should already have the correct ownership and destination.
if (!linkInfo.exists)
{
LOG_DETAIL("create symlink '%s' to '%s'", strPtr(pgPath), strPtr(link->destination));
LOG_DETAIL_FMT("create symlink '%s' to '%s'", strPtr(pgPath), strPtr(link->destination));
THROW_ON_SYS_ERROR_FMT(
symlink(strPtr(link->destination), strPtr(pgPath)) == -1, FileOpenError,
@ -987,7 +988,7 @@ restoreCleanBuild(Manifest *manifest)
// Create the path if it is missing If it exists it should already have the correct ownership and mode.
if (!pathInfo.exists)
{
LOG_DETAIL("create path '%s'", strPtr(pgPath));
LOG_DETAIL_FMT("create path '%s'", strPtr(pgPath));
storagePathCreateP(storagePgWrite(), pgPath, .mode = path->mode, .noParentCreate = true, .errorOnExists = true);
restoreCleanOwnership(storagePathP(storagePg(), pgPath), path->user, path->group, userId(), groupId(), true);
@ -1007,7 +1008,7 @@ restoreCleanBuild(Manifest *manifest)
// Create the link if it is missing. If it exists it should already have the correct ownership and destination.
if (!linkInfo.exists)
{
LOG_DETAIL("create symlink '%s' to '%s'", strPtr(pgPath), strPtr(link->destination));
LOG_DETAIL_FMT("create symlink '%s' to '%s'", strPtr(pgPath), strPtr(link->destination));
THROW_ON_SYS_ERROR_FMT(
symlink(strPtr(link->destination), strPtr(pgPath)) == -1, FileOpenError,
@ -1073,7 +1074,7 @@ restoreSelectiveExpression(Manifest *manifest)
THROW(FormatError, "no databases found for selective restore\nHINT: is this a valid cluster?");
// Log databases found
LOG_DETAIL("databases found for selective restore (%s)", strPtr(strLstJoin(dbList, ", ")));
LOG_DETAIL_FMT("databases found for selective restore (%s)", strPtr(strLstJoin(dbList, ", ")));
// Remove included databases from the list
const StringList *includeList = strLstNewVarLst(cfgOptionLst(cfgOptDbInclude));
@ -1141,7 +1142,7 @@ restoreSelectiveExpression(Manifest *manifest)
// If all user databases have been selected then nothing to do
if (expression == NULL)
{
LOG_INFO("nothing to filter - all user databases have been selected");
LOG_INFO_FMT("nothing to filter - all user databases have been selected");
}
// Else return the expression
else
@ -1340,7 +1341,7 @@ restoreRecoveryWriteConf(const Manifest *manifest, unsigned int pgVersion, const
// Only write recovery.conf if recovery type != none
if (!strEq(cfgOptionStr(cfgOptType), RECOVERY_TYPE_NONE_STR))
{
LOG_INFO("write %s", strPtr(storagePathP(storagePg(), PG_FILE_RECOVERYCONF_STR)));
LOG_INFO_FMT("write %s", strPtr(storagePathP(storagePg(), PG_FILE_RECOVERYCONF_STR)));
// Use the data directory to set permissions and ownership for recovery file
const ManifestPath *dataPath = manifestPathFind(manifest, MANIFEST_TARGET_PGDATA_STR);
@ -1446,7 +1447,7 @@ restoreRecoveryWriteAutoConf(unsigned int pgVersion, const String *restoreLabel)
strCatFmt(content, "%s", strPtr(restoreRecoveryConf(pgVersion, restoreLabel)));
}
LOG_INFO(
LOG_INFO_FMT(
"write %s%s", autoConf == NULL ? "" : "updated ", strPtr(storagePathP(storagePg(), PG_FILE_POSTGRESQLAUTOCONF_STR)));
// Use the data directory to set permissions and ownership for recovery file
@ -1503,7 +1504,7 @@ restoreRecoveryWrite(const Manifest *manifest)
if (!storageExistsP(storagePg(), recoveryFile))
{
LOG_WARN(
LOG_WARN_FMT(
"recovery type is " RECOVERY_TYPE_PRESERVE " but recovery file does not exist at '%s'",
strPtr(storagePathP(storagePg(), recoveryFile)));
}
@ -1899,7 +1900,7 @@ cmdRestore(void)
restoreManifestValidate(jobData.manifest, backupSet);
// Log the backup set to restore
LOG_INFO("restore backup set %s", strPtr(backupSet));
LOG_INFO_FMT("restore backup set %s", strPtr(backupSet));
// Map manifest
restoreManifestMap(jobData.manifest);
@ -1971,7 +1972,7 @@ cmdRestore(void)
strLstAdd(pathSynced, pgPath);
// Sync the path
LOG_DETAIL("sync path '%s'", strPtr(pgPath));
LOG_DETAIL_FMT("sync path '%s'", strPtr(pgPath));
storagePathSyncP(storageLocalWrite(), pgPath);
}
}
@ -1992,7 +1993,7 @@ cmdRestore(void)
const String *pgPath = storagePathP(storagePg(), manifestPathPg(manifestName));
LOG_DETAIL("sync path '%s'", strPtr(pgPath));
LOG_DETAIL_FMT("sync path '%s'", strPtr(pgPath));
storagePathSyncP(storagePgWrite(), pgPath);
}
@ -2011,7 +2012,7 @@ cmdRestore(void)
LOG_WARN("backup does not contain '" PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL "' -- cluster will not start");
// Sync global path
LOG_DETAIL("sync path '%s'", strPtr(storagePathP(storagePg(), PG_PATH_GLOBAL_STR)));
LOG_DETAIL_FMT("sync path '%s'", strPtr(storagePathP(storagePg(), PG_PATH_GLOBAL_STR)));
storagePathSyncP(storagePgWrite(), PG_PATH_GLOBAL_STR);
}
MEM_CONTEXT_TEMP_END();

View File

@ -125,7 +125,7 @@ cmdStanzaCreate(void)
// If no files copied, then the stanza was already valid
if (sourceFile == NULL)
LOG_INFO("stanza '%s' already exists and is valid", strPtr(cfgOptionStr(cfgOptStanza)));
LOG_INFO_FMT("stanza '%s' already exists and is valid", strPtr(cfgOptionStr(cfgOptStanza)));
}
// Else if both .info and corresponding .copy file are missing for one but not the other, then error
else

View File

@ -94,7 +94,7 @@ cmdStanzaUpgrade(void)
}
if (!(infoArchiveUpgrade || infoBackupUpgrade))
LOG_INFO("stanza '%s' is already up to date", strPtr(cfgOptionStr(cfgOptStanza)));
LOG_INFO_FMT("stanza '%s' is already up to date", strPtr(cfgOptionStr(cfgOptStanza)));
}
MEM_CONTEXT_TEMP_END();

View File

@ -44,7 +44,7 @@ level is set to debug or trace.
#define FUNCTION_LOG_END_BASE() \
stackTraceTestStart(); \
LOG(FUNCTION_LOG_LEVEL(), 0, "(%s)", stackTraceParam()); \
LOG_FMT(FUNCTION_LOG_LEVEL(), 0, "(%s)", stackTraceParam()); \
}
#else
#define FUNCTION_LOG_BEGIN_BASE(logLevel) \
@ -55,7 +55,7 @@ level is set to debug or trace.
stackTraceParamLog();
#define FUNCTION_LOG_END_BASE() \
LOG(FUNCTION_LOG_LEVEL(), 0, "(%s)", stackTraceParam()); \
LOG_FMT(FUNCTION_LOG_LEVEL(), 0, "(%s)", stackTraceParam()); \
}
#endif
@ -236,7 +236,7 @@ Macros to return function results (or void)
char buffer[STACK_TRACE_PARAM_MAX]; \
\
FUNCTION_LOG_##typeMacroPrefix##_FORMAT(FUNCTION_LOG_RETURN_result, buffer, sizeof(buffer)); \
LOG(FUNCTION_LOG_LEVEL(), 0, "=> %s", buffer); \
LOG_FMT(FUNCTION_LOG_LEVEL(), 0, "=> %s", buffer); \
} \
\
return FUNCTION_LOG_RETURN_result; \

View File

@ -115,7 +115,7 @@ exitSafe(int result, bool error, SignalType signalType)
// Assert errors always output a stack trace
if (logLevel == logLevelAssert)
LOG(logLevel, errorCode(), "%s\nSTACK TRACE:\n%s", errorMessage(), errorStackTrace());
LOG_FMT(logLevel, errorCode(), "%s\nSTACK TRACE:\n%s", errorMessage(), errorStackTrace());
else
{
// Log just the error to non-debug levels
@ -124,7 +124,7 @@ exitSafe(int result, bool error, SignalType signalType)
// Log the stack trace debug levels
if (logAny(logLevelDebug))
{
LOG_INTERNAL(
LOG_INTERNAL_FMT(
logLevel, logLevelDebug, LOG_LEVEL_MAX, 0, errorCode(), "%s\nSTACK TRACE:\n%s", errorMessage(),
errorStackTrace());
}

View File

@ -435,7 +435,7 @@ httpClientRequest(
// Retry if wait time has not expired
if (wait != NULL && waitMore(wait))
{
LOG_DEBUG("retry %s: %s", errorTypeName(errorType()), errorMessage());
LOG_DEBUG_FMT("retry %s: %s", errorTypeName(errorType()), errorMessage());
retry = true;
httpClientStatLocal.retry++;

View File

@ -651,7 +651,7 @@ tlsClientOpen(TlsClient *this)
// Retry if wait time has not expired
if (wait != NULL && waitMore(wait))
{
LOG_DEBUG("retry %s: %s", errorTypeName(errorType()), errorMessage());
LOG_DEBUG_FMT("retry %s: %s", errorTypeName(errorType()), errorMessage());
retry = true;
tlsClientStatLocal.retry++;

View File

@ -216,7 +216,8 @@ logFileSet(const char *logFile)
if (logHandleFile == -1)
{
int errNo = errno;
LOG_WARN("unable to open log file '%s': %s\nNOTE: process will continue without log file.", logFile, strerror(errNo));
LOG_WARN_FMT(
"unable to open log file '%s': %s\nNOTE: process will continue without log file.", logFile, strerror(errNo));
result = false;
}
@ -334,35 +335,35 @@ logWriteIndent(int handle, const char *message, size_t indentSize, const char *e
}
/***********************************************************************************************************************************
General log function
Generate the log header and anything else that needs to happen before the message is output
***********************************************************************************************************************************/
void
logInternal(
LogLevel logLevel, LogLevel logRangeMin, LogLevel logRangeMax, unsigned int processId, const char *fileName,
const char *functionName, int code, const char *format, ...)
typedef struct LogPreResult
{
size_t bufferPos;
char *logBufferStdErr;
size_t indentSize;
} LogPreResult;
static LogPreResult
logPre(LogLevel logLevel, unsigned int processId, const char *fileName, const char *functionName, int code)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, logLevel);
FUNCTION_TEST_PARAM(ENUM, logRangeMin);
FUNCTION_TEST_PARAM(ENUM, logRangeMax);
FUNCTION_TEST_PARAM(UINT, processId);
FUNCTION_TEST_PARAM(STRINGZ, fileName);
FUNCTION_TEST_PARAM(STRINGZ, functionName);
FUNCTION_TEST_PARAM(INT, code);
FUNCTION_TEST_PARAM(STRINGZ, format);
FUNCTION_TEST_END();
ASSERT_LOG_LEVEL(logLevel);
ASSERT_LOG_LEVEL(logRangeMin);
ASSERT_LOG_LEVEL(logRangeMax);
ASSERT(logRangeMin <= logRangeMax);
ASSERT(fileName != NULL);
ASSERT(functionName != NULL);
ASSERT(
(code == 0 && logLevel > logLevelError) || (logLevel == logLevelError && code != errorTypeCode(&AssertError)) ||
(logLevel == logLevelAssert && code == errorTypeCode(&AssertError)));
ASSERT(format != NULL);
size_t bufferPos = 0; // Current position in the buffer
// Initialize buffer position
LogPreResult result = {.bufferPos = 0};
// Add time
if (logTimestamp)
@ -370,24 +371,26 @@ logInternal(
TimeMSec logTimeMSec = timeMSec();
time_t logTimeSec = (time_t)(logTimeMSec / MSEC_PER_SEC);
bufferPos += strftime(logBuffer + bufferPos, sizeof(logBuffer) - bufferPos, "%Y-%m-%d %H:%M:%S", localtime(&logTimeSec));
bufferPos += (size_t)snprintf(
logBuffer + bufferPos, sizeof(logBuffer) - bufferPos, ".%03d ", (int)(logTimeMSec % 1000));
result.bufferPos += strftime(
logBuffer + result.bufferPos, sizeof(logBuffer) - result.bufferPos, "%Y-%m-%d %H:%M:%S", localtime(&logTimeSec));
result.bufferPos += (size_t)snprintf(
logBuffer + result.bufferPos, sizeof(logBuffer) - result.bufferPos, ".%03d ", (int)(logTimeMSec % 1000));
}
// Add process and aligned log level
bufferPos += (size_t)snprintf(
logBuffer + bufferPos, sizeof(logBuffer) - bufferPos, "P%0*u %*s: ", logProcessSize, processId, 6, logLevelStr(logLevel));
result.bufferPos += (size_t)snprintf(
logBuffer + result.bufferPos, sizeof(logBuffer) - result.bufferPos, "P%0*u %*s: ", logProcessSize, processId, 6,
logLevelStr(logLevel));
// When writing to stderr the timestamp, process, and log level alignment will be skipped
char *logBufferStdErr = logBuffer + bufferPos - strlen(logLevelStr(logLevel)) - 2;
result.logBufferStdErr = logBuffer + result.bufferPos - strlen(logLevelStr(logLevel)) - 2;
// Set the indent size -- this will need to be adjusted for stderr
size_t indentSize = bufferPos;
result.indentSize = result.bufferPos;
// Add error code
if (code != 0)
bufferPos += (size_t)snprintf(logBuffer + bufferPos, sizeof(logBuffer) - bufferPos, "[%03d]: ", code);
result.bufferPos += (size_t)snprintf(logBuffer + result.bufferPos, sizeof(logBuffer) - result.bufferPos, "[%03d]: ", code);
// Add debug info
if (logLevel >= logLevelDebug)
@ -395,33 +398,54 @@ logInternal(
// Adding padding for debug and trace levels
for (unsigned int paddingIdx = 0; paddingIdx < ((logLevel - logLevelDebug + 1) * 4); paddingIdx++)
{
logBuffer[bufferPos++] = ' ';
indentSize++;
logBuffer[result.bufferPos++] = ' ';
result.indentSize++;
}
bufferPos += (size_t)snprintf(
logBuffer + bufferPos, LOG_BUFFER_SIZE - bufferPos, "%.*s::%s: ", (int)strlen(fileName) - 2, fileName,
result.bufferPos += (size_t)snprintf(
logBuffer + result.bufferPos, LOG_BUFFER_SIZE - result.bufferPos, "%.*s::%s: ", (int)strlen(fileName) - 2, fileName,
functionName);
}
// Format message -- this will need to be indented later
va_list argumentList;
va_start(argumentList, format);
bufferPos += (size_t)vsnprintf(logBuffer + bufferPos, LOG_BUFFER_SIZE - bufferPos, format, argumentList);
va_end(argumentList);
FUNCTION_TEST_RETURN(result);
}
/***********************************************************************************************************************************
Finalize formatting and log after the message has been added to the buffer
***********************************************************************************************************************************/
static void
logPost(LogPreResult *logData, LogLevel logLevel, LogLevel logRangeMin, LogLevel logRangeMax)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(SIZE, logData->bufferPos);
FUNCTION_TEST_PARAM(STRINGZ, logData->logBufferStdErr);
FUNCTION_TEST_PARAM(SIZE, logData->indentSize);
FUNCTION_TEST_PARAM(ENUM, logLevel);
FUNCTION_TEST_PARAM(ENUM, logRangeMin);
FUNCTION_TEST_PARAM(ENUM, logRangeMax);
FUNCTION_TEST_END();
ASSERT_LOG_LEVEL(logLevel);
ASSERT_LOG_LEVEL(logRangeMin);
ASSERT_LOG_LEVEL(logRangeMax);
ASSERT(logRangeMin <= logRangeMax);
// Add linefeed
logBuffer[bufferPos++] = '\n';
logBuffer[bufferPos] = 0;
logBuffer[logData->bufferPos++] = '\n';
logBuffer[logData->bufferPos] = 0;
// Determine where to log the message based on log-level-stderr
if (logLevel <= logLevelStdErr)
{
if (logRange(logLevelStdErr, logRangeMin, logRangeMax))
logWriteIndent(logHandleStdErr, logBufferStdErr, indentSize - (size_t)(logBufferStdErr - logBuffer), "log to stderr");
{
logWriteIndent(
logHandleStdErr, logData->logBufferStdErr, logData->indentSize - (size_t)(logData->logBufferStdErr - logBuffer),
"log to stderr");
}
}
else if (logLevel <= logLevelStdOut && logRange(logLevelStdOut, logRangeMin, logRangeMax))
logWriteIndent(logHandleStdOut, logBuffer, indentSize, "log to stdout");
logWriteIndent(logHandleStdOut, logBuffer, logData->indentSize, "log to stdout");
// Log to file
if (logLevel <= logLevelFile && logHandleFile != -1 && logRange(logLevelFile, logRangeMin, logRangeMax))
@ -442,8 +466,72 @@ logInternal(
logFileBanner = true;
}
logWriteIndent(logHandleFile, logBuffer, indentSize, "log to file");
logWriteIndent(logHandleFile, logBuffer, logData->indentSize, "log to file");
}
FUNCTION_TEST_RETURN_VOID();
}
/**********************************************************************************************************************************/
void
logInternal(
LogLevel logLevel, LogLevel logRangeMin, LogLevel logRangeMax, unsigned int processId, const char *fileName,
const char *functionName, int code, const char *message)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, logLevel);
FUNCTION_TEST_PARAM(ENUM, logRangeMin);
FUNCTION_TEST_PARAM(ENUM, logRangeMax);
FUNCTION_TEST_PARAM(UINT, processId);
FUNCTION_TEST_PARAM(STRINGZ, fileName);
FUNCTION_TEST_PARAM(STRINGZ, functionName);
FUNCTION_TEST_PARAM(INT, code);
FUNCTION_TEST_PARAM(STRINGZ, message);
FUNCTION_TEST_END();
ASSERT(message != NULL);
LogPreResult logData = logPre(logLevel, processId, fileName, functionName, code);
// Copy message into buffer and update buffer position
strncpy(logBuffer + logData.bufferPos, message, sizeof(logBuffer) - logData.bufferPos);
logBuffer[sizeof(logBuffer) - 1] = 0;
logData.bufferPos += strlen(logBuffer + logData.bufferPos);
logPost(&logData, logLevel, logRangeMin, logRangeMax);
FUNCTION_TEST_RETURN_VOID();
}
/**********************************************************************************************************************************/
void
logInternalFmt(
LogLevel logLevel, LogLevel logRangeMin, LogLevel logRangeMax, unsigned int processId, const char *fileName,
const char *functionName, int code, const char *format, ...)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, logLevel);
FUNCTION_TEST_PARAM(ENUM, logRangeMin);
FUNCTION_TEST_PARAM(ENUM, logRangeMax);
FUNCTION_TEST_PARAM(UINT, processId);
FUNCTION_TEST_PARAM(STRINGZ, fileName);
FUNCTION_TEST_PARAM(STRINGZ, functionName);
FUNCTION_TEST_PARAM(INT, code);
FUNCTION_TEST_PARAM(STRINGZ, format);
FUNCTION_TEST_END();
ASSERT(format != NULL);
LogPreResult logData = logPre(logLevel, processId, fileName, functionName, code);
// Format message into buffer and update buffer position
va_list argumentList;
va_start(argumentList, format);
logData.bufferPos += (size_t)vsnprintf(
logBuffer + logData.bufferPos, LOG_BUFFER_SIZE - logData.bufferPos, format, argumentList);
va_end(argumentList);
logPost(&logData, logLevel, logRangeMin, logRangeMax);
FUNCTION_TEST_RETURN_VOID();
}

View File

@ -32,14 +32,14 @@ const char *logLevelStr(LogLevel logLevel);
/***********************************************************************************************************************************
Macros
Only call logInternal() if the message will be logged to one of the available outputs. Also simplify each call site by supplying
commonly-used values.
Macros only call logInternal()/logInternalFmt() if the message will be logged to one of the available outputs. The also simplify
each call site by supplying commonly-used values.
Note that it's possible that that not all the macros below will appear in the code. They are included for completeness and future
usage.
Note that it's possible that that not all the macros below will appear in the code. In particular the ERROR and ASSERT macros
should not be used directly. They are included for completeness and future usage.
***********************************************************************************************************************************/
// Define a macro to test logAny() that can be removed when performing coverage testing. Checking logAny() saves a function call
// for logging calls that won't be output anywhere, but since the macro then contains a branch it causes coverage problems.
// for logging calls that won't be output anywhere, but since the macro contains a branch it causes coverage problems.
#ifdef DEBUG_COVERAGE
#define IF_LOG_ANY(logLevel)
#else
@ -47,56 +47,107 @@ usage.
if (logAny(logLevel))
#endif
#define LOG_INTERNAL(logLevel, logRangeMin, logRangeMax, processId, code, ...) \
#define LOG_INTERNAL(logLevel, logRangeMin, logRangeMax, processId, code, message) \
do \
{ \
IF_LOG_ANY(logLevel) \
{ \
logInternal(logLevel, logRangeMin, logRangeMax, processId, __FILE__, __func__, code, __VA_ARGS__); \
logInternal(logLevel, logRangeMin, logRangeMax, processId, __FILE__, __func__, code, message); \
} \
} while (0)
#define LOG_PID(logLevel, processId, code, ...) \
LOG_INTERNAL(logLevel, LOG_LEVEL_MIN, LOG_LEVEL_MAX, processId, code, __VA_ARGS__)
#define LOG_INTERNAL_FMT(logLevel, logRangeMin, logRangeMax, processId, code, ...) \
do \
{ \
IF_LOG_ANY(logLevel) \
{ \
logInternalFmt(logLevel, logRangeMin, logRangeMax, processId, __FILE__, __func__, code, __VA_ARGS__); \
} \
} while (0)
#define LOG_ASSERT_PID(processId, ...) \
LOG_PID(logLevelAssert, processId, errorTypeCode(&AssertError), __VA_ARGS__)
#define LOG_ERROR_PID(processId, code, ...) \
LOG_PID(logLevelError, processId, code, __VA_ARGS__)
#define LOG_WARN_PID(processId, ...) \
LOG_PID(logLevelWarn, processId, 0, __VA_ARGS__)
#define LOG_INFO_PID(processId, ...) \
LOG_PID(logLevelInfo, processId, 0, __VA_ARGS__)
#define LOG_DETAIL_PID(processId, ...) \
LOG_PID(logLevelDetail, processId, 0, __VA_ARGS__)
#define LOG_DEBUG_PID(processId, ...) \
LOG_PID(logLevelDebug, processId, 0, __VA_ARGS__)
#define LOG_TRACE_PID(processId, ...) \
LOG_PID(logLevelTrace, processId, 0, __VA_ARGS__)
#define LOG_PID(logLevel, processId, code, message) \
LOG_INTERNAL(logLevel, LOG_LEVEL_MIN, LOG_LEVEL_MAX, processId, code, message)
#define LOG(logLevel, code, ...) \
LOG_PID(logLevel, 0, code, __VA_ARGS__)
#define LOG_ASSERT_PID(processId, message) \
LOG_PID(logLevelAssert, processId, errorTypeCode(&AssertError), message)
#define LOG_ERROR_PID(processId, code, message) \
LOG_PID(logLevelError, processId, code, message)
#define LOG_WARN_PID(processId, message) \
LOG_PID(logLevelWarn, processId, 0, message)
#define LOG_INFO_PID(processId, message) \
LOG_PID(logLevelInfo, processId, 0, message)
#define LOG_DETAIL_PID(processId, message) \
LOG_PID(logLevelDetail, processId, 0, message)
#define LOG_DEBUG_PID(processId, message) \
LOG_PID(logLevelDebug, processId, 0, message)
#define LOG_TRACE_PID(processId, message) \
LOG_PID(logLevelTrace, processId, 0, message)
#define LOG_ASSERT(...) \
LOG(logLevelAssert, errorTypeCode(&AssertError), __VA_ARGS__)
#define LOG_ERROR(code, ...) \
LOG(logLevelError, code, __VA_ARGS__)
#define LOG_WARN(...) \
LOG(logLevelWarn, 0, __VA_ARGS__)
#define LOG_INFO(...) \
LOG(logLevelInfo, 0, __VA_ARGS__)
#define LOG_DETAIL(...) \
LOG(logLevelDetail, 0, __VA_ARGS__)
#define LOG_DEBUG(...) \
LOG(logLevelDebug, 0, __VA_ARGS__)
#define LOG_TRACE(...) \
LOG(logLevelTrace, 0, __VA_ARGS__)
#define LOG_PID_FMT(logLevel, processId, code, ...) \
LOG_INTERNAL_FMT(logLevel, LOG_LEVEL_MIN, LOG_LEVEL_MAX, processId, code, __VA_ARGS__)
#define LOG_ASSERT_PID_FMT(processId, ...) \
LOG_PID_FMT(logLevelAssert, processId, errorTypeCode(&AssertError), __VA_ARGS__)
#define LOG_ERROR_PID_FMT(processId, code, ...) \
LOG_PID_FMT(logLevelError, processId, code, __VA_ARGS__)
#define LOG_WARN_PID_FMT(processId, ...) \
LOG_PID_FMT(logLevelWarn, processId, 0, __VA_ARGS__)
#define LOG_INFO_PID_FMT(processId, ...) \
LOG_PID_FMT(logLevelInfo, processId, 0, __VA_ARGS__)
#define LOG_DETAIL_PID_FMT(processId, ...) \
LOG_PID_FMT(logLevelDetail, processId, 0, __VA_ARGS__)
#define LOG_DEBUG_PID_FMT(processId, ...) \
LOG_PID_FMT(logLevelDebug, processId, 0, __VA_ARGS__)
#define LOG_TRACE_PID_FMT(processId, ...) \
LOG_PID_FMT(logLevelTrace, processId, 0, __VA_ARGS__)
#define LOG(logLevel, code, message) \
LOG_PID(logLevel, 0, code, message)
#define LOG_ASSERT(message) \
LOG(logLevelAssert, errorTypeCode(&AssertError), message)
#define LOG_ERROR(code, message) \
LOG(logLevelError, code, message)
#define LOG_WARN(message) \
LOG(logLevelWarn, 0, message)
#define LOG_INFO(message) \
LOG(logLevelInfo, 0, message)
#define LOG_DETAIL(message) \
LOG(logLevelDetail, 0, message)
#define LOG_DEBUG(message) \
LOG(logLevelDebug, 0, message)
#define LOG_TRACE(message) \
LOG(logLevelTrace, 0, message)
#define LOG_FMT(logLevel, code, ...) \
LOG_PID_FMT(logLevel, 0, code, __VA_ARGS__)
#define LOG_ASSERT_FMT(...) \
LOG_FMT(logLevelAssert, errorTypeCode(&AssertError), __VA_ARGS__)
#define LOG_ERROR_FMT(code, ...) \
LOG_FMT(logLevelError, code, __VA_ARGS__)
#define LOG_WARN_FMT(...) \
LOG_FMT(logLevelWarn, 0, __VA_ARGS__)
#define LOG_INFO_FMT(...) \
LOG_FMT(logLevelInfo, 0, __VA_ARGS__)
#define LOG_DETAIL_FMT(...) \
LOG_FMT(logLevelDetail, 0, __VA_ARGS__)
#define LOG_DEBUG_FMT(...) \
LOG_FMT(logLevelDebug, 0, __VA_ARGS__)
#define LOG_TRACE_FMT(...) \
LOG_FMT(logLevelTrace, 0, __VA_ARGS__)
/***********************************************************************************************************************************
Internal Functions
Internal Functions (in virtually all cases the macros above should be used in preference to these functions)
***********************************************************************************************************************************/
// Log function
void logInternal(
LogLevel logLevel, LogLevel logRangeMin, LogLevel logRangeMax, unsigned int processId, const char *fileName,
const char *functionName, int code, const char *format, ...);
const char *functionName, int code, const char *message);
// Log function with formatting
void logInternalFmt(
LogLevel logLevel, LogLevel logRangeMin, LogLevel logRangeMax, unsigned int processId, const char *fileName,
const char *functionName, int code, const char *format, ...) __attribute__((format(printf, 8, 9)));
#endif

View File

@ -143,7 +143,7 @@ cfgLoadUpdateOption(void)
// If the repo-type is defined, then see if corresponding retention-full is set
if (cfgOptionTest(cfgOptRepoType + optionIdx) && !cfgOptionTest(cfgOptRepoRetentionFull + optionIdx))
{
LOG_WARN(
LOG_WARN_FMT(
"option %s is not set, the repository may run out of space"
"\nHINT: to retain full backups indefinitely (without warning), set option '%s' to the maximum.",
cfgOptionName(cfgOptRepoRetentionFull + optionIdx),
@ -187,7 +187,7 @@ cfgLoadUpdateOption(void)
}
else
{
LOG_WARN("%s neither option '%s' nor option '%s' is set", strPtr(msgArchiveOff),
LOG_WARN_FMT("%s neither option '%s' nor option '%s' is set", strPtr(msgArchiveOff),
cfgOptionName(cfgOptRepoRetentionArchive + optionIdx),
cfgOptionName(cfgOptRepoRetentionDiff + optionIdx));
}
@ -196,7 +196,7 @@ cfgLoadUpdateOption(void)
{
CHECK(strEqZ(archiveRetentionType, CFGOPTVAL_TMP_REPO_RETENTION_ARCHIVE_TYPE_INCR));
LOG_WARN("%s option '%s' is not set", strPtr(msgArchiveOff),
LOG_WARN_FMT("%s option '%s' is not set", strPtr(msgArchiveOff),
cfgOptionName(cfgOptRepoRetentionArchive + optionIdx));
}
}
@ -208,7 +208,7 @@ cfgLoadUpdateOption(void)
if ((strEqZ(archiveRetentionType, CFGOPTVAL_TMP_REPO_RETENTION_ARCHIVE_TYPE_DIFF)) &&
(!cfgOptionTest(cfgOptRepoRetentionDiff + optionIdx)))
{
LOG_WARN("option '%s' is not set for '%s=%s'\n"
LOG_WARN_FMT("option '%s' is not set for '%s=%s'\n"
"HINT: to retain differential backups indefinitely (without warning), set option '%s' to the maximum.",
cfgOptionName(cfgOptRepoRetentionDiff + optionIdx),
cfgOptionName(cfgOptRepoRetentionArchiveType + optionIdx),

View File

@ -646,19 +646,19 @@ configParse(unsigned int argListSize, const char *argList[], bool resetLogLevel)
// Warn if the option not found
if (optionList[optionIdx].name == NULL)
{
LOG_WARN("environment contains invalid option '%s'", strPtr(key));
LOG_WARN_FMT("environment contains invalid option '%s'", strPtr(key));
continue;
}
// Warn if negate option found in env
else if (optionList[optionIdx].val & PARSE_NEGATE_FLAG)
{
LOG_WARN("environment contains invalid negate option '%s'", strPtr(key));
LOG_WARN_FMT("environment contains invalid negate option '%s'", strPtr(key));
continue;
}
// Warn if reset option found in env
else if (optionList[optionIdx].val & PARSE_RESET_FLAG)
{
LOG_WARN("environment contains invalid reset option '%s'", strPtr(key));
LOG_WARN_FMT("environment contains invalid reset option '%s'", strPtr(key));
continue;
}
@ -749,19 +749,19 @@ configParse(unsigned int argListSize, const char *argList[], bool resetLogLevel)
// Warn if the option not found
if (optionList[optionIdx].name == NULL)
{
LOG_WARN("configuration file contains invalid option '%s'", strPtr(key));
LOG_WARN_FMT("configuration file contains invalid option '%s'", strPtr(key));
continue;
}
// Warn if negate option found in config
else if (optionList[optionIdx].val & PARSE_NEGATE_FLAG)
{
LOG_WARN("configuration file contains negate option '%s'", strPtr(key));
LOG_WARN_FMT("configuration file contains negate option '%s'", strPtr(key));
continue;
}
// Warn if reset option found in config
else if (optionList[optionIdx].val & PARSE_RESET_FLAG)
{
LOG_WARN("configuration file contains reset option '%s'", strPtr(key));
LOG_WARN_FMT("configuration file contains reset option '%s'", strPtr(key));
continue;
}
@ -771,7 +771,7 @@ configParse(unsigned int argListSize, const char *argList[], bool resetLogLevel)
/// Warn if this option should be command-line only
if (cfgDefOptionSection(optionDefId) == cfgDefSectionCommandLine)
{
LOG_WARN("configuration file contains command-line only option '%s'", strPtr(key));
LOG_WARN_FMT("configuration file contains command-line only option '%s'", strPtr(key));
continue;
}
@ -794,7 +794,7 @@ configParse(unsigned int argListSize, const char *argList[], bool resetLogLevel)
// Warn if it is in a command section
if (sectionIdx % 2 == 0)
{
LOG_WARN(
LOG_WARN_FMT(
"configuration file contains option '%s' invalid for section '%s'", strPtr(key),
strPtr(section));
continue;
@ -807,7 +807,7 @@ configParse(unsigned int argListSize, const char *argList[], bool resetLogLevel)
if (cfgDefOptionSection(optionDefId) == cfgDefSectionStanza &&
strBeginsWithZ(section, CFGDEF_SECTION_GLOBAL))
{
LOG_WARN(
LOG_WARN_FMT(
"configuration file contains stanza-only option '%s' in global section '%s'", strPtr(key),
strPtr(section));
continue;

View File

@ -89,7 +89,7 @@ dbGet(bool primaryOnly, bool primaryRequired)
}
CATCH_ANY()
{
LOG_WARN("unable to check pg-%u: [%s] %s", pgIdx + 1, errorTypeName(errorType()), errorMessage());
LOG_WARN_FMT("unable to check pg-%u: [%s] %s", pgIdx + 1, errorTypeName(errorType()), errorMessage());
db = NULL;
}
TRY_END();

View File

@ -673,7 +673,7 @@ infoBackupLoadFileReconstruct(const Storage *storage, const String *fileName, Ci
if (manData->pgId == pgHistory.id && manData->pgSystemId == pgHistory.systemId &&
manData->pgVersion == pgHistory.version)
{
LOG_WARN("backup '%s' found in repository added to " INFO_BACKUP_FILE, strPtr(backupLabel));
LOG_WARN_FMT("backup '%s' found in repository added to " INFO_BACKUP_FILE, strPtr(backupLabel));
infoBackupDataAdd(infoBackup, manifest);
found = true;
break;
@ -681,7 +681,7 @@ infoBackupLoadFileReconstruct(const Storage *storage, const String *fileName, Ci
}
if (!found)
LOG_WARN("invalid backup '%s' cannot be added to current backups", strPtr(manData->backupLabel));
LOG_WARN_FMT("invalid backup '%s' cannot be added to current backups", strPtr(manData->backupLabel));
}
}
}
@ -697,7 +697,7 @@ infoBackupLoadFileReconstruct(const Storage *storage, const String *fileName, Ci
// Remove backup from the current list in the infoBackup object
if (!storageExistsP(storage, manifestFileName))
{
LOG_WARN("backup '%s' missing manifest removed from " INFO_BACKUP_FILE, strPtr(backupLabel));
LOG_WARN_FMT("backup '%s' missing manifest removed from " INFO_BACKUP_FILE, strPtr(backupLabel));
infoBackupDataDelete(infoBackup, backupLabel);
}
}

View File

@ -306,7 +306,7 @@ storageS3Request(
if (strEq(errorCode, S3_ERROR_REQUEST_TIME_TOO_SKEWED_STR))
{
LOG_DEBUG(
LOG_DEBUG_FMT(
"retry %s: %s", strPtr(errorCode),
strPtr(xmlNodeContent(xmlNodeChild(error, S3_XML_TAG_MESSAGE_STR, true))));

View File

@ -164,7 +164,7 @@ testRun(void)
}
// *****************************************************************************************************************************
if (testBegin("logInternal()"))
if (testBegin("logInternal() and logInternalFmt()"))
{
TEST_RESULT_VOID(logInit(logLevelOff, logLevelOff, logLevelOff, false, 1), "init logging to off");
TEST_RESULT_VOID(
@ -195,7 +195,7 @@ testRun(void)
logBuffer[0] = 0;
TEST_RESULT_VOID(
logInternal(logLevelWarn, LOG_LEVEL_MIN, LOG_LEVEL_MAX, 0, "file", "function", 0, "format %d", 99), "log warn");
logInternalFmt(logLevelWarn, LOG_LEVEL_MIN, LOG_LEVEL_MAX, 0, "file", "function", 0, "format %d", 99), "log warn");
TEST_RESULT_STR(logBuffer, "P00 WARN: format 99\n", " check log");
// This won't be logged due to the range