서버 디스크용량 부족한지 체크하는 프로그램
MRTG나 각종 관제용 프로그램을 사용하는곳에선 필요하지 않지만 소규모로 운영하는 곳은 이런것이 필요 합니다.
그리고 은근히 디스크용량 때문에 발생하는 문제 들이 있습니다.
나도 모르게 로그가 많이 쌓여서 disk full 만들어 다른 문제를 야기 시키죠
충분한 디스크 용량이 있으면 괜찮은데 그렇지 아니한 경우는 반드시 이러한 프로그램이 필요 합니다.
이렇게 하여 SMS나 텔레그램 같은 곳으로 전달을 받아 운영 관리를 하면 되겠지요.
class DiskUsageChecker {
/** @var int 사용률 임계값 (%) */
private $iThreshold = 95;
public function __construct($iThreshold=95) {
$this->iThreshold = $iThreshold;
}
/**
* df 명령을 실행하여 사용률이 임계값(iThreshold)을 초과하는 디스크 정보를 배열로 리턴합니다.
* NFS, NFS4, CIFS 파일 시스템은 제외합니다.
*
* @return array<int, array<string, string>> 사용률이 높은 디스크 정보 배열.
* 각 요소는 ['sTotalSize', 'sAvailableSize', 'sMountedOn', 'sUsagePercent'] 키를 가집니다.
*/
public function getHighUsageDisks(): array {
// 실행할 df 명령어 (nfs, nfs4, cifs 제외)
// -P 옵션은 출력을 POSIX 형식으로 표준화하여 파싱을 쉽게 합니다.
$sCommand = "df -P -x nfs -x nfs4 -x cifs 2>/dev/null";
$aOutput = [];
$iReturnVar = 0;
exec($sCommand, $aOutput, $iReturnVar);
if ($iReturnVar !== 0 || empty($aOutput)) {
return [];
}
$aHighUsageDisks = [];
array_shift($aOutput);
foreach ($aOutput as $sLine) {
$aParts = preg_split('/\s+/', $sLine, -1, PREG_SPLIT_NO_EMPTY);
if (count($aParts) < 6) {
continue;
}
$sUsedPercentRaw = $aParts[4];
$iUsedPercent = (int)rtrim($sUsedPercentRaw, '%');
// 사용률이 임계값(iThreshold)을 초과하는지 확인
if ($iUsedPercent > $this->iThreshold) {
// 결과 배열에 필요한 정보만 저장
$aHighUsageDisks[] = [
'sTotalSize' => $this->formatSizeFromKb($aParts[1]),
'sAvailableSize' => $this->formatSizeFromKb($aParts[3]),
'sMountedOn' => $aParts[5],
'sUsagePercent' => $sUsedPercentRaw,
];
}
// $aHighUsageDisks[] = [
// 'sTotalSize' => $this->formatSizeFromKb($aParts[1]),
// 'sAvailableSize' => $this->formatSizeFromKb($aParts[3]),
// 'sMountedOn' => $aParts[5],
// 'sUsagePercent' => $sUsedPercentRaw,
// ];
}
return $aHighUsageDisks;
}
/**
* df -P의 1K-blocks 값을 사람이 읽기 쉬운 용량 단위(GB, MB 등)로 변환합니다.
*
* @param string $sKbBlocks df -P에서 얻은 1K-blocks 값
* @return string 변환된 용량 문자열
*/
private function formatSizeFromKb(string $sKbBlocks): string {
$iBytes = (int)$sKbBlocks * 1024; // 1K-blocks * 1024 = Bytes
$aUnits = ['B', 'KB', 'MB', 'GB', 'TB'];
$i = 0;
if ($iBytes === 0) {
return '0B';
}
while ($iBytes >= 1024 && $i < count($aUnits) - 1) {
$iBytes /= 1024;
$i++;
}
return round($iBytes, 1) . $aUnits[$i];
}
}
$oChecker = new DiskUsageChecker(86);
$aCriticalDisks = $oChecker->getHighUsageDisks();
$msg = '';
if (empty($aCriticalDisks)) {
echo "사용률이 95%를 초과하는 디스크는 없습니다. \n";
} else {
$msg = " 디스크 사용율 초과 서버: $HOST_NAME \n";
foreach ($aCriticalDisks as $aDisk) {
$msg .= "----------------------------------\n";
$msg .= "마운트된 곳: " . $aDisk['sMountedOn'] . "\n";
$msg .= "사용률: " . $aDisk['sUsagePercent'] . "\n";
$msg .= "전체 용량: " . $aDisk['sTotalSize'] . "\n";
$msg .= "남은 용량: " . $aDisk['sAvailableSize'] . "\n";
}
$msg .= "----------------------------------\n";
}
echo $msg;
