ℹ️ Select 'Choose Exercise', or randomize 'Next Random Exercise' in selected language.

Choose Exercise:
Timer 00:00
WPM --
Score --
Acc --
Correct chars --

Simple Log Aggregation with `tail -f` and `tee`

Shell (sh)

Goal -- WPM

Ready
Exercise Algorithm Area
1#!/bin/sh
2
3# Script to aggregate multiple log files into a single output file.
4# Uses tail -f to monitor files and tee to duplicate output.
5
6# --- Configuration ---
7OUTPUT_LOG="/var/log/aggregated_app.log"
8LOG_FILES=(
9"/var/log/service1.log"
10"/var/log/service2.log"
11"/var/log/service3.log"
12)
13
14# --- Helper Functions ---
15
16# Function to check if a file exists and is readable.
17_is_readable() {
18local file="$1"
19if [ -r "$file" ]; then
20return 0 # Success
21else
22return 1 # Failure
23fi
24}
25
26# --- Main Execution ---
27
28# Clear the output log if it exists, or create it.
29if [ -f "$OUTPUT_LOG" ]; then
30echo "Clearing existing output log: $OUTPUT_LOG"
31> "$OUTPUT_LOG"
32else
33echo "Creating output log: $OUTPUT_LOG"
34touch "$OUTPUT_LOG"
35if [ $? -ne 0 ]; then
36echo "Error: Could not create output log '$OUTPUT_LOG'. Exiting." >&2
37exit 1
38fi
39fi
40
41echo "Starting log aggregation..."
42echo "Monitoring files: ${LOG_FILES[*]}"
43echo "Aggregated output will be in: $OUTPUT_LOG"
44
45# Prepare the tail commands
46TAIL_COMMANDS=""
47for log_file in "${LOG_FILES[@]}"; do
48# Check if the log file exists before adding it to tail
49if _is_readable "$log_file"; then
50TAIL_COMMANDS="$TAIL_COMMANDS tail -f \"$log_file\" | "
51else
52echo "Warning: Log file '$log_file' not found or not readable. Skipping."
53fi
54done
55
56# Remove the trailing " | " if any commands were added
57if [ -n "$TAIL_COMMANDS" ]; then
58TAIL_COMMANDS="${TAIL_COMMANDS% | }"
59else
60echo "Error: No readable log files found to monitor. Exiting." >&2
61exit 1
62fi
63
64# Execute the combined tail commands and pipe to tee
65# tee will write to the aggregated log and also to stdout
66# Using eval here to correctly handle multiple piped commands
67eval "$TAIL_COMMANDS | tee -a \"$OUTPUT_LOG\""
68
69# Note: This script will run indefinitely until interrupted (e.g., Ctrl+C).
70# The 'eval' is used to correctly construct and execute the piped command string.
71# The '-a' option for tee appends to the output file.
Algorithm description viewbox

Simple Log Aggregation with `tail -f` and `tee`

Algorithm description:

This script aggregates logs from multiple sources into a single file. It uses `tail -f` to continuously monitor each specified log file and pipes their output. The `tee -a` command then appends this combined stream to a designated output log file while also displaying it on standard output. This is useful for centralizing logs from different services or applications for easier monitoring and debugging.

Algorithm explanation:

The script initializes by clearing or creating the main output log file. It then iterates through a list of log files, checking if each is readable using a helper function `_is_readable`. For each readable file, it constructs a `tail -f` command. These commands are then chained together using pipes (`|`) and the entire sequence is executed using `eval`. The final output of all `tail -f` processes is piped to `tee -a`. `tee -a` duplicates the input stream: one copy is appended to the specified `OUTPUT_LOG` file, and another copy is sent to standard output. This allows for real-time viewing of aggregated logs while also persisting them. The script runs indefinitely until manually interrupted. The primary complexity lies in constructing the command string dynamically and handling potential errors like non-existent log files. Time complexity is effectively O(N*M) where N is the number of log files and M is the rate of log entries, as `tail -f` and `tee` are efficient I/O operations.

Pseudocode:

1. Define the output log file path and an array of input log file paths.
2. Define a helper function `_is_readable` that checks if a file exists and is readable.
3. Clear the output log file if it exists, or create it if it doesn't.
4. Handle errors if the output log cannot be created.
5. Initialize an empty string for `tail` commands.
6. Loop through each input log file:
    a. Use `_is_readable` to check if the file is accessible.
    b. If readable, append `tail -f <file>` and a pipe symbol to the `tail` commands string.
    c. If not readable, print a warning and skip.
7. If no readable log files were found, print an error and exit.
8. Remove the trailing pipe symbol from the `tail` commands string.
9. Construct the final command string: `<tail_commands> | tee -a <output_log_file>`.
10. Execute the final command string using `eval`.
11. The script will continue running until interrupted.