Skip to content

Instantly share code, notes, and snippets.

@kitzberger
Last active November 4, 2025 16:36
Show Gist options
  • Select an option

  • Save kitzberger/0f0fa7900f7032a365b400c077d38b24 to your computer and use it in GitHub Desktop.

Select an option

Save kitzberger/0f0fa7900f7032a365b400c077d38b24 to your computer and use it in GitHub Desktop.
#!/bin/bash
# TYPO3 Log Tail Formatter
# Formats TYPO3 log files with custom column rendering
# Parse arguments
COMPACT=false
LOG_PATH=""
MAX_LINES=""
JQ_FILTER="."
GREP_PATTERN=""
NO_JSON=false
for arg in "$@"; do
if [ "$arg" = "--compact" ]; then
COMPACT=true
elif [ "$arg" = "--no-json" ]; then
NO_JSON=true
elif [[ "$arg" =~ ^--max-lines=([0-9]+)$ ]]; then
MAX_LINES="${BASH_REMATCH[1]}"
elif [[ "$arg" =~ ^--jq=(.+)$ ]]; then
JQ_FILTER="${BASH_REMATCH[1]}"
elif [[ "$arg" =~ ^--grep=(.+)$ ]]; then
GREP_PATTERN="${BASH_REMATCH[1]}"
else
LOG_PATH="$arg"
fi
done
# Use default path if none provided
LOG_PATH="${LOG_PATH:-var/log/typo3_*.log}"
# Set up tail pipeline
if [ -n "$GREP_PATTERN" ]; then
TAIL_CMD="tail -f $LOG_PATH | grep --line-buffered '$GREP_PATTERN'"
else
TAIL_CMD="tail -f $LOG_PATH"
fi
eval "$TAIL_CMD" | while IFS= read -r line; do
# Parse the log line
# Format: Fri, 24 Oct 2025 10:53:28 +0200 [DEBUG] request="9be3da5813753" component="...": message - {json}
if [[ $line =~ ^([^[]+)\[([A-Z]+)\]\ request=\"([^\"]+)\"\ component=\"([^\"]+)\":\ ([^-]+)-\ (\{.*\})$ ]]; then
datetime="${BASH_REMATCH[1]}"
severity="${BASH_REMATCH[2]}"
request="${BASH_REMATCH[3]}"
component="${BASH_REMATCH[4]}"
message="${BASH_REMATCH[5]}"
json="${BASH_REMATCH[6]}"
# Format datetime based on compact mode
if [ "$COMPACT" = true ]; then
formatted_time=$(date -d "$datetime" "+%H:%M:%S" 2>/dev/null || echo "$datetime")
else
formatted_time=$(date -d "$datetime" "+%Y-%m-%d %H:%M:%S" 2>/dev/null || echo "$datetime")
fi
# Shorten request to 4 characters
request_short="${request:0:4}"
# Format component based on compact mode
if [ "$COMPACT" = true ]; then
# Shorten component: keep uppercase chars and last part complete
# E.g., Extcode.CartPayone.EventListener.Order.Payment.ProviderRedirect
# => E.CP.EL.O.P.ProviderRedirect
IFS='.' read -ra PARTS <<< "$component"
component_formatted=""
for i in "${!PARTS[@]}"; do
if [ $i -eq $((${#PARTS[@]} - 1)) ]; then
# Last part: keep complete
component_formatted+="${PARTS[$i]}"
else
# Other parts: extract uppercase letters
uppercase=$(echo "${PARTS[$i]}" | grep -o '[A-Z]' | tr -d '\n')
component_formatted+="${uppercase}."
fi
done
else
# Use full FQCN
component_formatted="$component"
fi
# Print formatted output
echo -e "\033[90m$formatted_time\033[0m \033[1m[$severity]\033[0m \033[36m$request_short\033[0m \033[33m$component_formatted\033[0m: $message"
if [ "$NO_JSON" = false ]; then
if [ -n "$MAX_LINES" ]; then
echo "$json" | jq --color-output "$JQ_FILTER" 2>/dev/null | head -n "$MAX_LINES" || echo "$json"
else
echo "$json" | jq --color-output "$JQ_FILTER" 2>/dev/null || echo "$json"
fi
fi
elif [[ $line =~ ^([^[]+)\[([A-Z]+)\]\ request=\"([^\"]+)\"\ component=\"([^\"]+)\":\ (.+)$ ]]; then
# Line without JSON
datetime="${BASH_REMATCH[1]}"
severity="${BASH_REMATCH[2]}"
request="${BASH_REMATCH[3]}"
component="${BASH_REMATCH[4]}"
message="${BASH_REMATCH[5]}"
# Format datetime based on compact mode
if [ "$COMPACT" = true ]; then
formatted_time=$(date -d "$datetime" "+%H:%M:%S" 2>/dev/null || echo "$datetime")
else
formatted_time=$(date -d "$datetime" "+%Y-%m-%d %H:%M:%S" 2>/dev/null || echo "$datetime")
fi
# Shorten request to 4 characters
request_short="${request:0:4}"
# Format component based on compact mode
if [ "$COMPACT" = true ]; then
# Shorten component
IFS='.' read -ra PARTS <<< "$component"
component_formatted=""
for i in "${!PARTS[@]}"; do
if [ $i -eq $((${#PARTS[@]} - 1)) ]; then
component_formatted+="${PARTS[$i]}"
else
uppercase=$(echo "${PARTS[$i]}" | grep -o '[A-Z]' | tr -d '\n')
component_formatted+="${uppercase}."
fi
done
else
# Use full FQCN
component_formatted="$component"
fi
# Print formatted output
echo -e "\033[90m$formatted_time\033[0m \033[1m[$severity]\033[0m \033[36m$request_short\033[0m \033[33m$component_formatted\033[0m: $message"
else
# Print line as-is if it doesn't match the pattern
echo "$line"
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment