feat(log): Use plain-text logging for all messages
Convert all logging output to plain-text structured messages using new function.
This commit is contained in:
@@ -139,23 +139,24 @@ exitOK() {
|
|||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# 1: cloudflare error object, 2: operation identifier
|
||||||
listCFErrors() {
|
listCFErrors() {
|
||||||
# extract error codes and messages in separate variables, replace newlines with underscores
|
# extract error codes and messages in separate variables, replace newlines with underscores
|
||||||
codes="$(printf "%s" "$1" | jq -r '.errors | .[] | .code' | tr '\n' '_')"
|
codes="$(printf "%s" "$1" | jq -r '.errors | .[] | .code' | tr '\n' '_')"
|
||||||
messages="$(printf "%s" "$1" | jq -r '.errors | .[] | .message' | tr '\n' '_')"
|
messages="$(printf "%s" "$1" | jq -r '.errors | .[] | .message' | tr '\n' '_')"
|
||||||
|
|
||||||
# iterate codes and messages and assemble into coherent messages in log
|
# iterate codes and messages, assemble into a coherent log message
|
||||||
while [ -n "$codes" ] && [ -n "$messages" ]; do
|
while [ -n "$codes" ] && [ -n "$messages" ]; do
|
||||||
# get first code and message in respective sets
|
# get the first code and message in respective sets
|
||||||
code="${codes%%_*}"
|
code="${codes%%_*}"
|
||||||
message="${messages%%_*}"
|
message="${messages%%_*}"
|
||||||
|
|
||||||
# update codes and messages sets by removing first item in each set
|
# update sets of codes and messages by removing the first item (above) in each set
|
||||||
codes="${codes#*_}"
|
codes="${codes#*_}"
|
||||||
messages="${messages#*_}"
|
messages="${messages#*_}"
|
||||||
|
|
||||||
# output to log
|
# output to log
|
||||||
writeLog cf "$message" "$code"
|
writePlainTextLog "${message}" "err" "fail" "$2" "$code"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -415,18 +416,24 @@ done
|
|||||||
### pre-flight checks
|
### pre-flight checks
|
||||||
if ! command -v curl >/dev/null; then
|
if ! command -v curl >/dev/null; then
|
||||||
printf "\n%sThis script requires 'curl' be installed and accessible. Exiting.%s\n\n" "$err" "$norm"
|
printf "\n%sThis script requires 'curl' be installed and accessible. Exiting.%s\n\n" "$err" "$norm"
|
||||||
|
writePlainTextLog "'curl' must be installed and accessible" "fatal" "fail" "preexec" 2
|
||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
if ! command -v jq >/dev/null; then
|
if ! command -v jq >/dev/null; then
|
||||||
printf "\n%sThis script requires 'jq' be installed and accessible. Exiting.%s\n\n" "$err" "$norm"
|
printf "\n%sThis script requires 'jq' be installed and accessible. Exiting.%s\n\n" "$err" "$norm"
|
||||||
|
writePlainTextLog "'jq' must be installed and accessible" "fatal" "fail" "preexec" 2
|
||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
[ -z "$dnsRecords" ] && badParam errMsg "You must specify at least one DNS record to update. Exiting."
|
if [ -z "$dnsRecords" ]; then
|
||||||
# verify credentials file exists and is not empty (default check)
|
badParam errMsg "You must specify at least one DNS record to update. Exiting."
|
||||||
if [ ! -f "$accountFile" ] || [ ! -s "$accountFile" ]; then
|
writePlainTextLog "At least one DNS record to update must be specified" "fatal" "fail" "params" 1
|
||||||
badParam errMsg "Cannot find Cloudflare credentials file (${accountFile}). Exiting."
|
|
||||||
fi
|
fi
|
||||||
if ! command -v logger >/dev/null 2>&1; then
|
# verify the credentials file exists and is not empty (default check)
|
||||||
|
if [ ! -f "$accountFile" ] || [ ! -s "$accountFile" ]; then
|
||||||
|
badParam errMsg "Cannot find the Cloudflare credentials file (${accountFile}). Exiting."
|
||||||
|
writePlainTextLog "Cannot find the specified Cloudflare credentials file (${accountFile})" "fatal" "fail" "params" 1
|
||||||
|
fi
|
||||||
|
if [ "$logToJournal" -eq 1 ] && ! command -v logger >/dev/null 2>&1; then
|
||||||
printf "\n%sThis script requires 'logger' be installed to write entries to your journaling system. Exiting.%s\n\n" "$err" "$norm"
|
printf "\n%sThis script requires 'logger' be installed to write entries to your journaling system. Exiting.%s\n\n" "$err" "$norm"
|
||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
@@ -443,17 +450,14 @@ if [ "$colourizeLogFile" -eq 0 ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
### initial log entries
|
### initial log entries
|
||||||
{
|
writePlainTextLog "starting '${scriptName}'" "info" "ok" "script"
|
||||||
|
writePlainTextLog "script path: ${scriptPath}/${scriptName}" "debug" "ok" "startup"
|
||||||
printf "%s[%s] -- Cloudflare DDNS update-script: starting --%s\n" "$ok" "$(stamp)" "$norm"
|
writePlainTextLog "credentials file: ${accountFile}" "debug" "ok" "startup"
|
||||||
printf "Parameters:\n"
|
|
||||||
printf "script path: %s\n" "$scriptPath/$scriptName"
|
|
||||||
printf "credentials file: %s\n" "$accountFile"
|
|
||||||
|
|
||||||
if [ "$ip4" -eq 1 ]; then
|
if [ "$ip4" -eq 1 ]; then
|
||||||
printf "mode: IP4\n"
|
writePlainTextLog "mode: IPv4" "debug" "ok" "startup"
|
||||||
elif [ "$ip6" -eq 1 ]; then
|
elif [ "$ip6" -eq 1 ]; then
|
||||||
printf "mode: IP6\n"
|
writePlainTextLog "mode: IPv6" "debug" "ok" "startup"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# detect and report IP address
|
# detect and report IP address
|
||||||
@@ -461,19 +465,21 @@ fi
|
|||||||
# detect public ip address
|
# detect public ip address
|
||||||
if [ "$ip4" -eq 1 ]; then
|
if [ "$ip4" -eq 1 ]; then
|
||||||
if ! ipAddress="$(curl -s $ip4DetectionSvc)"; then
|
if ! ipAddress="$(curl -s $ip4DetectionSvc)"; then
|
||||||
printf "ddns ip address:%s ERROR%s\n" "$err" "$norm"
|
writePlainTextLog \
|
||||||
exitError 10
|
"Unable to auto-detect this machine's public IP address; try again later or supply the IP address to be used" "err" "fail" "detectip" 10
|
||||||
|
exit 10
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
if [ "$ip6" -eq 1 ]; then
|
if [ "$ip6" -eq 1 ]; then
|
||||||
if ! ipAddress="$(curl -s $ip6DetectionSvc)"; then
|
if ! ipAddress="$(curl -s $ip6DetectionSvc)"; then
|
||||||
printf "ddns ip address:%s ERROR%s\n" "$err" "$norm"
|
writePlainTextLog \
|
||||||
exitError 10
|
"Unable to auto-detect this machine's public IP address; try again later or supply the IP address to be used" "err" "fail" "detectip" 10
|
||||||
|
exit 10
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
printf "ddns ip address (detected): %s\n" "$ipAddress"
|
writePlainTextLog "DDNS IP address (detected): $ipAddress" "info" "ok" "startup"
|
||||||
else
|
else
|
||||||
printf "ddns ip address (supplied): %s\n" "$ipAddress"
|
writePlainTextLog "DDNS IP address (supplied): $ipAddress" "info" "ok" "startup"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# iterate DNS records to update
|
# iterate DNS records to update
|
||||||
@@ -485,14 +491,10 @@ fi
|
|||||||
if [ -z "$record" ]; then
|
if [ -z "$record" ]; then
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
printf "updating record: %s\n" "$record"
|
writePlainTextLog "DNS host record '${record}' queued for update" "info" "ok" "startup"
|
||||||
done
|
done
|
||||||
|
|
||||||
printf "(end of parameter list)\n"
|
|
||||||
} >>"$logFile"
|
|
||||||
|
|
||||||
### read Cloudflare credentials
|
### read Cloudflare credentials
|
||||||
writeLog process "Reading Cloudflare credentials"
|
|
||||||
case "$accountFile" in
|
case "$accountFile" in
|
||||||
/*)
|
/*)
|
||||||
# absolute path, use as-is
|
# absolute path, use as-is
|
||||||
@@ -506,14 +508,14 @@ case "$accountFile" in
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
if [ -z "$cfKey" ]; then
|
if [ -z "$cfKey" ]; then
|
||||||
writeLog process-error
|
writePlainTextLog "Cloudflare authorized API key (cfKey) is either null or undefined; please check your Cloudflare credentials file" "err" "fail" "creds" 21
|
||||||
exitError 21
|
exit 21
|
||||||
fi
|
fi
|
||||||
if [ -z "$cfZoneId" ]; then
|
if [ -z "$cfZoneId" ]; then
|
||||||
writeLog process-error
|
writePlainTextLog "Cloudflare zone id (cfZoneId) is either null or undefined; please check your Cloudflare credentials file" "err" "fail" "creds" 22
|
||||||
exitError 22
|
exit 22
|
||||||
fi
|
fi
|
||||||
writeLog process-done "DONE"
|
writePlainTextLog "Cloudflare credentials file read successfully" "debug" "ok" "creds"
|
||||||
|
|
||||||
### connect to Cloudflare and do what needs to be done!
|
### connect to Cloudflare and do what needs to be done!
|
||||||
dnsRecordsToUpdate="$dnsRecords$dnsSeparator"
|
dnsRecordsToUpdate="$dnsRecords$dnsSeparator"
|
||||||
@@ -531,7 +533,6 @@ while [ -n "$dnsRecordsToUpdate" ] && [ "$dnsRecordsToUpdate" != "$dnsSeparator"
|
|||||||
if [ -z "$record" ]; then
|
if [ -z "$record" ]; then
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
writeLog process "Processing ${record}"
|
|
||||||
|
|
||||||
# exit if curl/network error
|
# exit if curl/network error
|
||||||
if ! cfLookup="$(
|
if ! cfLookup="$(
|
||||||
@@ -539,43 +540,39 @@ while [ -n "$dnsRecordsToUpdate" ] && [ "$dnsRecordsToUpdate" != "$dnsSeparator"
|
|||||||
-H "Authorization: Bearer ${cfKey}" \
|
-H "Authorization: Bearer ${cfKey}" \
|
||||||
-H "Content-Type: application/json"
|
-H "Content-Type: application/json"
|
||||||
)"; then
|
)"; then
|
||||||
writeLog process-error
|
writePlainTextLog "Unable to connect to Cloudflare servers; please try again later." "err" "fail" "cflogin" 3
|
||||||
exitError 3
|
exit 3
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# exit if API error
|
# an API error on this GET request likely indicates an authentication error that would affect all remaining operations
|
||||||
# exit here since API errors on GET request probably indicates authentication error which would affect all remaining operations
|
# no reason to continue processing other dns records and pile-up errors which might look like a DoS attempt
|
||||||
# no reason to continue processing other hosts and pile-up errors which might look like a DoS attempt
|
|
||||||
cfSuccess="$(printf "%s" "$cfLookup" | jq -r '.success')"
|
cfSuccess="$(printf "%s" "$cfLookup" | jq -r '.success')"
|
||||||
if [ "$cfSuccess" = "false" ]; then
|
if [ "$cfSuccess" = "false" ]; then
|
||||||
writeLog process-error
|
listCFErrors "$cfLookup" "cflogin"
|
||||||
listCFErrors "$cfLookup"
|
writePlainTextLog "Cloudflare API error; review any previously logged 'CF-ERR:' lines for details." "err" "fail" "cflogin" 25
|
||||||
exitError 25
|
exit 25
|
||||||
fi
|
fi
|
||||||
|
|
||||||
resultCount="$(printf "%s" "$cfLookup" | jq '.result_info.count')"
|
resultCount="$(printf "%s" "$cfLookup" | jq '.result_info.count')"
|
||||||
|
|
||||||
# skip to next host if cannot find existing host record (this script *updates* only, does not create!)
|
# skip to the next host if an existing host record cannot be found (this script *updates* only, does not create!)
|
||||||
if [ "$resultCount" = "0" ]; then
|
if [ "$resultCount" = "0" ]; then
|
||||||
# warn if record of host not found
|
writePlainTextLog "Cannot find an existing record matching '${record}' to update" "warn" "warn" "ddns"
|
||||||
writeLog process-warning "NOT FOUND"
|
|
||||||
writeLog warn "Cannot find existing record to update for DNS entry: ${record}"
|
|
||||||
invalidDomainCount=$((invalidDomainCount + 1))
|
invalidDomainCount=$((invalidDomainCount + 1))
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
objectId=$(printf "%s" "$cfLookup" | jq -r '.result | .[] | .id')
|
objectId=$(printf "%s" "$cfLookup" | jq -r '.result | .[] | .id')
|
||||||
currentIpAddr=$(printf "%s" "$cfLookup" | jq -r '.result | .[] | .content')
|
currentIpAddr=$(printf "%s" "$cfLookup" | jq -r '.result | .[] | .content')
|
||||||
writeLog process-done "FOUND: IP = ${currentIpAddr}"
|
writePlainTextLog "The current IP address for '${record}' is ${currentIpAddr}" "debug" "ok" "ddns"
|
||||||
|
|
||||||
# skip to next hostname if record already up-to-date
|
# skip to next hostname if record already up to date
|
||||||
if [ "$currentIpAddr" = "$ipAddress" ]; then
|
if [ "$currentIpAddr" = "$ipAddress" ]; then
|
||||||
writeLog stamped "IP address for ${record} is already up-to-date"
|
writePlainTextLog "The IP address for '${record}' is already up to date" "info" "ok" "ddns"
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# update record
|
# update record
|
||||||
writeLog process "Updating IP address for ${record}"
|
|
||||||
updateJSON="$(jq -n --arg key0 content --arg value0 "${ipAddress}" '{($key0):$value0}')"
|
updateJSON="$(jq -n --arg key0 content --arg value0 "${ipAddress}" '{($key0):$value0}')"
|
||||||
|
|
||||||
# exit if curl/network error
|
# exit if curl/network error
|
||||||
@@ -585,19 +582,17 @@ while [ -n "$dnsRecordsToUpdate" ] && [ "$dnsRecordsToUpdate" != "$dnsSeparator"
|
|||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
--data "${updateJSON}"
|
--data "${updateJSON}"
|
||||||
)"; then
|
)"; then
|
||||||
writeLog process-error
|
writePlainTextLog "Unable to connect to Cloudflare servers; please try again later." "err" "fail" "ddns" 3
|
||||||
exitError 3
|
exit 3
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# note update success or failure
|
# note update success or failure
|
||||||
cfSuccess="$(printf "%s" "$cfResult" | jq '.success')"
|
cfSuccess="$(printf "%s" "$cfResult" | jq '.success')"
|
||||||
if [ "$cfSuccess" = "true" ]; then
|
if [ "$cfSuccess" = "true" ]; then
|
||||||
writeLog process-done "DONE"
|
writePlainTextLog "The IP address for '${record}' successfully updated" "info" "ok" "ddns"
|
||||||
writeLog success "IP address for ${record} updated."
|
|
||||||
else
|
else
|
||||||
writeLog process-error
|
listCFErrors "$cfResult" "ddns"
|
||||||
listCFErrors "$cfResult"
|
writePlainTextLog "Unable to update the IP address for '${record}'" "err" "fail" "ddns"
|
||||||
writeLog err "Unable to update IP address for ${record}"
|
|
||||||
# do not exit with error, API error here is probably an update issue specific to this host
|
# do not exit with error, API error here is probably an update issue specific to this host
|
||||||
# increment counter and note it after all processing finished
|
# increment counter and note it after all processing finished
|
||||||
failedHostCount=$((failedHostCount + 1))
|
failedHostCount=$((failedHostCount + 1))
|
||||||
@@ -606,12 +601,14 @@ done
|
|||||||
|
|
||||||
# exit
|
# exit
|
||||||
if [ "$invalidDomainCount" -ne 0 ]; then
|
if [ "$invalidDomainCount" -ne 0 ]; then
|
||||||
writeLog warning "${invalidDomainCount} invalid host(s) supplied for updating."
|
writePlainTextLog "${invalidDomainCount} invalid host(s) were supplied for updating" "warn" "warn" "ddns"
|
||||||
fi
|
fi
|
||||||
if [ "$failedHostCount" -ne 0 ]; then
|
if [ "$failedHostCount" -ne 0 ]; then
|
||||||
exitError 26
|
writePlainTextLog \
|
||||||
|
"${failedHostCount} host update(s) failed; review 'CF-ERR:' lines in this log to help determine what may have gone wrong" "err" "fail" "ddns" 26
|
||||||
|
exit 26
|
||||||
else
|
else
|
||||||
exitOK
|
writePlainTextLog "${scriptName} completed successfully" "info" "ok" "script"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
### exit return codes
|
### exit return codes
|
||||||
|
|||||||
Reference in New Issue
Block a user