• SEARCH

    통합검색
세모계
    • Dark Mode
    • GNB Always Open
    • GNB Height Maximize
    • Color
    • Brightness
    • SINCE 2015.01.19.
    • 세모계 세모계
    •   SEARCH
    • 세상의 모든 계산기
      • 자유(질문) 게시판
      • 계산기 뉴스/정보
      • 수학, 과학, 공학 이야기
      • 세모계 : 공지 게시판
        • 구글 맞춤검색
    • TI
    • CASIO
    • HP
    • SHARP
    • 일반(쌀집) 계산기
    • 기타계산기
    • by OrangeDay
  • 세상의 모든 계산기 자유(질문) 게시판
    • 세상의 모든 계산기 자유(질문) 게시판 일반 ()
    • (Nginx) "웹 크롤러 request 순위 확인" 스크립트 (우분투)

    • Profile
      • 세상의모든계산기
      • 2025.02.15 - 10:57 2025.02.14 - 17:40 7302
    #!/bin/bash
    # monip.sh
    # Nginx access 로그에서 상위 25개 IP를 분석하여
    # - Bot (Crawler)인 경우: User-Agent 문자열로 Bot 종류를 추출
    # - User인 경우: whois 명령으로 Organization Name 조회
    # 그리고 IP별 국가 정보(geoiplookup)를 추가하여 출력함
    
    LOG_FILE="/var/log/nginx/access.log"
    
    if [ ! -f "$LOG_FILE" ]; then
        echo "로그 파일이 존재하지 않습니다: $LOG_FILE"
        exit 1
    fi
    
    awk '
      # Bot의 종류를 판별하는 함수
      function get_bot_type(ua,   ua_lower) {
        ua_lower = tolower(ua)
        if(ua_lower ~ /googlebot/)   return "Googlebot"
        if(ua_lower ~ /bingbot/)      return "Bingbot"
        if(ua_lower ~ /slurp/)        return "Yahoo Slurp"
        if(ua_lower ~ /duckduckbot/)  return "DuckDuckBot"
        if(ua_lower ~ /baiduspider/)  return "Baiduspider"
        if(ua_lower ~ /yandex/)       return "YandexBot"
        return "Unknown Bot"
      }
      
      # User-Agent 문자열을 바탕으로 사용자 종류를 판별
      function classify_user_agent(ua) {
        if(ua == "" || ua == "-") return "알 수 없음"
        ua_lower = tolower(ua)
        if(ua_lower ~ /bot|crawl|spider|slurp|mediapartners/) return "Bot (Crawler)"
        return "User"
      }
      
      # geoiplookup 명령을 사용하여 IP의 국가 정보를 가져오는 함수
      function get_country(ip,   cmd, result, arr, country) {
        cmd = "geoiplookup " ip " 2>/dev/null"
        if ((cmd | getline result) > 0) {
          # 예: "GeoIP Country Edition: US, United States"
          split(result, arr, ":")
          if(length(arr) > 1) {
            country = arr[2]
            gsub(/^[ \t]+|[ \t]+$/, "", country)
          } else {
            country = "Unknown"
          }
        } else {
          country = "조회 실패"
        }
        close(cmd)
        return country
      }
      
      {
        # Combined log format 예제:
        # 127.0.0.1 - - [14/Feb/2025:12:00:00 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 ..."
        regex = "([^ ]*) - ([^ ]*) \\[([^\\]]*)\\] \"([^\"]*)\" ([^ ]*) ([^ ]*) \"([^\"]*)\" \"([^\"]*)\""
        if(match($0, regex, arr)) {
          ip      = arr[1]
          referer = arr[7]
          ua_str  = arr[8]
          
          count[ip]++                  # IP별 요청 횟수 집계
          ua_stats[ip, ua_str]++        # IP별 User-Agent 빈도 집계
          ref_stats[ip, referer]++      # (참고용) 리퍼러 집계
        }
      }
      
      END {
        # gawk의 asorti() 함수로 요청 횟수 기준 내림차순 정렬
        n = asorti(count, sorted, "@val_num_desc")
        
        # 헤더 출력 (순서: 순위 | IP | 국가 | Requests | 사용자 종류 | 기타정보)
        printf("| %-2s | %-15s | %-18s | %-10s | %-17s | %-21s |\n", "순위", "IP", "국가", "Requests", "사용자 종류", "기타정보")
        print("|------|-----------------|----------------------|------------|------------------------|-------------------------|")
        
        limit = (n < 25 ? n : 25)
        for(i = 1; i <= limit; i++){
          ip = sorted[i]
          req_count = count[ip]
          
          # 해당 IP의 가장 많이 등장한 User-Agent 선택
          max_ua = ""
          max_ua_count = 0
          for(key in ua_stats) {
            split(key, parts, SUBSEP)
            if(parts[1] == ip) {
              if(ua_stats[key] > max_ua_count) {
                max_ua_count = ua_stats[key]
                max_ua = parts[2]
              }
            }
          }
          
          user_type = classify_user_agent(max_ua)
          
          extra = ""
          if(user_type == "User") {
             # User인 경우: whois 명령으로 Organization Name 조회
             cmd = "whois " ip " 2>/dev/null | grep -i -m 1 \"orgname:\""
             org = ""
             if((cmd | getline org) > 0) {
                sub(/^[ \t]+/, "", org)
                split(org, a, ":")
                if(length(a) > 1) {
                  org = a[2]
                  gsub(/^[ \t]+/, "", org)
                }
             } else {
                org = "조회 실패"
             }
             close(cmd)
             extra = org
          } else if(user_type == "Bot (Crawler)") {
             extra = get_bot_type(max_ua)
          } else {
             extra = "없음"
          }
          
          # 각 IP의 국가 정보 추가
          country = get_country(ip)
          
          printf("| %-4d | %-15s | %-20s | %-10d | %-22s | %-25s |\n", i, ip, country, req_count, user_type, extra)
        }
      }
    ' "$LOG_FILE"

     

     

    사용 방법

    1. 스크립트를 파일에 저장 후 실행 권한 부여:

      chmod +x monip.sh

    2. 스크립트 실행 (필요한 경우 sudo로):

      sudo ./monip.sh

     

     

    결과

    image.png

    Attached file
    image.png 288.8KB 44
    이 게시물을..
    N
    0
    0
    • 세상의모든계산기 25
      세상의모든계산기

      계산기는 거들 뿐
      혹은
      계산기를 거들 뿐

    세상의모든계산기 님의 최근 글

    ban 설정 강화 73544 1 2026 05.09 정적분 구간에 미지수가 있고, solve 를 사용할 수 없을 때 그 값을 확인하려면? 2682 4 2026 04.10 높아질수록 좁아지는 시야에 대하여 - written by ChatGPT 12360 2026 02.12 내가 올해 몇살이더라? (내 나이 계산기) 9889 2026 02.11 AGI 자기 거버넌스 구조와 인간-AGI 관계 모델 (written by GEMINI & GPT) 12838 1 2026 01.30

    세상의모든계산기 님의 최근 댓글

    본문의 변환 위젯에 사용된 전서체 폰트는 대만의 최고 학술 연구 기관인 중앙연구원(Academia Sinica)에서 제공하는 ‘숭희전체(崇羲篆體)’로 전통 한자 서체인 소전(小篆)을 현대 컴퓨터 폰트(글꼴)로 구축한 오픈소스 프로젝트로 개발되었습니다. https://xiaoxue.iis.sinica.edu.tw/chongxi/download.htm 2026 10.20 예제1)      예제2)       예제3)      추가옵션    2026 10.18 PC 소프트웨어에서 script Editor 로 소스코드를 쉽게 복사 -> AI에게 문의/개선요청 할 수 있습니다. 잘 되거나, 잘 안되는 부분이 있으면 대댓글 남겨주세요. 2026 10.16 AI로 딸깍하니까, lua 프로그램으로 바꿔주네요. 세상 참... 본문의 ti-basic 기반으로 만들었고, 서로 문제를 일으킬 수 있을 듯 하여 별개의 파일로 작성하였습니다.  1.1 Page : 설명 1.2 Page : 그래프  1.3 Page : Calculator     사용법  Root Locus 1+K*N/D=0    EX: (6s^2+5s+2)/(6s^3(s^2+7s+16)) INPUT (Calculator page 1.3 ):    rl_num:={6,5,2}    rl_den:={6,42,96,0,0,0}  or    num(6s^2+5s+2)    den(6s^3(s^2+7s+16))    optional:   rl_T:=10  rl_D:=1  Coeffs are descending powers of s.  Back on graph page it refreshes itself,  else press [r] or [enter].  KEYS: [+] [-] Kmax zoom, [0] reset, [r] reload  MARKS: x=pole, o=zero, red line=real axis,  gray dash=asymptote, box=break pt, diamond=j-cross  VARS: rl_Kmax rl_sigma rl_r rl_JK rl_Jw    첨부파일 rlocus_lua.tns   2026 10.16 링크가 깨졌다고 하시니   404 에러가 나는 아래 링크를 말씀하시는 것 같은데  https://digilander.libero.it/fpirozzi/fourier.zip 이것은 TI-89 / TI-92 용 파일이며    [TI-92][TI-89] Fourier Transform Library https://allcalc.org/52455 링크의 Attached files + 안에 있습니다.  2026 09.11
    글쓴이의 서명작성글 감추기 
    • 댓글 입력
    • 에디터 전환
    댓글 쓰기 에디터 사용하기 닫기
    • view_headline 목록
    • 14px
    • 목록
      view_headline
    × CLOSE
    전체 일반 389 질문 509 웃김 2 팁 & 정보 16 퀴즈 2 리뷰 11 퍼옴 & 링크 6 공지 1
    기본 (0) 제목 날짜 수정 조회 댓글 추천 비추
    분류 정렬 검색
    등록된 글이 없습니다.
    • 글쓰기
    • 세상의 모든 계산기 자유(질문) 게시판
    • 세상의모든계산기
    • 사업자등록번호 703-91-02181
    • 세모계 all rights reserved.