PHP 를 이용 하여 Nginx 로그 의 User Agent 데 이 터 를 어떻게 통계 합 니까?

8624 단어 nginxuseragent
머리말
파충류 사용 을 앞 두 고 User Agent(UA)데 이 터 를 수집 하려 고 합 니 다.이 어 자신의 사이트 방문 로그 가 기 존의 양질 의 데이터 소스 가 아니 냐 는 생각 이 들 었 다.그래서 즐겁게 스 크 립 트 를 써 서 Nginx 방문 로그 의 UA 정 보 를 집계 하기 로 했 습 니 다.
이런 간단 한 조작 은 스 크 립 트 언어 로 충분 하 며,틀림없이 가장 익숙 한 PHP 를 사용 해 야 한다.vim 를 열 면 훑 습 니 다.10 분 후에 기능 이 간단 한 통계 스 크 립 트 가 해 결 됩 니 다.
스 크 립 트 는 현재 세 가지 기능 이 있 습 니 다.
1.모든 UA 정 보 를 찾 아 정렬 하기;2.운영 체제 데 이 터 를 통계 한다.3.브 라 우 저 데 이 터 를 통계 합 니 다.
프로그램 실행 캡 처 는 다음 과 같 습 니 다.
1.UA 정보

2.운영 체제 정보

3.브 라 우 저

