mirror of
https://github.com/unraid/webgui.git
synced 2026-04-22 18:19:14 -05:00
Use timeout in command execution of diagnostics
This commit is contained in:
@@ -22,6 +22,11 @@ $var = file_exists("$get/var.ini") ? parse_ini_file("$get/var.ini") : [];
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
$folders = ['/boot','/boot/config','/boot/config/plugins','/boot/extra','/boot/syslinux','/var/log','/var/log/plugins','/var/log/packages','/tmp'];
|
||||
|
||||
function exert($cmd, &$save=null) {
|
||||
// execute command with timeout of 30s
|
||||
exec("timeout -s9 30 $cmd", $save);
|
||||
}
|
||||
|
||||
function anonymize($text,$select) {
|
||||
global $all;
|
||||
if ($all) return $text;
|
||||
@@ -51,7 +56,7 @@ function anonymize($text,$select) {
|
||||
if ($cli) {
|
||||
// script is called from CLI
|
||||
echo "Starting diagnostics collection... ";
|
||||
exec("mkdir -p /boot/logs");
|
||||
exert("mkdir -p /boot/logs");
|
||||
$server = isset($var['NAME']) ? str_replace(' ','_',strtolower($var['NAME'])) : 'tower';
|
||||
$date = date('Ymd-Hi');
|
||||
$diag = "$server-diagnostics-$date";
|
||||
@@ -63,9 +68,9 @@ if ($cli) {
|
||||
$date = "{$split[2]}-{$split[3]}";
|
||||
}
|
||||
// create folder structure
|
||||
exec("mkdir -p ".escapeshellarg("/$diag/system")." ".escapeshellarg("/$diag/config")." ".escapeshellarg("/$diag/logs")." ".escapeshellarg("/$diag/shares")." ".escapeshellarg("/$diag/smart")." ".escapeshellarg("/$diag/qemu"));
|
||||
exert("mkdir -p ".escapeshellarg("/$diag/system")." ".escapeshellarg("/$diag/config")." ".escapeshellarg("/$diag/logs")." ".escapeshellarg("/$diag/shares")." ".escapeshellarg("/$diag/smart")." ".escapeshellarg("/$diag/qemu"));
|
||||
// get utilization of running processes
|
||||
exec("top -bn1 -o%CPU 2>/dev/null|todos >".escapeshellarg("/$diag/system/top.txt"));
|
||||
exert("top -bn1 -o%CPU 2>/dev/null|todos >".escapeshellarg("/$diag/system/top.txt"));
|
||||
// make unRAID version reference
|
||||
$unraid = parse_ini_file('/etc/unraid-version');
|
||||
file_put_contents("/$diag/unRAID-".$unraid['version'].".txt",$unraid['version']);
|
||||
@@ -76,7 +81,7 @@ foreach (glob("$get/*.ini") as $file) {
|
||||
if ($all || $ini != "users") file_put_contents("/$diag/system/vars.txt",preg_replace(["/\n/","/^Array/"],["\r\n",$ini],anonymize(print_r(parse_ini_file($file,true),true),1)),FILE_APPEND);
|
||||
}
|
||||
// Create loads.txt
|
||||
$cpuload = exec("uptime")." Cores: ".exec("nproc")."\r\n".file_get_contents("/var/local/emhttp/cpuload.ini")."\r\n";
|
||||
$cpuload = exert("uptime")." Cores: ".exert("nproc")."\r\n".file_get_contents("/var/local/emhttp/cpuload.ini")."\r\n";
|
||||
$diskload = file("/var/local/emhttp/diskload.ini");
|
||||
$disks = parse_ini_file("/var/local/emhttp/disks.ini",true);
|
||||
foreach ( $diskload as $loadLine ) {
|
||||
@@ -90,38 +95,38 @@ foreach ( $diskload as $loadLine ) {
|
||||
}
|
||||
file_put_contents("/$diag/system/loads.txt",$cpuload.implode("\r\n",$loadTxt));
|
||||
// individual commands execution (suppress errors)
|
||||
exec("lscpu 2>/dev/null|todos >".escapeshellarg("/$diag/system/lscpu.txt"));
|
||||
exec("lsscsi -vgl 2>/dev/null|todos >".escapeshellarg("/$diag/system/lsscsi.txt"));
|
||||
exec("lspci -knn 2>/dev/null|todos >".escapeshellarg("/$diag/system/lspci.txt"));
|
||||
exec("lsusb 2>/dev/null|todos >".escapeshellarg("/$diag/system/lsusb.txt"));
|
||||
exec("free -mth 2>/dev/null|todos >".escapeshellarg("/$diag/system/memory.txt"));
|
||||
exec("ps -auxf --sort=-pcpu 2>/dev/null|todos >".escapeshellarg("/$diag/system/ps.txt"));
|
||||
exec("lsof -Pni 2>/dev/null|todos >".escapeshellarg("/$diag/system/lsof.txt"));
|
||||
exec("lsmod|sort 2>/dev/null|todos >".escapeshellarg("/$diag/system/lsmod.txt"));
|
||||
exec("df -h 2>/dev/null|todos >".escapeshellarg("/$diag/system/df.txt"));
|
||||
exec("ifconfig -a -s 2>/dev/null|grep -Po '^(eth|bond)[0-9]+'", $ports);
|
||||
exec("dmidecode -qt2|awk -F: '/^\tManufacturer:/{m=\$2};/^\tProduct Name:/{p=\$2} END{print m\" -\"p}' 2>/dev/null|todos >".escapeshellarg("/$diag/system/motherboard.txt"));
|
||||
exec("dmidecode -qt0 2>/dev/null|todos >>".escapeshellarg("/$diag/system/motherboard.txt"));
|
||||
exert("lscpu 2>/dev/null|todos >".escapeshellarg("/$diag/system/lscpu.txt"));
|
||||
exert("lsscsi -vgl 2>/dev/null|todos >".escapeshellarg("/$diag/system/lsscsi.txt"));
|
||||
exert("lspci -knn 2>/dev/null|todos >".escapeshellarg("/$diag/system/lspci.txt"));
|
||||
exert("lsusb 2>/dev/null|todos >".escapeshellarg("/$diag/system/lsusb.txt"));
|
||||
exert("free -mth 2>/dev/null|todos >".escapeshellarg("/$diag/system/memory.txt"));
|
||||
exert("ps -auxf --sort=-pcpu 2>/dev/null|todos >".escapeshellarg("/$diag/system/ps.txt"));
|
||||
exert("lsof -Pni 2>/dev/null|todos >".escapeshellarg("/$diag/system/lsof.txt"));
|
||||
exert("lsmod|sort 2>/dev/null|todos >".escapeshellarg("/$diag/system/lsmod.txt"));
|
||||
exert("df -h 2>/dev/null|todos >".escapeshellarg("/$diag/system/df.txt"));
|
||||
exert("ifconfig -a -s 2>/dev/null|grep -Po '^(eth|bond)[0-9]+'", $ports);
|
||||
exert("dmidecode -qt2|awk -F: '/^\tManufacturer:/{m=\$2};/^\tProduct Name:/{p=\$2} END{print m\" -\"p}' 2>/dev/null|todos >".escapeshellarg("/$diag/system/motherboard.txt"));
|
||||
exert("dmidecode -qt0 2>/dev/null|todos >>".escapeshellarg("/$diag/system/motherboard.txt"));
|
||||
// create ethernet information information (suppress errors)
|
||||
foreach ($ports as $port) {
|
||||
exec("ethtool ".escapeshellarg($port)." 2>/dev/null|todos >>".escapeshellarg("/$diag/system/ethtool.txt"));
|
||||
exert("ethtool ".escapeshellarg($port)." 2>/dev/null|todos >>".escapeshellarg("/$diag/system/ethtool.txt"));
|
||||
file_put_contents("/$diag/system/ethtool.txt", "\r\n", FILE_APPEND);
|
||||
exec("ethtool -i ".escapeshellarg($port)." 2>/dev/null|todos >>".escapeshellarg("/$diag/system/ethtool.txt"));
|
||||
exert("ethtool -i ".escapeshellarg($port)." 2>/dev/null|todos >>".escapeshellarg("/$diag/system/ethtool.txt"));
|
||||
file_put_contents("/$diag/system/ethtool.txt", "--------------------------------\r\n", FILE_APPEND);
|
||||
}
|
||||
exec("ifconfig -a 2>/dev/null|todos >".escapeshellarg("/$diag/system/ifconfig.txt"));
|
||||
exert("ifconfig -a 2>/dev/null|todos >".escapeshellarg("/$diag/system/ifconfig.txt"));
|
||||
// create system information (suppress errors)
|
||||
exec("find /sys/kernel/iommu_groups/ -type l 2>/dev/null|todos >".escapeshellarg("/$diag/system/iommu_groups.txt"));
|
||||
exec("todos </proc/cmdline >".escapeshellarg("/$diag/system/cmdline.txt"));
|
||||
exert("find /sys/kernel/iommu_groups/ -type l 2>/dev/null|sort -V|todos >".escapeshellarg("/$diag/system/iommu_groups.txt"));
|
||||
exert("todos </proc/cmdline >".escapeshellarg("/$diag/system/cmdline.txt"));
|
||||
// create folder structure listing
|
||||
$dest = "/$diag/system/folders.txt";
|
||||
foreach ($folders as $folder) {
|
||||
if (is_dir($folder)) exec("echo -ne ".escapeshellarg("\r\n$folder\r\n")." >>".escapeshellarg($dest).";ls -l ".escapeshellarg($folder)."|todos >>".escapeshellarg("$dest")); else exec("echo -ne ".escapeshellarg("\r\n$folder\r\nfolder does not exist\r\n")." >>".escapeshellarg("$dest"));
|
||||
if (is_dir($folder)) exert("echo -ne ".escapeshellarg("\r\n$folder\r\n")." >>".escapeshellarg($dest).";ls -l ".escapeshellarg($folder)."|todos >>".escapeshellarg("$dest")); else exert("echo -ne ".escapeshellarg("\r\n$folder\r\nfolder does not exist\r\n")." >>".escapeshellarg("$dest"));
|
||||
}
|
||||
// copy configuration files (suppress errors)
|
||||
exec("cp /boot/config/*.{cfg,conf,dat} /boot/config/go ".escapeshellarg("/$diag/config")." 2>/dev/null");
|
||||
exert("cp /boot/config/*.{cfg,conf,dat} /boot/config/go ".escapeshellarg("/$diag/config")." 2>/dev/null");
|
||||
// anonymize configuration files
|
||||
if (!$all) exec("sed -ri 's/^((disk|flash)(Read|Write)List.*=\")[^\"]+/\\1.../' ".escapeshellarg("/$diag/config/*.cfg")." 2>/dev/null");
|
||||
if (!$all) exert("sed -ri 's/^((disk|flash)(Read|Write)List.*=\")[^\"]+/\\1.../' ".escapeshellarg("/$diag/config/*.cfg")." 2>/dev/null");
|
||||
|
||||
// don't anonymize system share names
|
||||
$vardomain = file_exists('/boot/config/domain.cfg') ? parse_ini_file('/boot/config/domain.cfg') : [];
|
||||
@@ -143,7 +148,7 @@ foreach ($files as $file) {
|
||||
$dest = anonymize($dest,2);
|
||||
}
|
||||
@copy($file, $dest);
|
||||
if (!$all) exec("sed -ri 's/^(share(Comment|ReadList|WriteList)=\")[^\"]+/\\1.../' ".escapeshellarg($dest)." 2>/dev/null");
|
||||
if (!$all) exert("sed -ri 's/^(share(Comment|ReadList|WriteList)=\")[^\"]+/\\1.../' ".escapeshellarg($dest)." 2>/dev/null");
|
||||
}
|
||||
// create default user shares information
|
||||
$shares = file_exists("$get/shares.ini") ? parse_ini_file("$get/shares.ini", true) : [];
|
||||
@@ -156,17 +161,17 @@ $max = 1*1024*1024; //=1MB
|
||||
$docker = "/var/log/docker.log";
|
||||
if (file_exists($docker)) {
|
||||
$log = "/$diag/logs/docker";
|
||||
exec("todos <$docker >".escapeshellarg("$log.txt"));
|
||||
exert("todos <$docker >".escapeshellarg("$log.txt"));
|
||||
if (filesize($docker)>=$max) {
|
||||
exec("tail -n 200 ".escapeshellarg("$log.txt")." >".escapeshellarg("$log.last200.txt"));
|
||||
exec("truncate -s '<$max' ".escapeshellarg("$log.txt"));
|
||||
exert("tail -n 200 ".escapeshellarg("$log.txt")." >".escapeshellarg("$log.last200.txt"));
|
||||
exert("truncate -s '<$max' ".escapeshellarg("$log.txt"));
|
||||
}
|
||||
}
|
||||
// create SMART reports (suppress errors)
|
||||
$disks = file_exists("$get/disks.ini") ? parse_ini_file("$get/disks.ini", true) : [];
|
||||
include_once "$docroot/webGui/include/CustomMerge.php";
|
||||
include_once "$docroot/webGui/include/Wrappers.php";
|
||||
exec("ls -l /dev/disk/by-id/[asun]* 2>/dev/null|sed '/-part/d;s|^.*/by-id/[^-]*-||;s|-> ../../||;s|:|-|'", $devices);
|
||||
exert("ls -l /dev/disk/by-id/[asun]* 2>/dev/null|sed '/-part/d;s|^.*/by-id/[^-]*-||;s|-> ../../||;s|:|-|'", $devices);
|
||||
foreach ($devices as $device) {
|
||||
list($name,$port) = explode(' ',$device);
|
||||
$diskName = ''; $type = '';
|
||||
@@ -181,16 +186,16 @@ foreach ($devices as $device) {
|
||||
}
|
||||
$port = port_name($port);
|
||||
$status = $find['status'] == "DISK_OK" ? "" : " - {$find['status']}";
|
||||
exec("smartctl -x $type ".escapeshellarg("/dev/$port")." 2>/dev/null|todos >".escapeshellarg("/$diag/smart/$name-$date $diskName ($port)$status.txt"));
|
||||
exert("smartctl -x $type ".escapeshellarg("/dev/$port")." 2>/dev/null|todos >".escapeshellarg("/$diag/smart/$name-$date $diskName ($port)$status.txt"));
|
||||
}
|
||||
// create cache pool information
|
||||
if (is_dir('/mnt/cache') && strpos($disks['cache']['fsType'],'btrfs')!==false) {
|
||||
exec("/sbin/btrfs filesystem usage /mnt/cache 2>/dev/null|todos >".escapeshellarg("/$diag/system/btrfs-usage.txt"));
|
||||
exert("/sbin/btrfs filesystem usage /mnt/cache 2>/dev/null|todos >".escapeshellarg("/$diag/system/btrfs-usage.txt"));
|
||||
}
|
||||
// create installed plugin information
|
||||
$plugins = glob("/var/log/plugins/*.plg");
|
||||
foreach ($plugins as $plugin) {
|
||||
$installedPlugins .= basename($plugin)." - ".exec("plugin version ".escapeshellarg($plugin))."\r\n";
|
||||
$installedPlugins .= basename($plugin)." - ".exert("plugin version ".escapeshellarg($plugin))."\r\n";
|
||||
}
|
||||
$installedPlugins = $installedPlugins ?: "No additional Plugins Installed";
|
||||
file_put_contents("/$diag/system/plugins.txt",$installedPlugins);
|
||||
@@ -198,10 +203,10 @@ file_put_contents("/$diag/system/plugins.txt",$installedPlugins);
|
||||
$libvirtd = "/var/log/libvirt/libvirtd.log";
|
||||
if (file_exists($libvirtd)) {
|
||||
$log = "/$diag/logs/libvirt";
|
||||
exec("todos <$libvirtd >".escapeshellarg("$log.txt"));
|
||||
exert("todos <$libvirtd >".escapeshellarg("$log.txt"));
|
||||
if (filesize($libvirtd)>=$max) {
|
||||
exec("tail -n 200 ".escapeshellarg("$log.txt")." >".escapeshellarg("$log.last200.txt"));
|
||||
exec("truncate -s '<$max' ".escapeshellarg("$log.txt"));
|
||||
exert("tail -n 200 ".escapeshellarg("$log.txt")." >".escapeshellarg("$log.last200.txt"));
|
||||
exert("truncate -s '<$max' ".escapeshellarg("$log.txt"));
|
||||
}
|
||||
}
|
||||
// copy VMs information (if existing)
|
||||
@@ -209,10 +214,10 @@ $qemu = glob("/var/log/libvirt/qemu/*.log*");
|
||||
if ($qemu) {
|
||||
foreach ($qemu as $file) {
|
||||
$log = "/$diag/qemu/".basename($file,'.log');
|
||||
exec("todos <".escapeshellarg($file)." >".escapeshellarg("$log.txt"));
|
||||
exert("todos <".escapeshellarg($file)." >".escapeshellarg("$log.txt"));
|
||||
if (filesize($file)>=$max) {
|
||||
exec("tail -n 200 ".escapeshellarg("$log.txt")." >".escapeshellarg("$log.last200.txt"));
|
||||
exec("truncate -s '<$max' ".escapeshellarg("$log.txt"));
|
||||
exert("tail -n 200 ".escapeshellarg("$log.txt")." >".escapeshellarg("$log.last200.txt"));
|
||||
exert("truncate -s '<$max' ".escapeshellarg("$log.txt"));
|
||||
}
|
||||
}
|
||||
} else
|
||||
@@ -221,26 +226,26 @@ if ($qemu) {
|
||||
$max = 2*1024*1024; //=2MB
|
||||
foreach (glob("/var/log/syslog*") as $file) {
|
||||
$log = "/$diag/logs/".basename($file);
|
||||
exec("todos <".escapeshellarg($file)." >".escapeshellarg("$log.txt"));
|
||||
exert("todos <".escapeshellarg($file)." >".escapeshellarg("$log.txt"));
|
||||
if (!$all) {
|
||||
unset($titles,$rows);
|
||||
exec("grep -Po 'logger: moving \"\K[^\"]+' ".escapeshellarg("$log.txt")." 2>/dev/null|sort|uniq", $titles);
|
||||
exec("sed -ri 's|\b\S+@\S+\.\S+\b|xxx@removed.com|;s|\b(username\|password)([=:])\S+\b|\\1\\2xxx|;s|(GUID: \S)\S+(\S) |\\1..\\2 |;s|(moving \"\S\|\"/mnt/user/\S).*(\S)\"|\\1..\\2\"|' ".escapeshellarg("$log.txt"));
|
||||
exec("sed -ri 's|(host: \").+(\.unraid\.net:[0-9]+\")|\\1hash\\2|;s|(referrer: \"https?://).+(\.unraid\.net)|\\1hash\\2|' ".escapeshellarg("$log.txt"));
|
||||
exert("grep -Po 'logger: moving \"\K[^\"]+' ".escapeshellarg("$log.txt")." 2>/dev/null|sort|uniq", $titles);
|
||||
exert("sed -ri 's|\b\S+@\S+\.\S+\b|xxx@removed.com|;s|\b(username\|password)([=:])\S+\b|\\1\\2xxx|;s|(GUID: \S)\S+(\S) |\\1..\\2 |;s|(moving \"\S\|\"/mnt/user/\S).*(\S)\"|\\1..\\2\"|' ".escapeshellarg("$log.txt"));
|
||||
exert("sed -ri 's|(host: \").+(\.unraid\.net:[0-9]+\")|\\1hash\\2|;s|(referrer: \"https?://).+(\.unraid\.net)|\\1hash\\2|' ".escapeshellarg("$log.txt"));
|
||||
foreach ($titles as $mover) {
|
||||
$title = "/{$mover[0]}..".substr($mover,-1)."/...";
|
||||
exec("sed -ri 's|(logger: [.>cr].*)[ /]$mover/.*$|\\1 file: $title|' ".escapeshellarg("$log.txt")." 2>/dev/null");
|
||||
exert("sed -ri 's|(logger: [.>cr].*)[ /]$mover/.*$|\\1 file: $title|' ".escapeshellarg("$log.txt")." 2>/dev/null");
|
||||
}
|
||||
exec("grep -n ' cache_dirs: -' ".escapeshellarg("$log.txt")." 2>/dev/null|cut -d: -f1", $rows);
|
||||
for ($i = 0; $i < count($rows); $i += 2) for ($row = $rows[$i]+1; $row < $rows[$i+1]; $row++) exec("sed -ri '$row s|(cache_dirs: \S).*(\S)|\\1..\\2|' ".escapeshellarg("$log.txt")." 2>/dev/null");
|
||||
exert("grep -n ' cache_dirs: -' ".escapeshellarg("$log.txt")." 2>/dev/null|cut -d: -f1", $rows);
|
||||
for ($i = 0; $i < count($rows); $i += 2) for ($row = $rows[$i]+1; $row < $rows[$i+1]; $row++) exert("sed -ri '$row s|(cache_dirs: \S).*(\S)|\\1..\\2|' ".escapeshellarg("$log.txt")." 2>/dev/null");
|
||||
}
|
||||
// replace consecutive repeated lines in syslog
|
||||
exec("awk -i inplace '{if(s!=substr(\$0,17)){if(x>0)print\"### [PREVIOUS LINE REPEATED \"x\" TIMES] ###\\r\";print;x=0}else{x++}s=substr(\$0,17)}END{if(x>0)print\"### [PREVIOUS LINE REPEATED \"x\" TIMES] ###\\r\"}' ".escapeshellarg("$log.txt"));
|
||||
exert("awk -i inplace '{if(s!=substr(\$0,17)){if(x>0)print\"### [PREVIOUS LINE REPEATED \"x\" TIMES] ###\\r\";print;x=0}else{x++}s=substr(\$0,17)}END{if(x>0)print\"### [PREVIOUS LINE REPEATED \"x\" TIMES] ###\\r\"}' ".escapeshellarg("$log.txt"));
|
||||
// truncate syslog if too big
|
||||
if (basename($file)=='syslog' && filesize($file)>=$max) exec("tail -n 200 ".escapeshellarg("$log.txt")." >".escapeshellarg("$log.last200.txt"));
|
||||
exec("truncate -s '<$max' ".escapeshellarg("$log.txt"));
|
||||
if (basename($file)=='syslog' && filesize($file)>=$max) exert("tail -n 200 ".escapeshellarg("$log.txt")." >".escapeshellarg("$log.last200.txt"));
|
||||
exert("truncate -s '<$max' ".escapeshellarg("$log.txt"));
|
||||
}
|
||||
// create resulting zip file and remove temp folder
|
||||
exec("zip -qmr ".escapeshellarg($zip)." ".escapeshellarg("/$diag"));
|
||||
exert("zip -qmr ".escapeshellarg($zip)." ".escapeshellarg("/$diag"));
|
||||
if ($cli) echo "done.\nZIP file '$zip' created.\n";
|
||||
?>
|
||||
|
||||
Reference in New Issue
Block a user