Added fix for logging signal metrics

Added a fix for signal metrics logging being too aggressive in cleaning output resulting to empty JSONs
This commit is contained in:
Russel Yasol
2025-01-12 17:25:00 +08:00
parent 259d50ee69
commit 97e45f66c6
2 changed files with 140 additions and 77 deletions

View File

@@ -5,7 +5,7 @@ echo "Content-Type: application/json"
echo "" echo ""
# Directory where JSON files are stored (adjust as needed) # Directory where JSON files are stored (adjust as needed)
JSON_DIR="/tmp/signal_graphs/" JSON_DIR="/www/signal_graphs/"
# Function to safely read JSON file # Function to safely read JSON file
read_json_file() { read_json_file() {

View File

@@ -1,23 +1,71 @@
#!/bin/sh #!/bin/sh
# Configuration
LOGDIR="/www/signal_graphs"
MAX_ENTRIES=10
INTERVAL=15
QSCAN_FILE="$LOGDIR/qscan.json"
LOCK_FILE="/tmp/signal_logging.lock"
PAUSE_FILE="/tmp/signal_logging.pause"
# Ensure the directory exists # Ensure the directory exists
LOGDIR="/tmp/signal_graphs"
mkdir -p "$LOGDIR" mkdir -p "$LOGDIR"
# Maximum number of entries # Modified clean_atinout_output function - less aggressive cleaning
MAX_ENTRIES=10
# Interval between logs (in seconds)
INTERVAL=15
# Function to clean and extract actual output from atinout
clean_atinout_output() { clean_atinout_output() {
# Remove first line (echoed command), last line (OK), and trim whitespace # Keep everything between the command and OK, including the actual response
sed -n '2,/^OK$/p' | sed '$d' | tr -d '\r' | xargs sed '1d' | sed '/^OK$/d' | tr -d '\r' | grep -v '^$' | head -n1
} }
# Function to perform cell scan and output JSON response for CGI
perform_cell_scan() {
# Print CGI headers first
printf "Content-Type: application/json\n\n"
# Create pause file to stop continuous logging
touch "$PAUSE_FILE"
# Wait for any ongoing logging to complete
sleep 2
# Perform cell scan sequence
echo "AT+COPS=2" | atinout - /dev/smd7 -
sleep 2
# Run QSCAN and save output to temporary file
echo "AT+QSCAN=3,1" | atinout - /dev/smd7 "$QSCAN_OUT"
sleep 2
# Process QSCAN output and convert to JSON
if [ -f "$QSCAN_OUT" ]; then
# Extract the relevant part and convert to JSON format
sed -n '2,/^OK$/p' < "$QSCAN_OUT" | sed '$d' | tr -d '\r' | \
jq -R -s 'split("\n") | map(select(length > 0))' > "$QSCAN_FILE"
fi
# Re-enable network registration
echo "AT+COPS=0" | atinout - /dev/smd7 -
sleep 2
# Clean up temporary file
rm -f "$QSCAN_OUT"
# Remove pause file to resume logging
rm -f "$PAUSE_FILE"
# Return QSCAN results as JSON
if [ -f "$QSCAN_FILE" ]; then
printf '{"status":"success","data":%s}\n' "$(cat "$QSCAN_FILE")"
else
printf '{"status":"error","message":"No scan results available"}\n'
fi
}
# Function to log signal metric # Function to log signal metric
log_signal_metric() { log_signal_metric() {
[ -f "$PAUSE_FILE" ] && return
local COMMAND="$1" local COMMAND="$1"
local FILENAME="$2" local FILENAME="$2"
local LOGFILE="$LOGDIR/$FILENAME" local LOGFILE="$LOGDIR/$FILENAME"
@@ -28,35 +76,29 @@ log_signal_metric() {
# Get current timestamp # Get current timestamp
TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S") TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")
# Add debug logging
logger -t signal_metrics "Running command: $COMMAND"
# Run the AT command and capture its output, then clean it # Run the AT command and capture its output, then clean it
SIGNAL_OUTPUT=$(echo "$COMMAND" | atinout - /dev/smd7 - | clean_atinout_output) SIGNAL_OUTPUT=$(echo "$COMMAND" | atinout - /dev/smd7 - | clean_atinout_output)
# Log the raw output for debugging
logger -t signal_metrics "Raw output for $COMMAND: $SIGNAL_OUTPUT"
# Ensure the file exists and is a valid JSON array # Ensure the file exists and is a valid JSON array
if [ ! -s "$LOGFILE" ]; then [ ! -s "$LOGFILE" ] && echo "[]" > "$LOGFILE"
echo "[]" > "$LOGFILE"
fi
# Prepare new JSON entry # Use jq to update the JSON file
ESCAPED_TIMESTAMP=$(printf '%s' "$TIMESTAMP" | sed 's/"/\\"/g') jq --arg dt "$TIMESTAMP" \
ESCAPED_OUTPUT=$(printf '%s' "$SIGNAL_OUTPUT" | sed 's/"/\\"/g') --arg out "$SIGNAL_OUTPUT" \
'. + [{"datetime": $dt, "output": $out}] | .[-'"$MAX_ENTRIES"':]' \
# Use jq with a more robust approach "$LOGFILE" > "${LOGFILE}.tmp" && mv "${LOGFILE}.tmp" "$LOGFILE"
jq --arg datetime "$ESCAPED_TIMESTAMP" \
--arg output "$ESCAPED_OUTPUT" \
'
# Ensure the input is always an array
if type == "array" then .
else []
end |
# Add new entry
. + [{"datetime": $datetime, "output": $output}] |
# Trim to max entries
.[-'"$MAX_ENTRIES"':]
' "$LOGFILE" > "${LOGFILE}.tmp" && mv "${LOGFILE}.tmp" "$LOGFILE"
} }
# Function to log data usage # Function to log data usage
log_data_usage() { log_data_usage() {
[ -f "$PAUSE_FILE" ] && return
local LOGFILE="$LOGDIR/data_usage.json" local LOGFILE="$LOGDIR/data_usage.json"
# Ensure log directory exists # Ensure log directory exists
@@ -65,51 +107,72 @@ log_data_usage() {
# Get current timestamp # Get current timestamp
TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S") TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")
# Run the AT command and capture its output, then clean it # Run the AT command and capture its output
DATA_OUTPUT=$(echo "AT+QGDCNT?;+QGDNRCNT?" | atinout - /dev/smd7 - | clean_atinout_output) DATA_OUTPUT=$(echo "AT+QGDCNT?;+QGDNRCNT?" | atinout - /dev/smd7 - | clean_atinout_output)
# Ensure the file exists and is a valid JSON array # Ensure the file exists and is a valid JSON array
if [ ! -s "$LOGFILE" ]; then [ ! -s "$LOGFILE" ] && echo "[]" > "$LOGFILE"
echo "[]" > "$LOGFILE"
# Use jq to update the JSON file
jq --arg dt "$TIMESTAMP" \
--arg out "$DATA_OUTPUT" \
'. + [{"datetime": $dt, "output": $out}] | .[-'"$MAX_ENTRIES"':]' \
"$LOGFILE" > "${LOGFILE}.tmp" && mv "${LOGFILE}.tmp" "$LOGFILE"
}
# Main CGI request handler
handle_cgi_request() {
# Get query string from REQUEST_URI or QUERY_STRING
local QUERY=""
if [ -n "$REQUEST_URI" ]; then
QUERY=$(echo "$REQUEST_URI" | grep -o '[?&]request=[^&]*' | cut -d= -f2)
elif [ -n "$QUERY_STRING" ]; then
QUERY=$(echo "$QUERY_STRING" | grep -o 'request=[^&]*' | cut -d= -f2)
fi fi
# Prepare new JSON entry case "$QUERY" in
ESCAPED_TIMESTAMP=$(printf '%s' "$TIMESTAMP" | sed 's/"/\\"/g') "cellScan")
ESCAPED_OUTPUT=$(printf '%s' "$DATA_OUTPUT" | sed 's/"/\\"/g') perform_cell_scan
;;
# Use jq with a more robust approach *)
jq --arg datetime "$ESCAPED_TIMESTAMP" \ printf "Content-Type: application/json\n\n"
--arg output "$ESCAPED_OUTPUT" \ printf '{"status":"error","message":"Invalid request"}\n'
' ;;
# Ensure the input is always an array esac
if type == "array" then .
else []
end |
# Add new entry
. + [{"datetime": $datetime, "output": $output}] |
# Trim to max entries
.[-'"$MAX_ENTRIES"':]
' "$LOGFILE" > "${LOGFILE}.tmp" && mv "${LOGFILE}.tmp" "$LOGFILE"
} }
# Trap to handle script termination gracefully # Function to start continuous logging
cleanup() { start_continuous_logging() {
echo "Stopping signal logging..." # Check if another instance is running
exit 0 if [ -f "$LOCK_FILE" ]; then
} logger -t signal_metrics "Another instance is already running"
trap cleanup SIGINT SIGTERM exit 1
fi
# Create lock file
touch "$LOCK_FILE"
# Cleanup on exit
trap 'rm -f "$LOCK_FILE" "$PAUSE_FILE"; exit 0' INT TERM
# Log start to system log
logger -t signal_metrics "Starting continuous signal metrics logging"
# Continuous logging loop # Continuous logging loop
echo "Starting continuous signal metrics logging (Press Ctrl+C to stop)..."
while true; do while true; do
# Log RSRP if [ ! -f "$PAUSE_FILE" ]; then
log_signal_metric "AT+QRSRP" "rsrp.json" log_signal_metric "AT+QRSRP" "rsrp.json"
# Log RSRQ
log_signal_metric "AT+QRSRQ" "rsrq.json" log_signal_metric "AT+QRSRQ" "rsrq.json"
# Log SINR
log_signal_metric "AT+QSINR" "sinr.json" log_signal_metric "AT+QSINR" "sinr.json"
# Log data usage after signal stats
log_data_usage log_data_usage
# Wait for the specified interval fi
sleep "$INTERVAL" sleep "$INTERVAL"
done done
}
# Check if script is being run as CGI or directly
if [ -n "$REQUEST_URI" ] || [ -n "$QUERY_STRING" ]; then
handle_cgi_request
else
start_continuous_logging
fi