Skip to content

Instantly share code, notes, and snippets.

@lox
Created May 24, 2023 02:35
Show Gist options
  • Save lox/18f2b7f7e88d02602ed3f31b12d4f1e4 to your computer and use it in GitHub Desktop.
Save lox/18f2b7f7e88d02602ed3f31b12d4f1e4 to your computer and use it in GitHub Desktop.
Stream stdin to cloudwatch logs
#!/bin/bash
# Enable bash strict mode
set -euo pipefail
IFS=$'\n\t'
# Disable the pager for aws commands (no less on the host)
export AWS_PAGER=""
# Get the log group arn as a parameter and cut the group name out of it
# Looks like arn:aws:logs:us-west-2:123456789012:log-group:/my/log/group
log_group_arn="$1"
log_group=$(echo "${log_group_arn}" | awk -F ':log-group:' '{print $2}')
log_stream="$(/usr/local/bin/bk-ec2-instance-meta-data instance-id)"
# Ensure the log stream exists, create if it doesn't
log_stream_exists=$(aws logs describe-log-streams --log-group-name "${log_group}" \
--log-stream-name-prefix "${log_stream}" \
--query 'logStreams[?logStreamName==`'"${log_stream}"'`].logStreamName' \
--output text)
if [ -z "$log_stream_exists" ]; then
aws logs create-log-stream --log-group-name "${log_group}" \
--log-stream-name "${log_stream}" || { echo >&2 "Failed to create log stream."; exit 1; }
fi
# Function to send a message to CloudWatch Logs
send_message_to_logs() {
local message="${1}"
local sequence_token
sequence_token=$(aws logs describe-log-streams \
--log-group-name "${log_group}" \
--log-stream-name-prefix "${log_stream}" \
--query 'logStreams[0].uploadSequenceToken' \
--output text)
# Remove trailing newline characters
message=$(echo -n "$message" | tr -d '\n')
# Use json encoding for the message to escape chars that cause issues
local json_message
json_message=$(jq -aRs . <<< "$message")
if [ "$sequence_token" = "None" ]; then
aws logs put-log-events \
--log-group-name "${log_group}" \
--log-stream-name "${log_stream}" \
--log-events "timestamp=$(date +%s000),message=${json_message}"
else
aws logs put-log-events \
--log-group-name "${log_group}" \
--log-stream-name "${log_stream}" \
--log-events "timestamp=$(date +%s000),message=${json_message}" \
--sequence-token "$sequence_token"
fi
}
# Read stdin and send each line to CloudWatch Logs
while IFS= read -r line; do
send_message_to_logs "${line}"
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment