How to Save Hashicorp Nomad Logs with Nomad CLI and Bash
The aim of this page📝 is to explain how to modify a bash script to redirect output to a file and remove ANSI escape codes, based on the particular example of a script used to print HashiCorp Nomad logs. In my case, I constantly check the logs and often forward them, say as an attachment to Jira tickets.
- Originally, I had a bash script that printed HashiCorp Nomad logs.
#!/bin/bash
nomad_job_id_regex="(?<=jobs/)\S+"
job=$(echo "$1" | grep -Po "$nomad_job_id_regex")
echo
echo "-----STERR-----"
nomad alloc logs -job --stderr "$job"
echo
echo "-----STDOUT-----"
nomad alloc logs -job "$job"
- I wanted to modify the script to redirect the output to two separate files, one for
stderr
and one forstdout
. - The
tee
command can be used to write output to a file while also sending it to stdout. - However, my logs contained ANSI escape codes, which are used to colorize output.
[31m│[0m [0m[0m
[31m│[0m [0mThe given key does not identify an element in this collection value.
[31m╵[0m[0m
[31m╷[0m[0m
[31m│[0m [0m[1m[31mError: [0m[0m[1mInvalid index[0m
[31m│[0m [0m
- the escape codes in my logs are used to colorize the output. Here’s what they mean:
[31m
: This sets the text color to red.[0m
: This resets all attributes (color, bold, etc.) to their defaults.[1m
: This sets the text attribute to bold.[4m
: This sets the text attribute to underline.[90m
: This sets the text color to bright black (also known as gray).
So for example, [31m╷[0m[0m
would display a red "╷" symbol, and [1m[31mError: [0m[0m[1mInvalid index[0m
would display the word "Error:" in bold red, followed by "Invalid index" in bold with default color.
These codes are interpreted by my terminal or terminal emulator to display colored or styled text. When you redirect the output to a file or view it in a context that doesn’t interpret these codes (like a text editor), they appear as strange characters.
- The modified script:
#!/bin/bash
nomad_job_id_regex="(?<=jobs/)\S+"
job=$(echo "$1" | grep -Po "$nomad_job_id_regex")
echo
echo "-----STERR-----"
nomad alloc logs -job --stderr "$job" | sed 's/\x1b\[[0-9;]*m//g' | tee temp_stderr.log
echo
echo "-----STDOUT-----"
nomad alloc logs -job "$job" | sed 's/\x1b\[[0-9;]*m//g' | tee temp_stdout.log
#!/bin/bash
: This is called a shebang. It tells the system that this script should be executed using the bash shell.nomad_job_id_regex="(?<=jobs/)\S+"
: This line defines a regular expression that matches any non-whitespace characters (\S+
) that come after "jobs/" ((?<=jobs/)
) in a string.job=$(echo "$1" | grep -Po "$nomad_job_id_regex")
: This line uses thegrep
command with the-P
option (which enables Perl-compatible regular expressions) and the-o
option (which prints only the matching parts of a line) to find the job ID in the first argument to the script ($1
). The result is stored in the variablejob
.echo
: This command prints a blank line to stdout.echo "—————STERR—————"
: This command prints "—————STERR—————" to stdout.nomad alloc logs -job --stderr "$job" | sed 's/\x1b\[[0-9;]*m//g' | tee temp_stderr.log
: This line does several things:
nomad alloc logs -job --stderr "$job"
: This command fetches the stderr logs for the Nomad job with the ID stored injob
.| sed 's/\x1b\[[0-9;]*m//g'
: The output from the previous command is piped (|
) intosed
, which removes all ANSI escape codes from it.| tee temp_stderr.log
: The output from the previous command is piped into, which writes it to a file named "temp_stderr.log" and also prints it to stdout.
The next three lines do essentially the same thing but for stdout instead of stderr. This script allows you to fetch and clean up Nomad logs, and write them to separate files for stderr and stdout. It’s a great example of how you can use bash scripting to automate tasks and make your life easier!