bashjq

Check the amount of traffic on server, and then detects if the traffic has been decreased dramatically or not


I've written a script in the bash to connect to servers via SSH and check their traffic. If the traffic significantly decreases, the script will send an email to the address specified in the program.

#!/bin/bash  

# Variables  
server_ip="IP address"   # Replace with your server's IP address  
username="ubuntu"   # Replace with your SSH username  

# Function to fetch and calculate traffic data  
calculate_traffic() {
    echo "Connecting to $server_ip to fetch traffic data..."  

    # Running vnstat command and saving output  
    output=$(ssh -o StrictHostKeyChecking=no "${username}@${server_ip}" vnstat -d --json)
    # echo "$output"
    if [[ $? -ne 0 ]]; then
        echo "Failed to connect to $server_ip or vnstat is not installed."  
        return
    fi

    # Extract daily traffic data  
    # traffic_data=($(echo "$output" | jq -r '.interfaces[0].traffic | map(.day.rx + .day.tx) | .[]'))     
    traffic_data=($(echo "$output" | jq -r '.interfaces[0].day[] | "(.rx + .tx) bytes"'))
    echo "$traffic_data"
    #traffic_data=($(echo "$output" | jq '.interfaces[].day[] | {date: .date, rx: .rx, tx: .tx}' data.json))
    # Validate that we have enough data  
    if [[ ${#traffic_data[@]} -lt 10 ]]; then
        echo "Not enough data available for the past 10 days."  
        return
    fi

    # Calculate new_traffic (average of the last 5 days)  
    new_traffic=0
    for i in {0..4}; do
        new_traffic=$(echo "$new_traffic + ${traffic_data[$i]}" | bc)
    done
    new_traffic=$(echo "$new_traffic / 5" | bc -l)

    # Calculate old_traffic (average of days 6-10)  
    old_traffic=0
    for i in {5..9}; do
     old_traffic=$(echo "$old_traffic + ${traffic_data[$i]}" | bc)
    done
    old_traffic=$(echo "$old_traffic / 5" | bc -l)

    echo "Average traffic in the last 5 days: $new_traffic MB"  
    echo "Average traffic in the 5 to 10 days ago: $old_traffic MB"  

    # Optionally, compare or take action based on traffic  
}

# Run the function to calculate traffic 

The SSH connection works fine, but the following code leads to an error.

jq: error (at <stdin>:1): Cannot iterate over null (null)
Not enough data available for the past 10 days.

The output is not empty. This is the result after running vnstat -d on the server.

and this is the output when I put the line

 echo "$traffic_data"
 {"vnstatversion":"2.12","jsonversion":"2","interfaces":[{"name":"eth0","alias":"","created":{"date":{"year":2024,"month":10,"day":13},"timestamp":1728801752},"updated":{"date":{"year":2024,"month":10,"day":13},"time":{"hour":9,"minute":35},"timestamp":1728812100},"traffic":{"total":{"rx":1301247,"tx":1443456},"fiveminute":[{"id":2,"date":{"year":2024,"month":10,"day":13},"time":{"hour":6,"minute":40},"timestamp":1728801600,"rx":35241,"tx":53433},{"id":1,"date":{"year":2024,"month":10,"day":13},"time":{"hour":6,"minute":45},"timestamp":1728801900,"rx":5604,"tx":4450},{"id":3,"date":{"year":2024,"month":10,"day":13},"time":{"hour":6,"minute":50},"timestamp":1728802200,"rx":5737,"tx":4531},{"id":4,"date":{"year":2024,"month":10,"day":13},"time":{"hour":6,"minute":55},"timestamp":1728802500,"rx":44158,"tx":45048},{"id":5,"date":{"year":2024,"month":10,"day":13},"time":{"hour":7,"minute":0},"timestamp":1728802800,"rx":8273,"tx":7747},{"id":6,"date":{"year":2024,"month":10,"day":13},"time":{"hour":7,"minute":5},"timestamp":1728803100,"rx":5234,"tx":4260},{"id":7,"date":{"year":2024,"month":10,"day":13},"time":{"hour":7,"minute":10},"timestamp":1728803400,"rx":10659,"tx":8577},{"id":8,"date":{"year":2024,"month":10,"day":13},"time":{"hour":7,"minute":15},"timestamp":1728803700,"rx":63903,"tx":55183},{"id":9,"date":{"year":2024,"month":10,"day":13},"time":{"hour":7,"minute":20},"timestamp":1728804000,"rx":67698,"tx":61890},{"id":10,"date":{"year":2024,"month":10,"day":13},"time":{"hour":7,"minute":25},"timestamp":1728804300,"rx":9286,"tx":8401},{"id":11,"date":{"year":2024,"month":10,"day":13},"time":{"hour":7,"minute":30},"timestamp":1728804600,"rx":5533,"tx":4165},{"id":12,"date":{"year":2024,"month":10,"day":13},"time":{"hour":7,"minute":35},"timestamp":1728804900,"rx":7187,"tx":6073},{"id":13,"date":{"year":2024,"month":10,"day":13},"time":{"hour":7,"minute":40},"timestamp":1728805200,"rx":10659,"tx":10097},{"id":14,"date":{"year":2024,"month":10,"day":13},"time":{"hour":7,"minute":45},"timestamp":1728805500,"rx":8103,"tx":7595},{"id":15,"date":{"year":2024,"month":10,"day":13},"time":{"hour":7,"minute":50},"timestamp":1728805800,"rx":10720,"tx":12586},{"id":16,"date":{"year":2024,"month":10,"day":13},"time":{"hour":7,"minute":55},"timestamp":1728806100,"rx":4151,"tx":3119},{"id":17,"date":{"year":2024,"month":10,"day":13},"time":{"hour":8,"minute":0},"timestamp":1728806400,"rx":4650,"tx":4004},{"id":18,"date":{"year":2024,"month":10,"day":13},"time":{"hour":8,"minute":5},"timestamp":1728806700,"rx":7248,"tx":6828},{"id":19,"date":{"year":2024,"month":10,"day":13},"time":{"hour":8,"minute":10},"timestamp":1728807000,"rx":9530,"tx":7368},{"id":20,"date":{"year":2024,"month":10,"day":13},"time":{"hour":8,"minute":15},"timestamp":1728807300,"rx":6675,"tx":6095},{"id":21,"date":{"year":2024,"month":10,"day":13},"time":{"hour":8,"minute":20},"timestamp":1728807600,"rx":4623,"tx":3447},{"id":22,"date":{"year":2024,"month":10,"day":13},"time":{"hour":8,"minute":25},"timestamp":1728807900,"rx":10352,"tx":9920},{"id":23,"date":{"year":2024,"month":10,"day":13},"time":{"hour":8,"minute":30},"timestamp":1728808200,"rx":8638,"tx":7432},{"id":24,"date":{"year":2024,"month":10,"day":13},"time":{"hour":8,"minute":35},"timestamp":1728808500,"rx":6395,"tx":6085},{"id":25,"date":{"year":2024,"month":10,"day":13},"time":{"hour":8,"minute":40},"timestamp":1728808800,"rx":100639,"tx":118300},{"id":26,"date":{"year":2024,"month":10,"day":13},"time":{"hour":8,"minute":45},"timestamp":1728809100,"rx":100824,"tx":133866},{"id":27,"date":{"year":2024,"month":10,"day":13},"time":{"hour":8,"minute":50},"timestamp":1728809400,"rx":123621,"tx":162497},{"id":28,"date":{"year":2024,"month":10,"day":13},"time":{"hour":8,"minute":55},"timestamp":1728809700,"rx":105350,"tx":127156},{"id":29,"date":{"year":2024,"month":10,"day":13},"time":{"hour":9,"minute":0},"timestamp":1728810000,"rx":53538,"tx":58412},{"id":30,"date":{"year":2024,"month":10,"day":13},"time":{"hour":9,"minute":5},"timestamp":1728810300,"rx":87424,"tx":101574},{"id":31,"date":{"year":2024,"month":10,"day":13},"time":{"hour":9,"minute":10},"timestamp":1728810600,"rx":58102,"tx":61288},{"id":32,"date":{"year":2024,"month":10,"day":13},"time":{"hour":9,"minute":15},"timestamp":1728810900,"rx":53089,"tx":58081},{"id":33,"date":{"year":2024,"month":10,"day":13},"time":{"hour":9,"minute":20},"timestamp":1728811200,"rx":82041,"tx":83978},{"id":34,"date":{"year":2024,"month":10,"day":13},"time":{"hour":9,"minute":25},"timestamp":1728811500,"rx":114346,"tx":120850},{"id":35,"date":{"year":2024,"month":10,"day":13},"time":{"hour":9,"minute":30},"timestamp":1728811800,"rx":62016,"tx":69120}],"hour":[{"id":1,"date":{"year":2024,"month":10,"day":13},"time":{"hour":6,"minute":0},"timestamp":1728799200,"rx":90740,"tx":107462},{"id":2,"date":{"year":2024,"month":10,"day":13},"time":{"hour":7,"minute":0},"timestamp":1728802800,"rx":211406,"tx":189693},{"id":3,"date":{"year":2024,"month":10,"day":13},"time":{"hour":8,"minute":0},"timestamp":1728806400,"rx":488545,"tx":592998},{"id":4,"date":{"year":2024,"month":10,"day":13},"time":{"hour":9,"minute":0},"timestamp":1728810000,"rx":510556,"tx":553303}],"day":[{"id":1,"date":{"year":2024,"month":10,"day":13},"timestamp":1728777600,"rx":1301247,"tx":1443456}],"month":[{"id":1,"date":{"year":2024,"month":10},"timestamp":1727740800,"rx":1301247,"tx":1443456}],"year":[{"id":1,"date":{"year":2024},"timestamp":1704067200,"rx":1301247,"tx":1443456}],"top":[{"id":1,"date":{"year":2024,"month":10,"day":13},"timestamp":1728777600,"rx":1301247,"tx":1443456}]}}]}

Solution

  • It is because the element interfaces in the output of vnstat -d --json does not have a day element. The following is a sample truncated output of this command. There are day elements inside the JSON, but none of them are direct children of interfaces. The way you have called it requires day to be a direct element of interfaces[0].

    You might have copied the code from somewhere else or generated it by AI which has used an older version of vnstat or maybe the AI was hallucinating.

    By the way, you could have dug deeper into it to find out that the output of (echo "$output" | jq -r --compact-output '.interfaces[0].day[]') is null.

    {                                                      
        "vnstatversion": "2.10",                           
        "jsonversion": "2",                                
        "interfaces": [                                    
            {                                              
                "name": "eth0",                            
                "alias": "",                               
                "created": {                               
                    "date": {                              
                        "year": 2024,                      
                        "month": 4,                        
                        "day": 28                          
                    },                                     
                    "timestamp": 1714303206                
                },                                         
                "updated": {                               
                    "date": {                              
                        "year": 2024,                      
                        "month": 10,                       
                        "day": 15                          
                    },                                     
                    "time": {                              
                        "hour": 4,                         
                        "minute": 20                       
                    },                                     
                    "timestamp": 1728966000                
                },                                         
                "traffic": {                               
                    "total": {                             
                        "rx": 721795234718,                
                        "tx": 720659482363                 
                    },                                     
                    "fiveminute": [                        
                        {                                  
                            "id": 96594,                   
                            "date": {                      
                                "year": 2024,              
                                "month": 10,               
                                "day": 13                  
                            },                             
                            "time": {                      
                                "hour": 4,                 
                                "minute": 0                
                            },                             
                            "timestamp": 1728792000,       
                            "rx": 435591,                  
                            "tx": 463409                   
                        },                                 
                        {                                  
                            "id": 96596,                   
                            "date": {                      
                                "year": 2024,              
                                "month": 10,               
                                "day": 13                  
                            },                             
                            "time": {                      
                                "hour": 4,                 
                                "minute": 5                
                            },                             
                            "timestamp": 1728792300,       
                            "rx": 695570,                  
                            "tx": 912465                   
                        },                                 
                        {                                  
                            "id": 96598,