Last active
June 9, 2025 10:01
-
-
Save akunzai/0e14f68d810da2bc01930a063fe1a5c7 to your computer and use it in GitHub Desktop.
Revisions
-
akunzai revised this gist
Jun 9, 2025 . 1 changed file with 0 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -46,7 +46,6 @@ FIELDS=( "attributes.MQ__Exchange" "attributes.MQ__MessageId" "attributes.MQ__RoutingKey" "instrumentation_scope.name" ) -
akunzai created this gist
Jun 9, 2025 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,156 @@ #!/bin/bash # Script to convert Loki logs JSON to CSV format # Usage: ./loki_json_to_csv.sh input.json output.csv # Check if jq is installed if ! command -v jq &> /dev/null; then echo "Error: jq is not installed. Please install it first." echo "On macOS: brew install jq" echo "On Ubuntu/Debian: sudo apt-get install jq" exit 1 fi # Check arguments if [ "$#" -ne 2 ]; then echo "Usage: $0 <input.json> <output.csv>" exit 1 fi INPUT_FILE="$1" OUTPUT_FILE="$2" # Check if input file exists if [ ! -f "$INPUT_FILE" ]; then echo "Error: Input file '$INPUT_FILE' not found." exit 1 fi # Define the fields we want to extract # You can modify this list to include/exclude fields as needed FIELDS=( "timestamp" "body" "severity" "traceid" "spanid" "attributes.Application" "attributes.VerificationEventId" "attributes.ChildEventId" "attributes.ChildEventType" "attributes.State" "attributes.Source" "attributes.FinalState" "attributes.NewState" "attributes.NewSource" "attributes.MQ__Exchange" "attributes.MQ__MessageId" "attributes.MQ__RoutingKey" "resources.service.name" "instrumentation_scope.name" ) # Create CSV header HEADER="" for field in "${FIELDS[@]}"; do if [ -z "$HEADER" ]; then HEADER="\"$field\"" else HEADER="$HEADER,\"$field\"" fi done echo "$HEADER" > "$OUTPUT_FILE" # Function to safely extract JSON value and escape for CSV extract_field() { local json="$1" local field="$2" # Extract the value using jq value=$(echo "$json" | jq -r ".$field // empty" 2>/dev/null) # If value contains quotes, double them for CSV value="${value//\"/\"\"}" # If value contains comma, newline, or quote, wrap in quotes if [[ "$value" =~ [,\"\n] ]]; then echo "\"$value\"" else echo "$value" fi } # Function to convert nanosecond timestamp to ISO 8601 format convert_timestamp() { local timestamp_ns="$1" # Convert nanoseconds to seconds and nanoseconds remainder local seconds=$((timestamp_ns / 1000000000)) local nanoseconds=$((timestamp_ns % 1000000000)) # Format the date using the date command # On macOS, use -r flag for seconds since epoch if [[ "$OSTYPE" == "darwin"* ]]; then local date_str=$(date -r "$seconds" -u +"%Y-%m-%dT%H:%M:%S") else # On Linux, use -d flag local date_str=$(date -d "@$seconds" -u +"%Y-%m-%dT%H:%M:%S") fi # Add nanoseconds and UTC timezone printf "%s.%09dZ" "$date_str" "$nanoseconds" } # Process each JSON object echo "Processing JSON file..." line_count=0 # Read the JSON array and process each object jq -c '.[]' "$INPUT_FILE" 2>/dev/null | while IFS= read -r json_obj; do line_count=$((line_count + 1)) # Parse the line field which contains the actual log data line_data=$(echo "$json_obj" | jq -r '.line' 2>/dev/null) if [ -n "$line_data" ]; then # Parse the nested JSON in the line field parsed_data=$(echo "$line_data" | jq '.' 2>/dev/null) if [ $? -eq 0 ]; then # Build CSV row ROW="" # First add the timestamp from the outer object timestamp=$(echo "$json_obj" | jq -r '.timestamp // empty' 2>/dev/null) if [ -n "$timestamp" ]; then iso_timestamp=$(convert_timestamp "$timestamp") ROW="$iso_timestamp" else ROW="" fi # Then add fields from the parsed line data for field in "${FIELDS[@]:1}"; do value=$(extract_field "$parsed_data" "$field") ROW="$ROW,$value" done echo "$ROW" >> "$OUTPUT_FILE" else echo "Warning: Failed to parse JSON in line $line_count" fi fi # Show progress every 100 lines if [ $((line_count % 100)) -eq 0 ]; then echo "Processed $line_count lines..." fi done echo "Conversion complete! Processed $line_count lines." echo "Output saved to: $OUTPUT_FILE" # If you want to see the first few rows of the output echo -e "\nFirst 5 rows of the CSV:" head -n 6 "$OUTPUT_FILE"