blob: 7455b487d28b57153a5763fcc22c2e06d383e5c0 [file] [log] [blame]
#!/system/bin/sh
# Copyright 2016 Nest Labs, Inc. All rights reserved.
# Base directory that contains any log reporter state files.
LOG_STATE_DIR="/data/misc/logrotate"
LOG_DIR="/data/misc/logd/"
# Max upload/download rate
LIMIT_RATE="200K"
# Log sender lock in case the sender is already running.
LOG_SENDER_LOCK="${LOG_STATE_DIR}/lock/log_sender"
# File descriptor to reference lock file, single digit only in Android Shell(mksh)
LOG_SENDER_LOCK_FD=9
# Path to a CA certificate file for log server
CA_CERTIFICATES_FILE_PATH="/system/etc/dropcam_calist.pem"
SSL_CERT="/data/misc/certs/device_cert.pem"
SSL_CERT_TYPE="PEM"
SSL_KEY="/data/misc/certs/device_cert.key"
SSL_KEY_TYPE="PEM"
# File whose existence implies we're running and not to start again.
RUN_FILE="${LOG_STATE_DIR}/run/log_sender.pid"
# The tag for all logging we emit.
TAG="$(basename $0)[$$]"
# Directory to store timestamp files indicating the uploads in the past 24
# hours.
TIMESTAMPS_DIR="${LOG_STATE_DIR}/log_sender"
# Temp directory for this process.
TMP_DIR=""
lecho() {
log -t "${TAG}" "$@"
}
lwarn() {
lecho -psyslog.warn "$@"
}
die () {
lecho $@
lecho "Exit"
exit 1
}
cleanup() {
if [ -n "${TMP_DIR}" ]; then
rm -rf "${TMP_DIR}"
fi
rm -f "${RUN_FILE}"
# clean all log_sender files in case things are going wrong
rm -rf /data/misc/logrotate/tmp/log_sender*
}
# Returns true if uploading is enabled
is_upload_enabled() {
[ "$(get_key_value "log.upload_enabled")" -eq 1 ] && return 0
return 1
}
get_key_value() {
local key="$1" value
value=`getprop persist.nl.${key}`
echo "${value:-undefined}"
}
send_log() {
local log_path="$1"
local url="$(get_key_value "log.server")"
local send_size="$(stat -c "%s" "${log_path}" 2>/dev/null)"
local mac=`sysenv get hwaddr0`
# Cloud does not parse ":" in MAC address, so remove all of them
mac=${mac//":"/""}
# If log_reporter.server is not set return with an error.
if [ -z "${url}" ]; then
lecho "Configuration error: log server not set."
return 1
fi
if [[ -z "${mac}" || ${#mac} -ne 12 ]]; then
lecho "Configuration error: mac address is invalid."
return 1
fi
lecho "Sending log:"
lecho " MAC: ${mac}"
lecho " File: ${log_path}"
lecho " URL: ${url}"
lecho " Size: ${send_size}"
local curl_stderr="${TMP_DIR}/curl_stderr"
local curl_report="${TMP_DIR}/report"
set +e
curl -vvv "${url}" \
--cacert "${CA_CERTIFICATES_FILE_PATH}" \
--cert "${SSL_CERT}" \
--cert-type "${SSL_CERT_TYPE}" \
--key "${SSL_KEY}" \
--key-type "${SSL_KEY_TYPE}" \
--limit-rate "${LIMIT_RATE}" \
-F "mac=${mac}" \
-F "file=@${log_path};type=application/octet-stream" \
-o "${curl_report}" \
2>"${curl_stderr}"
curl_result=$?
set -e
if [ -f ${curl_report} ]; then
lecho "Message from server: " \
"$(cat "${curl_report}")"
fi
if [ ${curl_result} -eq 0 ]; then
local timestamp="$(date +%s)"
lecho "Log ${log_path} has been sent at ${timestamp}"
else
lecho "Log sending failed with exit code ${curl_result}: " \
"$(cat "${curl_stderr}")"
fi
rm -f "${curl_report}"
rm -f "${curl_stderr}"
return ${curl_result}
}
# *.meta files always end with done=1 so we can tell if they are complete.
# Remove the given report path.
remove_report() {
rm -f -- "${1}"
}
# Send all logs from the given directory.
send_logs() {
local dir="$1"
lecho "Sending logs for ${dir}"
if [ ! -d "${dir}" ]; then
die "Can't find directory ${dir}"
fi
# start from old
for log_path in $(ls -1tr "${dir}"/messages.*.gz 2>/dev/null); do
lecho "Considering log ${log_path}."
# Try to upload.
if ! send_log "${log_path}"; then
lecho "Problem sending ${log_path}, not removing."
continue
fi
# Send was successful, now remove.
lecho "Successfully sent log ${log_path} and removing."
remove_report "${log_path}"
done
}
main() {
lecho "Starting log uploading..."
if ! is_upload_enabled;
then
lecho "Log uploading is disabled. Exit."
exit 0;
fi
# We don't perform checks on this because we have a master lock with the
# LOG_SENDER_LOCK file. This pid file is for the system to keep track
# that we're still running.
echo $$ > "${RUN_FILE}"
TMP_DIR="$(mktemp -d "${LOG_STATE_DIR}/tmp/log_sender.XXXXXX")"
if [ $? -ne 0 ]; then
die "Failed to create TMP_DIR: ${LOG_STATE_DIR}/tmp/log_sender.XXXXX"
fi
# Send system-wide logs
send_logs "${LOG_DIR}"
}
trap cleanup EXIT INT TERM
mkdir -p $(dirname ${LOG_SENDER_LOCK})
(
# -x:Exclusive lock, -n:Non-blocking
flock -xn 9 || die "Failed to acquire lock!"
main "$@"
) 9>$LOG_SENDER_LOCK