최근 한 달 간 의 방문 로 그 를 스 크 립 트 로 집계 하여 다음 과 같은 결 과 를 얻 을 수 있 습 니 다.
  • 검색엔진 파충류 가 비교적 빈번 하고 매일 수천 번 의 데이터 방문 이 있다
  • 윈도 우 는 여전히 점유 율 이 가장 큰 운영 체제 이 고 리 눅 스 데스크 톱 은 여전히 점유 율 이 매우 작다
  • 4.567917.크롬 은 현재 브 라 우 저 분야 의 맹주 이 고 그 다음은 Firefox 이 며 Opera 는 이미 매우 작다마지막 으로 PHP 스 크 립 트 의 코드 를 첨부 하면 본인 의 Github 에서 찾 을 수 있 습 니 다.https://github.com/tlanyan/Scripts/blob/master/statUA.php
    
    #!/usr/bin/php
    <?php
    /**
     * @brief stat UA in access log
     *
     * @author tlanyan<[email protected]>
     * @link http://tlanyan.me
     */
    /* vim: set ts=4; set sw=4; set ss=4; set expandtab; */
    function getFileList(string $path) : array {
     return glob(rtrim($path, "/") . "/*access.log*");
    }
    function statFiles(array $files) : array {
     $stat = [];
     echo PHP_EOL, "start to read files...", PHP_EOL;
     foreach ($files as $file) {
      echo "read file: $file ...", PHP_EOL;
      $contents = getFileContent($file);
      foreach ($contents as $line) {
       $ua = getUA($line);
       if (isset($stat[$ua])) {
        $stat[$ua] += 1;
       } else {
        $stat[$ua] = 1;
       }
      }
     }
     echo "stat all files done!", PHP_EOL, PHP_EOL;
     return $stat;
    }
    function getFileContent(string $file) : array {
     if (substr($file, -3, 3) === ".gz") {
      return gzfile($file);
     }
     return file($file);
    }
    function getUA(string $line) : ?string {
     // important! Nginx log format determins the UA location in the line!
     // You may have to refactor following codes to get the right result
     // UA starts from fifth double quote 
     $count = 0; $offset = 0;
     while ($count < 5) {
      $pos = strpos($line, '"', $offset);
      if ($pos === false) {
       echo "Error! Unknown line: $line", PHP_EOL;
       return null;
      }
      $count ++;
      $offset = $pos + 1;
     }
     $end = strpos($line, '"', $offset);
     return substr($line, $offset, $end - $offset);
    }
    function usage() {
     echo "Usage: php statUA.php [option] [dir]", PHP_EOL;
     echo " options:", PHP_EOL;
     echo " -h: show this help", PHP_EOL;
     echo " -v: verbose mode", PHP_EOL;
     echo "-n NUM: UA list number", PHP_EOL;
     echo " dir: directory to the log files", PHP_EOL;
     echo PHP_EOL;
    }
    function filterUA(array& $stat, array $UAFilters) {
     $filterCount = 0;
     foreach ($UAFilters as $filter) {
      foreach ($stat as $ua => $count) {
       if (stripos($ua, $filter) !== false) {
        $filterCount += $count;
        unset($stat[$ua]);
       }
      }
     }
     echo "filter $filterCount records!", PHP_EOL;
    }
    function printCount(array $stat) {
     $sum = array_sum($stat);
     foreach ($stat as $key => $count) {
      echo $key, " : ", $count, ", percent: ", sprintf("%.2f", 100*$count/$sum), PHP_EOL;
     }
    }
    function statOS(array $UAs) : array {
     global $debug;
     echo PHP_EOL, "stat OS...", PHP_EOL;
     $os = ["Windows", "MacOS", "Linux", "Android", "iOS", "other"];
     $stat = array_fill_keys($os, 0);
     foreach ($UAs as $key => $count) {
      if (strpos($key, "Windows") !== false) {
       $stat["Windows"] += $count;
      } else if (strpos($key, "Macintosh") !== false) {
       $stat["MacOS"] += $count;
      // must deal Android first, then Linux
      } else if (strpos($key, "Android") !== false) {
       $stat["Android"] += $count;
      } else if (strpos($key, "Linux") !== false) {
       $stat["Linux"] += $count;
      } else if (strpos($key, "iPhone") !== false || strpos($key, "iOS") !== false || strpos($key, "like Mac OS") !== false || strpos($key, "Darwin") !== false) {
       $stat["iOS"] += $count;
      } else {
       if ($debug) {
        echo "other: $key, count: $count", PHP_EOL;
       }
       $stat["other"] += $count;
      }
     }
     return $stat;
    }
    function statBrowser(array $UAs) : array {
     global $debug;
     echo PHP_EOL, "stat brwoser...", PHP_EOL;
     $browsers = ["Chrome", "Firefox", "IE", "Safari", "Edge", "Opera", "other"];
     $stat = array_fill_keys($browsers, 0);
     foreach ($UAs as $key => $count) {
      if (strpos($key, "MSIE") !== false) {
       $stat["IE"] += $count;
      } else if (strpos($key, "Edge") !== false) {
       $stat["Edge"] += $count;
      } else if (strpos($key, "Firefox") !== false) {
       $stat["Firefox"] += $count;
      } else if (strpos($key, "OPR") !== false) {
       $stat["Opera"] += $count;
      // first Chrome, then Safari
      } else if (strpos($key, "Chrome") !== false) {
       $stat["Chrome"] += $count;
      } else if (strpos($key, "Safari") !== false) {
       $stat["Safari"] += $count;
      } else {
       if ($debug) {
        echo "other: $key, count: $count", PHP_EOL;
       }
       $stat["other"] += $count;
      }
     }
     return $stat;
    }
    function parseCmd() {
     global $debug, $num, $path, $argc, $argv;
     $optind = null;
     $options = getopt("hvn:", [], $optind);
     if ($argc > 2 && empty($options)) {
      usage();
      exit(1);
     }
     if (isset($options['h'])) {
      usage();
      exit(0);
     }
     if (isset($options['v'])) {
      $debug = true;
     }
     if (isset($options['n'])) {
      $num = intval($options['n']);
      if ($num <= 0) {
       $num = 10;
      }
     }
     if ($argc === 2 && empty($options)) {
      $path = $argv[1];
     }
     if ($argc > $optind) {
      $path = $argv[$optind];
     }
     if (!is_dir($path)) {
      echo "invalid directory: $path", PHP_EOL;
      exit(1);
     }
     if ($debug) {
      echo "num: $num", PHP_EOL;
      echo "verbose: ", var_export($debug, true), PHP_EOL;
      echo "path: $path", PHP_EOL;
     }
    }
    if (version_compare(PHP_VERSION, "7.1") < 0) {
     exit("scripts require PHP >=7.1");
    }
    $path = ".";
    $debug = false;
    $num = 10;
    $UAFilters = [
     "spider",
     "bot",
     "wget",
     "curl",
    ];
    parseCmd();
    $files = getFileList($path);
    if (empty($files)) {
     echo '"' . realpath($path) . '" does not contain access log files.', PHP_EOL;
     exit(0);
    }
    $allUA = statFiles($files);
    if (empty($allUA)) {
     echo "no data", PHP_EOL;
     exit(0);
    }
    filterUA($allUA, $UAFilters);
    // sort array with count
    uasort($allUA, function ($a, $b) {
     return $b - $a;
    });
    if ($debug) {
     print_r($allUA);
    }
    echo PHP_EOL, "---- top $num UA ----", PHP_EOL;
    printCount(array_slice($allUA, 0, $num));
    echo "-------------------", PHP_EOL;
    $os = statOS($allUA);
    echo PHP_EOL, "os count:", PHP_EOL;
    printCount($os);
    $browser = statBrowser($allUA);
    echo PHP_EOL, "browser count:", PHP_EOL;
    printCount($browser);
    총결산
    이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.

    좋은 웹페이지 즐겨찾기