#!/usr/bin/php -q Array)$/","$1..$2$3",$row); $row = preg_replace("/^(\s*\[(name|nameOrig|comment|flashGUID|regGUID|regTo|readList|writeList|csrf_token)\] => \S).*(\S)$/","$1..$3",$row); } } return implode("\n", $rows); case 2: $name = basename($text,'.cfg'); $len = strlen($name); if ($len>2) { $dash = str_repeat('-',$len-2); $name = preg_replace("/^(\S).*(\S)/","$1$dash$2",$name); $i = 1; while (file_exists(dirname($text)."/$name.cfg")) {$name = substr($name,0,$len)." ($i)"; $i++;} } return dirname($text)."/$name.cfg"; } } if ($cli) { // script is called from CLI echo "Starting diagnostics collection... "; exec("mkdir -p /boot/logs"); $server = isset($var['NAME']) ? str_replace(' ','_',strtolower($var['NAME'])) : 'tower'; $date = date('Ymd-Hi'); $diag = "$server-diagnostics-$date"; $zip = "/boot/logs/$diag.zip"; } else { // script is called from GUI $diag = basename($zip, '.zip'); $split = explode('-', $diag); $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")); // make unRAID version reference $unraid = parse_ini_file('/etc/unraid-version'); file_put_contents("/$diag/unRAID-".$unraid['version'].".txt",$unraid['version']); // copy ini variables foreach (glob("$get/*.ini") as $file) { $ini = basename($file,".ini"); // skip users file in anonymized mode 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); } // 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 -mt 2>/dev/null|todos >".escapeshellarg("/$diag/system/memory.txt")); exec("ps -ef 2>/dev/null|todos >".escapeshellarg("/$diag/system/ps.txt")); exec("lsof -Pni 2>/dev/null|todos >".escapeshellarg("/$diag/system/lsof.txt")); exec("lsmod 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); // create ethernet information information (suppress errors) foreach ($ports as $port) { exec("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")); file_put_contents("/$diag/system/ethtool.txt", "--------------------------------\r\n", FILE_APPEND); } exec("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 ".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")); } // copy configuration files (suppress errors) exec("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"); // copy share information (anonymize if applicable) $files = glob("/boot/config/shares/*.cfg"); foreach ($files as $file) { $dest = anonymize("/$diag/shares/".basename($file),2); @copy($file, $dest); if (!$all) exec("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) : []; foreach ($shares as $share) { $name = $share['name']; if (!in_array("/boot/config/shares/$name.cfg",$files)) file_put_contents(anonymize("/$diag/shares/$name.cfg",2),"# This share has default settings.\r\n"); } // copy syslog information (anonymize if applicable) $max = 2*1024*1024; //=2MB foreach (glob("/var/log/syslog*") as $file) { $log = "/$diag/logs/".basename($file); exec("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")); 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"); } 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"); } 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")); } // copy docker information (if existing) $max = 1*1024*1024; //=1MB $docker = "/var/log/docker.log"; if (file_exists($docker)) { $log = "/$diag/logs/docker"; exec("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")); } } // copy libvirt information (if existing) $libvirtd = "/var/log/libvirt/libvirtd.log"; if (file_exists($libvirtd)) { $log = "/$diag/logs/libvirt"; exec("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")); } } // copy VMs information (if existing) $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")); if (filesize($file)>=$max) { exec("tail -n 200 ".escapeshellarg("$log.txt")." >".escapeshellarg("$log.last200.txt")); exec("truncate -s '<$max' ".escapeshellarg("$log.txt")); } } } else file_put_contents("/$diag/qemu/no qemu log files",""); // 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"; exec("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,$dev) = explode(' ',$device); $type = ''; foreach ($disks as $find) { if ($find['device']==$dev) { $type = isset($find['smType']) ? $find['smType'] : -1; if ($type==-1) $type = isset($var['smType']) ? $var['smType'] : ''; if ($type) { $ports = []; if (isset($find['smDevice']) && strlen($find['smDevice'])) $port = $find['smDevice']; if (isset($find['smPort1']) && strlen($find['smPort1'])) $ports[] = $find['smPort1']; if (isset($find['smPort2']) && strlen($find['smPort2'])) $ports[] = $find['smPort2']; if (isset($find['smPort3']) && strlen($find['smPort3'])) $ports[] = $find['smPort3']; if ($ports) { $glue = isset($find['smGlue']) ? $find['smGlue'] : ','; $type .= ','.implode($glue,$ports); } } break; } } exec("smartctl -a $type ".escapeshellarg("/dev/$dev")." 2>/dev/null|todos >".escapeshellarg("/$diag/smart/$name-$date.txt")); } // create cache pool information if (is_dir('/mnt/cache') && $disks['cache']['fsType']=='btrfs') { exec("/sbin/btrfs filesystem show /mnt/cache 2>/dev/null|todos >".escapeshellarg("/$diag/system/btrfs-show.txt")); exec("/sbin/btrfs filesystem df /mnt/cache 2>/dev/null|todos >".escapeshellarg("/$diag/system/btrfs-df.txt")); } // create resulting zip file and remove temp folder exec("zip -qmr ".escapeshellarg($zip)." ".escapeshellarg("/$diag")); if ($cli) echo "done.\nZIP file '$zip' created.\n"; ?>