Added files
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+7
File diff suppressed because one or more lines are too long
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
/*! jQuery Timepicker Addon - v1.6.3 - 2016-04-20
|
||||
* http://trentrichardson.com/examples/timepicker
|
||||
* Copyright (c) 2016 Trent Richardson; Licensed MIT */
|
||||
|
||||
.ui-timepicker-div .ui-widget-header{margin-bottom:8px}.ui-timepicker-div dl{text-align:left}.ui-timepicker-div dl dt{float:left;clear:left;padding:0 0 0 5px}.ui-timepicker-div dl dd{margin:0 10px 10px 40%}.ui-timepicker-div td{font-size:90%}.ui-tpicker-grid-label{background:0 0;border:0;margin:0;padding:0}.ui-timepicker-div .ui_tpicker_unit_hide{display:none}.ui-timepicker-div .ui_tpicker_time .ui_tpicker_time_input{background:0 0;color:inherit;border:0;outline:0;border-bottom:solid 1px #555;width:95%}.ui-timepicker-div .ui_tpicker_time .ui_tpicker_time_input:focus{border-bottom-color:#aaa}.ui-timepicker-rtl{direction:rtl}.ui-timepicker-rtl dl{text-align:right;padding:0 5px 0 0}.ui-timepicker-rtl dl dt{float:right;clear:right}.ui-timepicker-rtl dl dd{margin:0 40% 10px 10px}.ui-timepicker-div.ui-timepicker-oneLine{padding-right:2px}.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_time,.ui-timepicker-div.ui-timepicker-oneLine dt{display:none}.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_time_label{display:block;padding-top:2px}.ui-timepicker-div.ui-timepicker-oneLine dl{text-align:right}.ui-timepicker-div.ui-timepicker-oneLine dl dd,.ui-timepicker-div.ui-timepicker-oneLine dl dd>div{display:inline-block;margin:0}.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_minute:before,.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_second:before{content:':';display:inline-block}.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_millisec:before,.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_microsec:before{content:'.';display:inline-block}.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_unit_hide,.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_unit_hide:before{display:none}
|
||||
Vendored
+5
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+18706
File diff suppressed because it is too large
Load Diff
+1311
File diff suppressed because it is too large
Load Diff
Executable
+53
@@ -0,0 +1,53 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -x
|
||||
|
||||
# Function to get the default gateway IP address
|
||||
get_gateway_ip() {
|
||||
gateway_ip=$(ip route | awk '/default/ {print $3}')
|
||||
echo "$gateway_ip"
|
||||
}
|
||||
|
||||
# Assign the gateway IP address automatically
|
||||
gateway_ip=$(get_gateway_ip)
|
||||
|
||||
# Array of IP addresses to ping, including the gateway IP
|
||||
ip_addresses=("9.9.9.9" "8.8.8.8" "1.1.1.1")
|
||||
if [ -n "$gateway_ip" ]; then
|
||||
ip_addresses+=("$gateway_ip")
|
||||
fi
|
||||
|
||||
# CSV file to store ping results
|
||||
csv_file="ping_data.csv"
|
||||
|
||||
# Check if the CSV file already exists
|
||||
if [ ! -e "$csv_file" ]; then
|
||||
# Create the CSV file with a header including a timestamp column
|
||||
echo "Timestamp,IP Address,Status" > "$csv_file"
|
||||
fi
|
||||
|
||||
# Function to ping an IP address and log the result to the CSV file
|
||||
ping_ip() {
|
||||
ip="$1"
|
||||
result=$(ping -c 4 -i 0.2 -q "$ip" | tail -1)
|
||||
if [ $? -eq 0 ]; then
|
||||
if [ "$ip" == "$gateway_ip" ]; then
|
||||
status="1" # Gateway IP is "1" for successful pings
|
||||
else
|
||||
status="2" # Other IP addresses are "2" for successful pings
|
||||
fi
|
||||
else
|
||||
status="0" # Network is not reachable
|
||||
fi
|
||||
timestamp=$(date +"%Y-%m-%d %H:%M:%S")
|
||||
echo "$timestamp,$ip,$status" >> "$csv_file"
|
||||
}
|
||||
|
||||
# Loop through the IP addresses and ping them periodically
|
||||
while true; do
|
||||
for ip in "${ip_addresses[@]}"; do
|
||||
ping_ip "$ip"
|
||||
done
|
||||
sleep 60 # Ping every 60 seconds, adjust as needed
|
||||
done
|
||||
|
||||
Executable
+182
@@ -0,0 +1,182 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Ping Results</title>
|
||||
|
||||
<script src="/cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.min.js"></script>
|
||||
<script src="/cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||
<link rel="stylesheet" href="/code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
|
||||
<script src="/code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
|
||||
<!-- Include jQuery UI Timepicker addon -->
|
||||
<link rel="stylesheet" href="/cdnjs.cloudflare.com/ajax/libs/jquery-ui-timepicker-addon/1.6.3/jquery-ui-timepicker-addon.min.css">
|
||||
<script src="/cdnjs.cloudflare.com/ajax/libs/jquery-ui-timepicker-addon/1.6.3/jquery-ui-timepicker-addon.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Ping Results</h1>
|
||||
<div>
|
||||
Start Date & Time: <input type="text" id="startDate">
|
||||
End Date & Time: <input type="text" id="endDate">
|
||||
<button id="applyFilterButton">Apply Filter</button>
|
||||
</div>
|
||||
<canvas id="pingChart" width="800" height="400"></canvas>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
// Initialize date pickers with time picker addon
|
||||
$("#startDate").datetimepicker({
|
||||
dateFormat: "yy-mm-dd",
|
||||
timeFormat: "HH:mm:ss"
|
||||
});
|
||||
$("#endDate").datetimepicker({
|
||||
dateFormat: "yy-mm-dd",
|
||||
timeFormat: "HH:mm:ss"
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: "ping_data.csv", // Replace with the path to your CSV file
|
||||
dataType: "text",
|
||||
success: function (data) {
|
||||
processData(data);
|
||||
}
|
||||
});
|
||||
|
||||
// Attach click event handler to Apply Filter button
|
||||
$("#applyFilterButton").click(function () {
|
||||
applyDateFilter();
|
||||
});
|
||||
});
|
||||
|
||||
let labels = [];
|
||||
const datasets = {}; // Store datasets for each IP
|
||||
let chart = null; // Declare a variable to store the Chart instance
|
||||
|
||||
function processData(csvData) {
|
||||
const rows = csvData.split('\n');
|
||||
|
||||
for (let i = 1; i < rows.length; i++) {
|
||||
const columns = rows[i].split(',');
|
||||
const timestampStr = columns[0]; // Timestamp in "YYYY-MM-DD HH:MM:SS" format
|
||||
const ip = columns[1];
|
||||
const status = columns[2];
|
||||
|
||||
if (!datasets[ip]) {
|
||||
// Create a new dataset for each IP address
|
||||
datasets[ip] = {
|
||||
label: ip, // Use IP address as the label
|
||||
data: [],
|
||||
borderColor: getRandomColor(), // Function to generate random colors
|
||||
borderWidth: 1,
|
||||
fill: false
|
||||
};
|
||||
}
|
||||
|
||||
const value = status === '1' ? 1 : 2; // Display 1 for "Success (1)" and 2 for "Success (2)"
|
||||
const formattedTimestamp = formatTimestamp(timestampStr); // Format timestamp
|
||||
|
||||
labels.push(formattedTimestamp);
|
||||
datasets[ip].data.push(value);
|
||||
}
|
||||
|
||||
createChart(labels, Object.values(datasets));
|
||||
}
|
||||
|
||||
function formatTimestamp(timestampStr) {
|
||||
const timestamp = new Date(timestampStr);
|
||||
const year = timestamp.getFullYear();
|
||||
const month = (timestamp.getMonth() + 1).toString().padStart(2, '0');
|
||||
const day = timestamp.getDate().toString().padStart(2, '0');
|
||||
const hours = timestamp.getHours().toString().padStart(2, '0');
|
||||
const minutes = timestamp.getMinutes().toString().padStart(2, '0');
|
||||
const seconds = timestamp.getSeconds().toString().padStart(2, '0');
|
||||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||
}
|
||||
|
||||
function applyDateFilter() {
|
||||
// Get selected start and end date/time
|
||||
const startDate = $("#startDate").datetimepicker("getDate");
|
||||
const endDate = $("#endDate").datetimepicker("getDate");
|
||||
|
||||
// Filter data based on selected date range
|
||||
const filteredLabels = [];
|
||||
const filteredDatasets = {};
|
||||
|
||||
labels.forEach((label, index) => {
|
||||
const timestamp = new Date(label);
|
||||
|
||||
if (timestamp >= startDate && timestamp <= endDate) {
|
||||
filteredLabels.push(label);
|
||||
|
||||
// Copy the datasets for IPs within the selected date range
|
||||
Object.keys(datasets).forEach((ip) => {
|
||||
if (!filteredDatasets[ip]) {
|
||||
filteredDatasets[ip] = { ...datasets[ip] };
|
||||
filteredDatasets[ip].data = [];
|
||||
}
|
||||
|
||||
filteredDatasets[ip].data.push(datasets[ip].data[index]);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Update the chart with filtered data
|
||||
updateChart(filteredLabels, Object.values(filteredDatasets));
|
||||
}
|
||||
|
||||
function createChart(labels, datasets) {
|
||||
const ctx = document.getElementById('pingChart').getContext('2d');
|
||||
chart = new Chart(ctx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: labels,
|
||||
datasets: datasets
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
x: {
|
||||
type: 'category', // Use category scale for date and time labels
|
||||
position: 'bottom', // Position x-axis at the bottom
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Timestamp (Date + Time)'
|
||||
}
|
||||
},
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Ping Status'
|
||||
},
|
||||
ticks: {
|
||||
max: 2,
|
||||
min: 1,
|
||||
stepSize: 1,
|
||||
callback: function (value, index, values) {
|
||||
return value === 1 ? 'Gateway (1)' : value === 2 ? 'DNS Servers (2)' : '';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function updateChart(labels, datasets) {
|
||||
if (chart) {
|
||||
chart.destroy();
|
||||
}
|
||||
createChart(labels, datasets);
|
||||
}
|
||||
|
||||
function getRandomColor() {
|
||||
const letters = '0123456789ABCDEF';
|
||||
let color = '#';
|
||||
for (let i = 0; i < 6; i++) {
|
||||
color += letters[Math.floor(Math.random() * 16)];
|
||||
}
|
||||
return color;
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user