Observability with Bash: Leveraging .bashrc for Command Monitoring

Padmajeet Mhaske
3 min read3 days ago

Introduction

In the world of software development and operations, observability has become a crucial aspect of maintaining and improving system performance and reliability. Observability refers to the ability to understand the internal state of a system based on the data it produces, such as logs, metrics, and traces. While observability is often associated with complex distributed systems, it can also be applied to simpler environments, such as command-line interfaces.

In this article, we will explore how to implement observability in a Bash environment by leveraging the .bashrc file. By capturing and logging command execution details, we can gain valuable insights into user behavior, system performance, and potential issues.

Importance of Observability

Observability provides several benefits, including:

  1. Improved Debugging: By capturing detailed information about command execution, developers and system administrators can quickly identify and resolve issues.
  2. Performance Monitoring: Observability allows for the tracking of command execution times, helping to identify performance bottlenecks and optimize workflows.
  3. Security Auditing: Logging command execution can help detect unauthorized or suspicious activities, enhancing system security.
  4. User Behavior Analysis: Understanding how users interact with the system can inform improvements to user experience and system design.

Implementing Observability in Bash

To implement observability in a Bash environment, we can modify the .bashrc file to capture and log command execution details. Below is a sample implementation that logs command execution time, command content, and other relevant information.

Code Sample

1# Variable to store the command to be logged
2export LAST_COMMAND=""
3
4# Function to log the start time and capture the command before each command
5log_start_time() {
6 export START_TIME=$(date +%s%3N)
7 LAST_COMMAND="$BASH_COMMAND"
8}
9
10# Function to calculate and display the execution time after each command
11calculate_execution_time() {
12 local end_time=$(date +%s%3N)
13 local exec_time=$((end_time - START_TIME))
14 echo "Command execution time: ${exec_time} ms"
15 export EXEC_TIME=$exec_time
16}
17
18# Function to log and send command
19log_and_send_command() {
20 local command="$LAST_COMMAND"
21 echo "Executing command: $command"
22 # Temporarily disable trap and PROMPT_COMMAND
23 trap - DEBUG
24 PROMPT_COMMAND=""
25 # Execute the command and capture any error
26 eval "$command"
27 local exit_status=$?
28 # Re-enable trap and PROMPT_COMMAND
29 trap 'log_start_time' DEBUG
30 PROMPT_COMMAND='calculate_execution_time; log_and_send_command'
31
39 # Encode the command using base64
40 local encoded_command=$(echo -n "$command" | base64)
41 # Decode the command for printing
42 local decoded_command=$(echo "$encoded_command" | base64 --decode)
43 echo "Encoded command: $encoded_command"
44 echo "Decoded command: $decoded_command"
45 local data=$(printf '{"id":"%s","ipAddress":"%s","cellContent":"%s","cellExecutionTime":%d,"sessionId":"session_id_placeholder","executionCount":0,"errorBeforeExec":"","startTime":"%s","errorInExec":"%s"}' "$id" "$(hostname -I | awk '{print $1}')" "$encoded_command" "$EXEC_TIME" "$(date -u +"%Y-%m-%dT%H:%M:%S.%3N")" "$error_in_exec")
46 echo "Data to be sent to REST API: $data"
47 echo "Endpoint REST API: ${ES_HOST}"
48 curl -X POST "${ES_HOST}" \
49 -H "Content-Type: application/json" \
50 -d "$data"
51}
52
53# Ensure ES_HOST is set correctly
54export ES_HOST='https://es-service'
55
56# Set trap to call the function before each command
57trap 'log_start_time' DEBUG
58
59# Set PROMPT_COMMAND to call the function after each command
60PROMPT_COMMAND='calculate_execution_time; log_and_send_command'

Explanation

  • Command Capture: The log_start_time function captures the command being executed and stores it in the LAST_COMMAND variable.
  • Execution Time Calculation: The calculate_execution_time function calculates the time taken to execute the command and logs it.
  • Command Logging: The log_and_send_command function logs the command details, encodes the command using base64, and sends the data to a REST API endpoint for further analysis.

Conclusion

By leveraging the .bashrc file, we can implement observability in a Bash environment to capture and log command execution details. This approach provides valuable insights into system performance, user behavior, and potential security issues. While this implementation is a simple example, it can be extended and customized to meet specific observability requirements.

Observability is a powerful tool that can enhance the reliability and performance of systems, and its principles can be applied to various environments, from complex distributed systems to simple command-line interfaces.

--

--

Padmajeet Mhaske
Padmajeet Mhaske

Written by Padmajeet Mhaske

Padmajeet is a seasoned leader in artificial intelligence and machine learning, currently serving as the VP and AI/ML Application Architect at JPMorgan Chase.

No responses yet