You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-07-15 01:04:37 +02:00
Improve logging.
Move command begin to C except when it must be called after another command in Perl (e.g. expire after backup). Command begin logs correctly for complex data types like hash and list. Specify which commands will log to file immediately and set the default log level for log messages that are common to all commands. File logging is initiated from C.
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
/***********************************************************************************************************************************
|
||||
Common Command Routines
|
||||
***********************************************************************************************************************************/
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "common/log.h"
|
||||
@ -14,53 +15,95 @@ Begin the command
|
||||
void
|
||||
cmdBegin()
|
||||
{
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
// A command must be set
|
||||
assert(cfgCommand() != cfgCmdNone);
|
||||
|
||||
// This is fairly expensive log message to generate so skip it if it won't be output
|
||||
if (logWill(cfgLogLevelDefault()))
|
||||
{
|
||||
// Basic info on command start
|
||||
String *info = strNewFmt("%s command begin %s:", cfgCommandName(cfgCommand()), PGBACKREST_VERSION);
|
||||
|
||||
// Loop though options and add the ones that are interesting
|
||||
for (ConfigOption optionId = 0; optionId < CFG_OPTION_TOTAL; optionId++)
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
const Variant *option = cfgOption(optionId);
|
||||
// Basic info on command start
|
||||
String *info = strNewFmt("%s command begin %s:", cfgCommandName(cfgCommand()), PGBACKREST_VERSION);
|
||||
|
||||
// Skip the option if it is not valid, or default, or not set
|
||||
if (!cfgOptionValid(optionId) ||
|
||||
cfgOptionSource(optionId) == cfgSourceDefault ||
|
||||
(option == NULL && !cfgOptionNegate(optionId)))
|
||||
// Loop though options and add the ones that are interesting
|
||||
for (ConfigOption optionId = 0; optionId < CFG_OPTION_TOTAL; optionId++)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// Skip the option if it is not valid
|
||||
if (!cfgOptionValid(optionId))
|
||||
continue;
|
||||
|
||||
// If option was negated
|
||||
if (cfgOptionNegate(optionId))
|
||||
strCatFmt(info, " --no-%s", cfgOptionName(optionId));
|
||||
// Else not negated
|
||||
else
|
||||
{
|
||||
ConfigDefineOption optionDefId = cfgOptionDefIdFromId(optionId);
|
||||
strCatFmt(info, " --%s", cfgOptionName(optionId));
|
||||
|
||||
if (cfgDefOptionType(optionDefId) != cfgDefOptTypeBoolean)
|
||||
// If option was negated
|
||||
if (cfgOptionNegate(optionId))
|
||||
strCatFmt(info, " --no-%s", cfgOptionName(optionId));
|
||||
// If option was reset
|
||||
else if (cfgOptionReset(optionId))
|
||||
strCatFmt(info, " --reset-%s", cfgOptionName(optionId));
|
||||
// Else set and not default
|
||||
else if (cfgOptionSource(optionId) != cfgSourceDefault && cfgOptionTest(optionId))
|
||||
{
|
||||
ConfigDefineOption optionDefId = cfgOptionDefIdFromId(optionId);
|
||||
|
||||
// Don't show redacted options
|
||||
if (cfgDefOptionSecure(optionDefId))
|
||||
strCat(info, "=<redacted>");
|
||||
strCatFmt(info, " --%s=<redacted>", cfgOptionName(optionId));
|
||||
// Output boolean option
|
||||
else if (cfgDefOptionType(optionDefId) == cfgDefOptTypeBoolean)
|
||||
strCatFmt(info, " --%s", cfgOptionName(optionId));
|
||||
// Output other options
|
||||
else
|
||||
{
|
||||
const String *optionStr = varStrForce(option);
|
||||
StringList *valueList = NULL;
|
||||
|
||||
if (strchr(strPtr(optionStr), ' ') != NULL)
|
||||
optionStr = strNewFmt("\"%s\"", strPtr(optionStr));
|
||||
// Generate the values of hash options
|
||||
if (cfgDefOptionType(optionDefId) == cfgDefOptTypeHash)
|
||||
{
|
||||
valueList = strLstNew();
|
||||
|
||||
strCatFmt(info, "=%s", strPtr(optionStr));
|
||||
const KeyValue *optionKv = cfgOptionKv(optionId);
|
||||
const VariantList *keyList = kvKeyList(optionKv);
|
||||
|
||||
for (unsigned int keyIdx = 0; keyIdx < varLstSize(keyList); keyIdx++)
|
||||
{
|
||||
strLstAdd(
|
||||
valueList,
|
||||
strNewFmt(
|
||||
"%s=%s", strPtr(varStr(varLstGet(keyList, keyIdx))),
|
||||
strPtr(varStrForce(kvGet(optionKv, varLstGet(keyList, keyIdx))))));
|
||||
}
|
||||
}
|
||||
// Generate values for list options
|
||||
else if (cfgDefOptionType(optionDefId) == cfgDefOptTypeList)
|
||||
{
|
||||
valueList = strLstNewVarLst(cfgOptionLst(optionId));
|
||||
}
|
||||
// Else only one value
|
||||
else
|
||||
{
|
||||
valueList = strLstNew();
|
||||
strLstAdd(valueList, varStrForce(cfgOption(optionId)));
|
||||
}
|
||||
|
||||
// Output options and values
|
||||
for (unsigned int valueListIdx = 0; valueListIdx < strLstSize(valueList); valueListIdx++)
|
||||
{
|
||||
const String *value = strLstGet(valueList, valueListIdx);
|
||||
|
||||
strCatFmt(info, " --%s", cfgOptionName(optionId));
|
||||
|
||||
if (strchr(strPtr(value), ' ') != NULL)
|
||||
value = strNewFmt("\"%s\"", strPtr(value));
|
||||
|
||||
strCatFmt(info, "=%s", strPtr(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LOG_INFO(strPtr(info));
|
||||
LOG_ANY(cfgLogLevelDefault(), 0, strPtr(info));
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -69,17 +112,24 @@ End the command
|
||||
void
|
||||
cmdEnd(int code)
|
||||
{
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
// A command must be set
|
||||
assert(cfgCommand() != cfgCmdNone);
|
||||
|
||||
// Skip this log message if it won't be output. It's not too expensive but since we skipped cmdBegin(), may as well.
|
||||
if (logWill(cfgLogLevelDefault()))
|
||||
{
|
||||
// Basic info on command end
|
||||
String *info = strNewFmt("%s command end: ", cfgCommandName(cfgCommand()));
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
// Basic info on command end
|
||||
String *info = strNewFmt("%s command end: ", cfgCommandName(cfgCommand()));
|
||||
|
||||
if (code == 0)
|
||||
strCat(info, "completed successfully");
|
||||
else
|
||||
strCatFmt(info, "aborted with exception [%03d]", code);
|
||||
if (code == 0)
|
||||
strCat(info, "completed successfully");
|
||||
else
|
||||
strCatFmt(info, "aborted with exception [%03d]", code);
|
||||
|
||||
LOG_INFO(strPtr(info));
|
||||
LOG_ANY(cfgLogLevelDefault(), 0, strPtr(info));
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
}
|
||||
|
Reference in New Issue
Block a user