Microsoft MVP성태의 닷넷 이야기
개발 환경 구성: 510. Logstash - FileBeat을 이용한 IIS 로그 처리 [링크 복사], [링크+제목 복사],
조회: 12664
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 
(연관된 글이 1개 있습니다.)

Logstash - FileBeat을 이용한 IIS 로그 처리

이제 제법 Logstash에 익숙해졌으니,

Logstash 기본 사용법
; https://www.sysnet.pe.kr/2/0/12312

Logstash - 사용자 정의 grok 패턴 추가를 이용한 IIS 로그 처리
; https://www.sysnet.pe.kr/2/0/12313

근래에 더 현실적으로 사용되는 Beat -> Logstash -> Elasticsearch (또는, Beat -> Elasticsearch) 구조를 살펴보겠습니다. 그나저나 Beat는 "수집"만을 전용으로 담당하는 경량화된 모듈이라고 보면 되는데, 데이터의 성격상 여러 Beat 제품으로 나뉘어 있습니다.

The Beats family
; https://www.elastic.co/downloads/beats

  • FileBeat
  • Packetbeat
  • Winlogbeat
  • Metricbeat
  • Heartbeat
  • Auditbeat
  • Functionbeat
  • Journalbeat

모든 걸 여기서 다룰 수는 없고, 이 글에서는 IIS 로그가 File로 남겨지기 때문에 이를 위한 Filebeat를 사용해 실습을 해보겠습니다.




자, 그럼 먼저 웹 서버 측에 Filebeat를 다운로드해야겠지요.

Download Filebeat (약 24MB)
; https://www.elastic.co/downloads/beats/filebeat

압축 해제 후, 시작은 .\filebeat.exe를 실행하면 되는데 그전에 yml 파일을 통해 설정을 좀 해야 합니다.

  • fields.yml
  • filebeat.yml
  • filebeat.reference.yml

이 중에서 filebeat.reference.yml, fields.yml은 일종의 레퍼런스 문서 역할을 하니 나중에 천천히 보시고, 실질적인 설정을 담당하는 filebeat.yml을 열어 봅니다. (아래는 기본 설치된 filebeat.yml의 주석을 제거한 설정값들을 정리한 것입니다.)

filebeat.inputs:

