PHPは簡単なnginxログファイルの監視機能を実現

11386 ワード

この機能は、nginxで生成されたログデータをタイミング的に監視し、新しいデータを1つのインタフェース(例えば、ビッグデータのインタフェース、ビッグデータに分析させる)にコミットするために実現されます.
define("MAX_SHOW", 8192*5);  //        
define("LOG_NAME", "");  //       
define("LOG_SIZE", ""); //         
define("LOG_URL", ""); //      



//   log      
$log_size        = get_filesize();
$file_size         = filesize(LOG_NAME);

if(empty($log_size)){//        ,        
    $file_size = $file_size;
}else if($log_size > $file_size){ //
    $file_size = 0;
}else{  //          
    $file_size = $log_size;
}

$file_size_new     = 0;
$add_size         = 0;
$ignore_size     = 0;
$fp = fopen(LOG_NAME, "r");
while(1){
    clearstatcache();
    $read_num = 0;
    $file_size_new = filesize(LOG_NAME);
    $add_size = $file_size_new - $file_size;
    $add_data = array();
    $add_log  = '';
    if($add_size > 0){ 
        //          
        if($add_size > MAX_SHOW){
            fseek($fp, $file_size);
            
            //      8192,         
            $page = ceil($add_size/8192);
            for($i=1; $i<=$page; $i++){
                if($i == $page){//    
                    $end_add = $add_size - ($page -1) * 8192;
                    $add_log .= fread($fp, $end_add);
                }else{
                    $add_log .= fread($fp, 8192);
                    $file_size_step =  $file_size + $i  * 8192;
                    fseek($fp, $file_size_step);
                }
                
            }
            $add_data['add_log'] = $add_log;
            $add_data['add_log'] = base64_encode($add_data['add_log']);
            http_post(LOG_URL, $add_data);
            $file_size = $file_size_new;
            //      
            save_filesize($file_size);
        }
    }else if($add_size < 0){  //        
        $file_size = 0;
    }
    sleep(2);
}
fclose($fp);


/**
 *                
 */
function get_filesize(){
    $size = file_get_contents(LOG_SIZE);
    return $size;
}


/**
 *                 
 */
function  save_filesize($size){
    return  file_put_contents(LOG_SIZE, $size);
}



/**
 * http  
 * @param array $data
 * @return boolean
 */
function http_post($url = '', $data = array())
{
    if(empty($url)){
        return FALSE;
    }

    if($data){
        $data = http_build_query($data);
    }

    $ch = curl_init ();
    curl_setopt ( $ch, CURLOPT_URL, $url );
    curl_setopt ( $ch, CURLOPT_POST, 1 );
    curl_setopt ( $ch, CURLOPT_HEADER, 0 );
    curl_setopt ( $ch, CURLOPT_TIMEOUT, 5 );
    curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
    curl_setopt ( $ch, CURLOPT_POSTFIELDS, $data );
    $return = curl_exec ( $ch );
    curl_close ( $ch );
    return $return;
}

備考:ログファイルは明け方に切断されるので、判断が必要です.翌日のログはログファイルの先頭から読み取る必要があると判断します
最適化が必要なロジック:中間プロセスが停止し、しばらく停止してから起動すると、前回の場所から再読み込みされ、コミットされたデータが比較的大きくなり、コミットされたデータのサイズの制限を超える可能性があります.