Skip to content

Commit

Permalink
Add logger configuration support and improved setup (#12)
Browse files Browse the repository at this point in the history
* Add logger configuration support and improved setup

With this commit, I have added support for configuring the logger either through the command line, json config, or both. This allows the user to specify the log level, the log type (JSON or STDOUT), and the log file if they are choosing to log to a file. 

I have also done a bit of work to enhance the README, including changing the build instructions to better support older versions of CMAKE and updating the setup.sh script to provide a better experience.

* Update README and FileUtils

I have updated the readme to utilize a more exact specifier for building the test executable for running unit tests. I have also updated a method signature in FileUtils to use a constant string reference based on a PR comment.
  • Loading branch information
matthewpaul committed Dec 8, 2020
1 parent b77c1c3 commit 056cb07
Show file tree
Hide file tree
Showing 19 changed files with 642 additions and 171 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -2,6 +2,7 @@
cmake-build-debug/
sdk-cpp-workspace/
out/
build/

# Ignore compiled documentation folders
doc/html/
Expand Down
1 change: 0 additions & 1 deletion CMakeLists.txt
Expand Up @@ -8,7 +8,6 @@ list(APPEND CMAKE_MODULE_PATH "./sdk-cpp-workspace/lib/cmake")

file(GLOB DC_SRC "source/*.cpp" /
"source/*.c" /
"source/external/cJSON/*.c" /
"source/**/*.cpp" /
"source/**/*.c")

Expand Down
60 changes: 55 additions & 5 deletions README.md
Expand Up @@ -20,11 +20,16 @@ Options:
aws-iot-device-sdk-cpp-v2
* BUILD_TEST_DEPS: This CMake flag is set to `ON` by default, will enable CMake to pull and build googletest

Use the following `cmake` commands to build the AWS IoT Device Client with dependencies and tests.
Use the following `cmake` commands to build the AWS IoT Device Client with dependencies and tests. These should be run
with `aws-iot-device-client` (the contents of this repository) in a folder called `aws-iot-device-client` in your
current working directory:

```bash
cmake -S aws-iot-device-client -B aws-iot-device-client/build
cmake --build aws-iot-device-client/build --target aws-iot-device-client
mkdir aws-iot-device-client/build
cd aws-iot-device-client/build
cmake ../
cmake --build . --target aws-iot-device-client
cmake --build . --target test-aws-iot-device-client # This line builds the test executable
```

##### Build With Dependencies Already Installed
Expand All @@ -38,10 +43,20 @@ applicable if you already have the aws-iot-device-sdk-cpp-v2 installed on your d
* The Device Client tests require that [googletest](https://github.com/google/googletest) is installed.

Use the following `cmake` commands to build the AWS IoT Device Client with already existing and installed dependencies.
These commands should be run with `aws-iot-device-client` (the contents of this repository) in a folder called
`aws-iot-device-client` in your current working directory

```bash
cmake -DBUILD_SDK=OFF -DBUILD_TEST_DEPS=OFF -S aws-iot-device-client -B aws-iot-device-client/build
cmake --build aws-iot-device-client/build --target aws-iot-device-client
mkdir aws-iot-device-client/build
cd aws-iot-device-client/build
cmake ../ -DBUILD_SDK=OFF -DBUILD_TEST_DEPS=OFF
cmake --build . --target aws-iot-device-client
cmake --build . --target test-aws-iot-device-client # This line builds the test executable
```

### Running the tests
```
./build/test-aws-iot-device-client
```

### Setting Up The Device Client
Expand All @@ -59,6 +74,41 @@ To use the script, run the following command.
./setup.sh
```

### Usage
Configuration information can be passed to the AWS IoT Device Client through either the command line, a JSON configuration
file, or both. For a complete list of available command line arguments, pass `--help` to the executable.

#### Configuring the AWS IoT Device Client's Logger
The AWS IoT Device Client has the capability to log directly to standard output or write logs to a log file. For
either option, the logging level can be specified as either DEBUG, INFO, WARN, or ERROR. The logger implementation
can be specified as either "STDOUT" (for standard output) or "FILE" (for logging to a file). If file based logging
is specified, you can also specify a file to log to. If a file is not specified, the Device Client will log to
the default log location of `/var/log/aws-iot-device-client.log`. Keep in mind that the Device Client will need
elevated permissions to log to this location, and will automatically fall back to STDOUT logging if the Device Client
is unable to log to either the specified or default location.

###### Example
Configuring the logger via the command line:
```
./aws-iot-device-client --log-level WARN --log-type FILE --log-file ./aws-iot-device-client.log
```

Configuring the logger via JSON:
```
{
...
"logging": {
"level": "WARN",
"type": "FILE",
"file": "./aws-iot-device-client.log"
}
...
}
```
If you've decided to add additional logs to the AWS IoT Device Client's source code, the high-level
logging API macros can be found in `source/logging/LoggerFactory.h` and typically follow the convention of
`LOG_XXXX` for simple log messages and `LOGM_XXXX` for logs that should be formatted with variadic arguments.

### Security

See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information.
Expand Down
146 changes: 90 additions & 56 deletions setup.sh
@@ -1,6 +1,11 @@
#!/bin/sh
set -e

if ! [ $(id -u) = 0 ]; then
echo "WARNING: Please run this setup script as root (sudo), otherwise you may encounter problems installing the" \
"AWS IoT Device Client as a service and/or installing important files"
fi

# Prompt color constants
PMPT='\033[95;1m'
GREEN='\033[92m'
Expand All @@ -9,37 +14,55 @@ NC='\033[0m'

### Build Configuration File ###

echo -e "${PMPT}Do you want to interactively generate a configuration file for the AWS IoT Device Client? y/n${NC}"
echo "${PMPT}Do you want to interactively generate a configuration file for the AWS IoT Device Client? y/n${NC}"
read -r BUILD_CONFIG

if [ "$BUILD_CONFIG" = "y" ]; then
while [ "$CONFIGURED" != 1 ]
do
echo -e "${PMPT}Specify AWS IoT endpoint to use:${NC}"
while [ "$CONFIGURED" != 1 ]; do
echo "${PMPT}Specify AWS IoT endpoint to use:${NC}"
read -r ENDPOINT
echo -e "${PMPT}Specify absolute path to public PEM certificate:${NC}"
read -e -r CERT
echo -e "${PMPT}Specify absolute path to private key:${NC}"
read -e -r PRIVATE_KEY
echo -e "${PMPT}Specify absolute path to ROOT CA certificate:${NC}"
read -e -r ROOT_CA
echo "${PMPT}Specify absolute path to public PEM certificate:${NC}"
read -r CERT
echo "${PMPT}Specify absolute path to private key:${NC}"
read -r PRIVATE_KEY
echo "${PMPT}Specify absolute path to ROOT CA certificate:${NC}"
read -r ROOT_CA
echo "${PMPT}Specify thing name:${NC}"
read -r THING_NAME

### Logging Config ###
echo "${PMPT}Would you like to configure the logger? y/n${NC}"
CONFIGURE_LOGS=""
read -r CONFIGURE_LOGS
if [ "$CONFIGURE_LOGS" = "y" ]; then
echo "${PMPT}Specify desired log level: DEBUG/INFO/WARN/ERROR${NC}"
read -r LOG_LEVEL
echo "${PMPT}Specify log type: STDOUT for standard output, FILE for file${NC}"
read -r LOG_TYPE
if [ "$LOG_TYPE" = "FILE" ] || [ "$LOG_TYPE" = "file" ]; then
echo "${PMPT}Specify path to desired log file:${NC}"
read -r LOG_LEVEL
fi
else
LOG_LEVEL="DEBUG"
LOG_TYPE="FILE"
LOG_FILE="/var/log/aws-iot-device-client.log"
fi

### Jobs Config ###
echo -e "${PMPT}Enable Jobs feature? y/n${NC}"
echo "${PMPT}Enable Jobs feature? y/n${NC}"
JOBS_ENABLED=""
read -r ENABLE_JOBS
if [ "$ENABLE_JOBS" = "y" ]; then
JOBS_ENABLED="true"
echo -e "${PMPT}Specify thing name:${NC}"
read -r THING_NAME
echo -e "${PMPT}Specify absolute path to Job handler directory:${NC}"
read -e -r HANDLER_DIR
echo "${PMPT}Specify absolute path to Job handler directory:${NC}"
read -r HANDLER_DIR
else
JOBS_ENABLED="false"
fi

### ST Config ###
echo -e "${PMPT}Enable Secure Tunneling feature? y/n${NC}"
echo "${PMPT}Enable Secure Tunneling feature? y/n${NC}"
ST_ENABLED=""
read -r ENABLE_ST
if [ "$ENABLE_ST" = "y" ]; then
Expand All @@ -54,28 +77,42 @@ if [ "$BUILD_CONFIG" = "y" ]; then
\"cert\": \"$CERT\",
\"key\": \"$PRIVATE_KEY\",
\"root-ca\": \"$ROOT_CA\",
\"thing-name\": \"$THING_NAME\",
\"logging\": {
\"level\": \"$LOG_LEVEL\",
\"type\": \"$LOG_TYPE\",
\"file\": \"$LOG_FILE\"
},
\"jobs\": {
\"enabled\": \"$JOBS_ENABLED\",
\"thing_name\": \"$THING_NAME\",
\"handler_directory\": \"$HANDLER_DIR\"
},
\"tunneling\": {
\"enabled\": \"$ST_ENABLED\"
}
}"

echo -e "${PMPT}Does the following configuration appear correct? y/n${NC}"
echo -e "${GREEN}${CONFIG_OUTPUT}${NC}"
echo "${PMPT}Does the following configuration appear correct? y/n${NC}"
echo "${GREEN}${CONFIG_OUTPUT}${NC}"
read -r GOOD_TO_GO
if [ "$GOOD_TO_GO" = "y" ]; then
CONFIGURED=1
echo "$CONFIG_OUTPUT" | sudo tee /etc/aws-iot-device-client.conf > /dev/null
echo "$CONFIG_OUTPUT" | tee /etc/aws-iot-device-client.conf >/dev/null
fi
tput sgr0
done
fi

echo -e "${PMPT}Do you want to install AWS IoT Device Client as a service? y/n${NC}"
echo "${PMPT}Do you want to copy the sample job handlers to the default handler directory? (/etc/aws-iot-device-client/handlers/) y/n${NC}"
read -r COPY_HANDLERS

if [ "$COPY_HANDLERS" = "y" ]; then
mkdir -p /etc/aws-iot-device-client/handlers/
cp ./sample-job-handlers/* /etc/aws-iot-device-client/handlers/
chmod +x /etc/aws-iot-device-client/handlers/*
fi

echo "${PMPT}Do you want to install AWS IoT Device Client as a service? y/n${NC}"
read -r INSTALL_SERVICE

if [ "$INSTALL_SERVICE" = "y" ]; then
Expand All @@ -84,7 +121,7 @@ if [ "$INSTALL_SERVICE" = "y" ]; then
FOUND_DEVICE_CLIENT=false
DEVICE_CLIENT_ARTIFACT_DEFAULT="./build/aws-iot-device-client"
while [ "$FOUND_DEVICE_CLIENT" != true ]; do
echo -e "${PMPT}Enter the complete directory path for the aws-iot-device-client. (Empty for default: ${DEVICE_CLIENT_ARTIFACT_DEFAULT})${NC}"
echo "${PMPT}Enter the complete directory path for the aws-iot-device-client. (Empty for default: ${DEVICE_CLIENT_ARTIFACT_DEFAULT})${NC}"
read -r DEVICE_CLIENT_ARTIFACT
if [ -z "$DEVICE_CLIENT_ARTIFACT" ]; then
DEVICE_CLIENT_ARTIFACT="$DEVICE_CLIENT_ARTIFACT_DEFAULT"
Expand All @@ -100,7 +137,7 @@ if [ "$INSTALL_SERVICE" = "y" ]; then
FOUND_SERVICE_FILE=false
SERVICE_FILE_DEFAULT="./setup/aws-iot-device-client.service"
while [ "$FOUND_SERVICE_FILE" != true ]; do
echo -e "${PMPT}Enter the complete directory path for the aws-iot-device-client service file. (Empty for default: ${SERVICE_FILE_DEFAULT})${NC}"
echo "${PMPT}Enter the complete directory path for the aws-iot-device-client service file. (Empty for default: ${SERVICE_FILE_DEFAULT})${NC}"
read -r SERVICE_FILE
if [ -z "$SERVICE_FILE" ]; then
SERVICE_FILE="$SERVICE_FILE_DEFAULT"
Expand All @@ -112,11 +149,11 @@ if [ "$INSTALL_SERVICE" = "y" ]; then
fi
done

echo -e "${PMPT}Do you want to run the AWS IoT Device Client service via Valgrind for debugging? y/n${NC}"
echo "${PMPT}Do you want to run the AWS IoT Device Client service via Valgrind for debugging? y/n${NC}"
read -r SERVICE_DEBUG
if [ "$SERVICE_DEBUG" = "y" ]; then
LOG_FILE="/var/log/aws-iot-device-client-debug"
echo -e "${GREEN}Valgrind output can be found at $LOG_FILE-{PID}.log. {PID} corresponds
echo "${GREEN}Valgrind output can be found at $LOG_FILE-{PID}.log. {PID} corresponds
to the current process ID of the service, and will change if the system is rebooted${NC}"
DEBUG_SCRIPT="#!/bin/sh
valgrind --log-file=\"${LOG_FILE}-\$\$.log\" /sbin/aws-iot-device-client-bin"
Expand All @@ -125,36 +162,33 @@ if [ "$INSTALL_SERVICE" = "y" ]; then
BINARY_DESTINATION="/sbin/aws-iot-device-client"
fi


echo -e "${PMPT}Installing AWS IoT Device Client...${NC}"
if command -v "systemctl" &> /dev/null;
then
sudo -n systemctl stop aws-iot-device-client.service || true
sudo -n cp "$SERVICE_FILE" /etc/systemd/system/aws-iot-device-client.service
if [ "$SERVICE_DEBUG" = "y" ]; then
echo "$DEBUG_SCRIPT" | sudo tee /sbin/aws-iot-device-client > /dev/null
else
# In case we previously ran in debug, make sure to delete the old binary
sudo -n rm -f /sbin/aws-iot-device-client-bin
fi
sudo -n cp "$DEVICE_CLIENT_ARTIFACT" "$BINARY_DESTINATION"
sudo -n systemctl enable aws-iot-device-client.service
sudo -n systemctl start aws-iot-device-client.service
sudo -n systemctl status aws-iot-device-client.service
elif command -v "service" &> /dev/null;
then
sudo -n service stop aws-iot-device-client.service || true
sudo -n cp "$SERVICE_FILE" /etc/systemd/system/aws-iot-device-client.service
if [ "$SERVICE_DEBUG" = "y" ]; then
echo "$DEBUG_SCRIPT" | sudo tee /sbin/aws-iot-device-client > /dev/null
else
# In case we previously ran in debug, make sure to delete the old binary
sudo -n rm -f /sbin/aws-iot-device-client-bin
fi
sudo -n cp "$DEVICE_CLIENT_ARTIFACT" "$BINARY_DESTINATION"
sudo -n service enable aws-iot-device-client.service
sudo -n service start aws-iot-device-client.service
sudo -n service status aws-iot-device-client.service
echo "${PMPT}Installing AWS IoT Device Client...${NC}"
if command -v "systemctl" &>/dev/null; then
systemctl stop aws-iot-device-client.service || true
cp "$SERVICE_FILE" /etc/systemd/system/aws-iot-device-client.service
if [ "$SERVICE_DEBUG" = "y" ]; then
echo "$DEBUG_SCRIPT" | tee /sbin/aws-iot-device-client >/dev/null
else
# In case we previously ran in debug, make sure to delete the old binary
rm -f /sbin/aws-iot-device-client-bin
fi
cp "$DEVICE_CLIENT_ARTIFACT" "$BINARY_DESTINATION"
systemctl enable aws-iot-device-client.service
systemctl start aws-iot-device-client.service
systemctl status aws-iot-device-client.service
elif command -v "service" &>/dev/null; then
service stop aws-iot-device-client.service || true
cp "$SERVICE_FILE" /etc/systemd/system/aws-iot-device-client.service
if [ "$SERVICE_DEBUG" = "y" ]; then
echo "$DEBUG_SCRIPT" | tee /sbin/aws-iot-device-client >/dev/null
else
# In case we previously ran in debug, make sure to delete the old binary
rm -f /sbin/aws-iot-device-client-bin
fi
cp "$DEVICE_CLIENT_ARTIFACT" "$BINARY_DESTINATION"
service enable aws-iot-device-client.service
service start aws-iot-device-client.service
service status aws-iot-device-client.service
fi
echo -e "${PMPT}AWS IoT Device Client is now running! Check /var/log/aws-iot-device-client.log for log output.${NC}"
echo "${PMPT}AWS IoT Device Client is now running! Check /var/log/aws-iot-device-client.log for log output.${NC}"
fi

0 comments on commit 056cb07

Please sign in to comment.