- type: log

  enabled: false
  paths:
    - /var/log/*.log

filebeat.config.modules:
  path: ${path.config}/modules.d/*.yml
  reload.enabled: false

setup.template.settings:
  index.number_of_shards: 1

setup.kibana:

output.elasticsearch:
  hosts: ["localhost:9200"]

processors:
  - add_host_metadata:
      when.not.contains.tags: forwarded
  - add_cloud_metadata: ~
  - add_docker_metadata: ~
  - add_kubernetes_metadata: ~

우선 "filebeat.config.modules"의 "path"인 "${path.config}/modules.d" 폴더를 보면 Filebeat이 제공하는 다양한 모듈들에 대한 개별 설정을 담고 있지만 확장자가 ".disabled"로 끝나기 때문에 filebeat이 로드해야 할 모듈(*.yml)에 포함되지 않습니다. 따라서, IIS 모듈이 동작하려면 "${path.config}/modules.d/iis.yml.disabled" 파일의 확장자인 ".disabled"를 제거하고 그 안의 내용을,
# Module: iis
# Docs: https://www.elastic.co/guide/en/beats/filebeat/7.9/filebeat-module-iis.html

- module: iis
  # Access logs
  access:
    enabled: true

    # Set custom paths for the log files. If left empty,
    # Filebeat will choose the paths depending on your OS.
    #var.paths:

  # Error logs
  error:
    enabled: true

    # Set custom paths for the log files. If left empty,
    # Filebeat will choose the paths depending on your OS.
    #var.paths:

문서에 따라 "access"의 "var.paths"와 "error"의 "var.paths"를 각각 여러분들의 환경에 맞게 설정/저장해야 합니다. 가령 제 경우에는 다음과 같이 변경했습니다.

- module: iis
  access:
    enabled: true
    var.paths: [ "C:\\inetpub\\logs\\LogFiles\\*\\*.log" ]

  error:
    enabled: true
    var.paths: [ "C:\\Windows\\System32\\LogFiles\\HTTPERR\\*.log" ]

여기까지 설정하고 filebeat.exe을 실행하면 "localhost:9200"의 elasticsearch로 IIS 로그를 보내게 됩니다.




약간의 디버깅 용도라고 하면, elasticsearch에 어떤 데이터를 넘기는지 확인하기 위해 logstash를 사용할 수 있습니다. "Logstash 기본 사용법" 글의 설명에 따라, logstash의 파이프라인을 다음과 같이 설정하고,

input {
    beats {
        port => "5044"
    }
}

output {
    stdout { }
}

Filebeats의 iis.yml에 설정된 출력을 Logstash 쪽으로 바꿔주면,

output.logstash:
  hosts: ["localhost:5044"]

예를 들어, C:\Windows\System32\LogFiles\HTTPERR 경로에 에러 항목이 다음과 같은 유형으로 포함되어 있는 경우,

#Software: Microsoft HTTP API 2.0
#Version: 1.0
#Date: 2020-09-02 12:52:59
#Fields: date time c-ip c-port s-ip s-port cs-version cs-method cs-uri streamid sc-status s-siteid s-reason s-queuename
2020-09-07 04:34:46 192.168.0.7 53858 192.168.100.50 8020 - - - - - - Timer_MinBytesPerSecond -

Logstash 콘솔 출력에 이런 내용을 확인할 수 있습니다.

{
    "@timestamp" => 2020-09-07T04:34:55.340Z,
          "host" => {
        "architecture" => "x86_64",
                  "ip" => [
            [0] "fe80::38cd:62c9:a8a4:d20a",
            [1] "192.168.100.50"
        ],
            "hostname" => "testpc",
                 "mac" => [
            [0] "00:15:5d:00:05:2f"
        ],
                  "id" => "102f9250-5ebd-465d-b42b-b4cd8c09f0f3",
                  "os" => {
               "build" => "17763.1397",
              "kernel" => "10.0.17763.1397 (WinBuild.160101.0800)",
              "family" => "windows",
            "platform" => "windows",
             "version" => "10.0",
                "name" => "Windows Server 2019 Standard"
        },
                "name" => "testpc"
    },
         "event" => {
         "module" => "iis",
        "dataset" => "iis.error"
    },
       "fileset" => {
        "name" => "error"
    },
      "@version" => "1",
         "agent" => {
        "ephemeral_id" => "a533d7f7-b4b8-4ee8-abe1-426091f010ca",
                "type" => "filebeat",
            "hostname" => "testpc",
                  "id" => "c16e0429-6ffa-4f17-afa4-32be234ffdbb",
             "version" => "7.9.1",
                "name" => "testpc"
    },
          "tags" => [
        [0] "beats_input_codec_plain_applied"
    ],
       "service" => {
        "type" => "iis"
    },
           "ecs" => {
        "version" => "1.5.0"
    },
         "input" => {
        "type" => "log"
    },
       "message" => "2020-09-07 04:34:46 192.168.0.7 53858 192.168.100.50 8020 - - - - - - Timer_MinBytesPerSecond -",
           "log" => {
        "offset" => 370319,
          "file" => {
            "path" => "C:\\Windows\\System32\\LogFiles\\HTTPERR\\httperr13.log"
        }
    }
}

그런데, 보는 바와 같이 beats가 보내주는 내용이 꽤 많으므로 만약 이 내용을 그대로 Elasticsearch에 보내면 용량이 꽤나 부담스러울 것입니다. (대부분 mutate/remove_field의 조합으로 잘라내고 싶겠죠. ^^ 그래서 현실적인 이유로 봤을 때 "Beats -> Logstash -> Elasticsearch" 구조가 주로 사용될 것입니다.)




그나저나, logstash가 Filebeat로 받은 데이터를 보면 중간에 beats_input_codec_plain_applied 항목을 담은 "tags"가 있습니다.

{
    "@timestamp" => 2020-09-07T04:37:39.988Z,
         "event" => {
         "module" => "iis",
        "dataset" => "iis.access"
    },
         ...[생략]...
    },
          "tags" => [
        [0] "beats_input_codec_plain_applied"]
    ],
       "service" => {
        "type" => "iis"
    },
         ...[생략]...
}

이전의 _grokparsefailure, _geoip_lookup_failure 경험을 보면 tags에 뭔가 메시지가 있다는 것은 부정적인 의미로 비치는데요, 이에 대해 검색을 해보면,

The tag “beats_input_codec_plain_applied” present in every document in Kibana
; https://stackoverflow.com/questions/61782692/the-tag-beats-input-codec-plain-applied-present-in-every-document-in-kibana

다행히도, Beats 구성 요소가 생성하는 메시지는 전부 저 항목을 포함하고 있다고 합니다. 따라서, (그냥 무시해도 되지만) 이 항목을 (elasticsearch 서버의 디스크 공간을 절약하기 위해) 없애려면 mutate/remove_field로 잘라내거나,

if "beats_input_codec_plain_applied" in [tags] {
    mutate {
        remove_tag => ["beats_input_codec_plain_applied"]
    }
}

아니면, input 단계에서 include_codec_tag 옵션을 추가할 수 있습니다.

input {
    beats {
        port => "5044"
        include_codec_tag => false
    }
}




참고로, filebeat 실행 시 다음과 같은 식의 오류가 발생한다면?

C:\beat\filebeat> filebeat.exe
Exiting: Failed to start crawler: creating module reloader failed: 1 error: invalid config: yaml: line 11: found unknown escape character
loading configs
github.com/elastic/beats/v7/libbeat/cfgfile.(*Reloader).Check
        /go/src/github.com/elastic/beats/libbeat/cfgfile/reload.go:143
github.com/elastic/beats/v7/filebeat/beater.(*crawler).Start
        /go/src/github.com/elastic/beats/filebeat/beater/crawler.go:91
github.com/elastic/beats/v7/filebeat/beater.(*Filebeat).Run
        /go/src/github.com/elastic/beats/filebeat/beater/filebeat.go:438
github.com/elastic/beats/v7/libbeat/cmd/instance.(*Beat).launch
        /go/src/github.com/elastic/beats/libbeat/cmd/instance/beat.go:456
github.com/elastic/beats/v7/libbeat/cmd/instance.Run.func1
        /go/src/github.com/elastic/beats/libbeat/cmd/instance/beat.go:189
github.com/elastic/beats/v7/libbeat/cmd/instance.Run
        /go/src/github.com/elastic/beats/libbeat/cmd/instance/beat.go:190
github.com/elastic/beats/v7/libbeat/cmd.genRunCmd.func1
        /go/src/github.com/elastic/beats/libbeat/cmd/run.go:36
github.com/spf13/cobra.(*Command).execute
        /go/pkg/mod/github.com/spf13/cobra@v0.0.3/command.go:766
github.com/spf13/cobra.(*Command).ExecuteC
        /go/pkg/mod/github.com/spf13/cobra@v0.0.3/command.go:852
github.com/spf13/cobra.(*Command).Execute
        /go/pkg/mod/github.com/spf13/cobra@v0.0.3/command.go:800
main.main
        /go/src/github.com/elastic/beats/x-pack/filebeat/main.go:22
runtime.main
        /usr/local/go/src/runtime/proc.go:203
runtime.goexit
        /usr/local/go/src/runtime/asm_amd64.s:1373

filebeat.yml이나 각 module의 yml 설정에서 파일 경로에 대한 구분자로 단일 '\' 문자를 사용했는지 확인해 봅니다.

var.paths: [ "C:\inetpub\logs\LogFiles\*\*.log" ]

저렇게 하면 escape 문자로 취급하기 때문에 반드시 2개 연속으로 디렉터리 구분자를 사용해야 합니다.

var.paths: [ "C:\\inetpub\\logs\\LogFiles\\*\\*.log" ]

또는, *nix 식 구분자를 사용하거나.

var.paths: [ "C:/inetpub/logs/LogFiles/*/*.log" ]




마지막으로, 혹시 docker나 k8s에 대한 Beats의 활용이 궁금하신 분은 다음의 영상 강좌를 참고해 보는 것도 좋겠습니다.

Beats 및 Elasticsearch를 이용한 Docker & Kubernetes 로그 수집 및 모니터링
; https://www.elastic.co/kr/webinars/elasticsearch-log-collection-with-kubernetes-docker-and-containers/?view=1





[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 9/8/2020]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 



2020-09-09 11시22분
참고로, FileBeat를 NT 서비스로 구동하고 싶다거나 한다면?

cd "C:\Program Files\Filebeat"
.\install-service-filebeat.ps1
정성태
2020-09-10 10시23분
Filebeat로 Logstash를 경유해 Elasticsearch에 저장하는 경우 인덱스 이름이 Logstash-...로 시작하지만, Logstash를 경유하지 않으면 "filebeat-..."가 됩니다.
정성태

... 76  [77]  78  79  80  81  82  83  84  85  86  87  88  89  90  ...
NoWriterDateCnt.TitleFile(s)
11727정성태10/8/201814113오류 유형: 491. Visual Studio의 리눅스 SSH 원격 연결 - "Connectivity Failure. Please make sure host name and port number are correct."
11726정성태10/7/201816403사물인터넷: 49. 라즈베리 파이를 이용해 원격 컴퓨터의 전원 스위치 제어파일 다운로드1
11724정성태10/5/201815196개발 환경 구성: 407. 유니코드와 한글 - "Hangul Compatibility Jamo"파일 다운로드1
11723정성태10/4/201811754개발 환경 구성: 406. "Docker for Windows" 컨테이너 내의 .NET Core 응용 프로그램에서 직렬 포트(Serial Port, COM Port) 사용 방법
11722정성태10/4/201813611.NET Framework: 798. C# - Hyper-V 가상 머신의 직렬 포트와 연결된 Named Pipe 간의 통신파일 다운로드1
11721정성태10/4/201814311.NET Framework: 797. Linux 환경의 .NET Core 응용 프로그램에서 직렬 포트(Serial Port, COM Port) 사용 방법파일 다운로드1
11720정성태10/4/201815545개발 환경 구성: 405. Hyper-V 가상 머신에서 직렬 포트(Serial Port, COM Port) 사용
11719정성태10/4/201816583.NET Framework: 796. C# - 인증서를 윈도우에 설치하는 방법
11718정성태10/4/201811817개발 환경 구성: 404. (opkg가 설치된) Synology NAS(DS216+II)에 cmake 설치
11717정성태10/3/201814088사물인터넷: 48. 넷두이노의 C# 네트워크 프로그램 [1]
11716정성태10/3/201814685사물인터넷: 47. Raspberry PI Zero (W)에 FTDI 장치 연결 후 C/C++로 DTR 제어파일 다운로드1
11715정성태10/3/201814259사물인터넷: 46. Raspberry PI Zero (W)에 docker 설치
11714정성태10/2/201813025사물인터넷: 45. Raspberry PI에 ping을 hostname으로 하는 방법
11713정성태10/2/201815726개발 환경 구성: 403. Synology NAS(DS216+II)에 docker 설치 후 .NET Core 2.1 응용 프로그램 실행하는 방법
11712정성태10/2/201820331.NET Framework: 795. C# - 폰트 목록을 한글이 아닌 영문으로 구하는 방법 [3]
11711정성태10/2/201816103오류 유형: 490. 윈도우 라이선스 키 입력 오류 0xc004f050, 0xc004e028
11710정성태10/2/201814574.NET Framework: 794. C# - 같은 모양, 다른 값의 한글 자음을 비교하는 호환 분해 [5]
11709정성태9/30/201812810개발 환경 구성: 402. .NET Core 콘솔 응용 프로그램을 docker로 실행/디버깅하는 방법 [1]
11708정성태9/30/201814958개발 환경 구성: 401. .NET Core 콘솔 응용 프로그램을 배포(publish) 시 docker image 자동 생성 [2]파일 다운로드1
11707정성태9/30/201816732오류 유형: 489. ASP.NET Core를 docker에서 실행 시 "Failed with a critical error." 오류 발생 [1]
11706정성태9/29/201813630개발 환경 구성: 400. Synology NAS(DS216+II)에서 실행한 gcc의 Segmentation fault [2]
11705정성태9/29/201814393개발 환경 구성: 399. Synology NAS(DS216+II)에 gcc 컴파일러 설치
11704정성태9/29/201817489기타: 73. Synology NAS 신호음(beep) 끄기 [1]파일 다운로드1
11703정성태9/27/201813511개발 환경 구성: 398. Blazor 환경 구성 후 빌드 속도가 너무 느리다면? [2]
11702정성태9/26/201810949사물인터넷: 44. 넷두이노(Netduino)의 네트워크 설정 방법
11701정성태9/26/201815608개발 환경 구성: 397. 공유기를 일반 허브로 활용하는 방법파일 다운로드1
... 76  [77]  78  79  80  81  82  83  84  85  86  87  88  89  90  ...