728x90
반응형

개요

  • ELK에서 공식적으로 지원하는 Alerting 기능은 X-PACK을 구입하여야 사용 가능한 기능입니다.
  • Yelp에서 개발한 오픈소스 라이브러리로, ElasticSearch의 데이터 패턴에 대한 알림을 설정할 수 있다. 다양한 커스터마이징을 제공함

 

설치 방법

1. 파이썬과 필요한 패키지를 설치 합니다.

 

# 파이썬 설치
yum install python3
 
# pip 설치
yum install python-pip
 
# 위에 방법으로 설치가 안될 때 진행
1. curl -O https://bootstrap.pypa.io/get-pip.py
2, python3 get-pip.py --user
 
# ciff 설치 (1.11.5 이상 필요)
yum install pyhon-ciff*
 
# 파이썬 Develop 설치 파이썬과 같은 버전으로 설치 진행
yum install python-devel3*
 
# 관련 패키지 설치
pip install "setuptools>=11.3" python setup.py install
 
# ElastAlert 설치
pip install elastalert

 

2. 설치 기본 경로로 이동

cd /usr/local/lib/python3.6/site-packages/elastalert

 

3. ElastAlert 관련 Yaml 설정

  • config.yaml 과 rule.yaml을 설정 해야 합니다.

config.yaml 주요 옵션
rules_folder : config.yaml 파일의 경로 기준으로 rule 파일들이 위치한 폴더
run_every : 알람의 주기를 설정하는 옵션, python 문법으로 timedelta 옵션에 쓸수있는 값들을 넣으면된다. days, seconds, microseconds, milliseconds, minutes, hours, weeks
buffer_time : 일부 로그소스가 실시간이 아닌 경우 결과를 버퍼링할 최근기간
es_host : elasticsearch 호스트
es_port : elasticsearch 포트

writeback_index : 메타데이터 저장에 사용하는 index, 해당 인덱스는 사용자가 직접 만들어줘야 하는듯하다.
alert_time_limit : 알람 실패시 재시도할 주기

728x90
# config.yaml 
 
# This is the folder that contains the rule yaml files
# Any .yaml file will be loaded as a rule
rules_folder: /usr/local/lib/python3.6/site-packages/elastalert/alertScript/
 
# How often ElastAlert will query Elasticsearch
# The unit can be anything from weeks to seconds
run_every:
  minutes: 5
 
# ElastAlert will buffer results from the most recent
# period of time, in case some log sources are not in real time
buffer_time:
  minutes: 15
 
# The Elasticsearch hostname for metadata writeback
# Note that every rule can have its own Elasticsearch host
es_host: syf-es-0.cocone
 
# The Elasticsearch port
es_port: 9200
 
# The AWS region to use. Set this when using AWS-managed elasticsearch
#aws_region: us-east-1
 
# The AWS profile to use. Use this if you are using an aws-cli profile.
# See http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html
# for details
#profile: test
 
# Optional URL prefix for Elasticsearch
#es_url_prefix: elasticsearch
 
# Connect with TLS to Elasticsearch
#use_ssl: True
 
# Verify TLS certificates
#verify_certs: True
 
# GET request with body is the default option for Elasticsearch.
# If it fails for some reason, you can pass 'GET', 'POST' or 'source'.
# See http://elasticsearch-py.readthedocs.io/en/master/connection.html?highlight=send_get_body_as#transport
# for details
#es_send_get_body_as: GET
 
# Option basic-auth username and password for Elasticsearch
#es_username: someusername
#es_password: somepassword
 
# Use SSL authentication with client certificates client_cert must be
# a pem file containing both cert and key for client
#verify_certs: True
#ca_certs: /path/to/cacert.pem
#client_cert: /path/to/client_cert.pem
#client_key: /path/to/client_key.key
 
# The index on es_host which is used for metadata storage
# This can be a unmapped index, but it is recommended that you run
# elastalert-create-index to set a mapping
writeback_index: elastalert_status
writeback_alias: elastalert_alerts
 
# If an alert fails for some reason, ElastAlert will retry
# sending the alert until this time period has elapsed
alert_time_limit:
  days: 1
 
# Custom logging configuration
# If you want to setup your own logging configuration to log into
# files as well or to Logstash and/or modify log levels, use
# the configuration below and adjust to your needs.
# Note: if you run ElastAlert with --verbose/--debug, the log level of
# the "elastalert" logger is changed to INFO, if not already INFO/DEBUG.
#logging:
#  version: 1
#  incremental: false
#  disable_existing_loggers: false
#  formatters:
#    logline:
#      format: '%(asctime)s %(levelname)+8s %(name)+20s %(message)s'
#
#    handlers:
#      console:
#        class: logging.StreamHandler
#        formatter: logline
#        level: DEBUG
#        stream: ext://sys.stderr
#
#      file:
#        class : logging.FileHandler
#        formatter: logline
#        level: DEBUG
#        filename: elastalert.log
#
#    loggers:
#      elastalert:
#        level: WARN
#        handlers: []
#        propagate: true
#
#      elasticsearch:
#        level: WARN
#        handlers: []
#        propagate: true
#
#      elasticsearch.trace:
#        level: WARN
#        handlers: []
#        propagate: true
#
#      '':  # root logger
#        level: WARN
#          handlers:
#            - console
#            - file
#        propagate: false

 

 

4. rule.yaml 설정

  • name : rule이름, 고유한 이름이므로 중복되어선 안된다.
  • type : 알람의 타입, 예제 파일 내용인 frequency 일때는 timeframe, num_events 옵션을 사용한다.
  • index : 해당 rule이 탐색할 elasticsearch의 인덱스
  • num_events : 정해진 time_frame 시간동안 일정 횟수이상 document 매치시 알람 발생.
  • timeframe : num_events 카운트를측정할 시간 단위
  • filter : 인덱스에서 매칭시킬 조건.
    • query_string : 루씬 쿼리 포맷을 사용하는 방식
    • filter: - query: query_string: query: "username: bob" - query: query_string: query: "_type: login_logs" - query: query_string: query: "field: value OR otherfield: othervalue" - query: query_string: query: "this: that AND these: those"
    • term : 지정한 필드에 매치할 값을 지정하는 방식
    • filter: - term: name_field: "bob" - term: _type: "login_logs"
    • terms : term과 같은 개념인데 매칭시킬 값을 여러개로 할수있다. (배열식)
    • filter: - terms: field: ["value1", "value2"] # value1 OR value2 - terms: fieldX: ["value1", "value2"] fieldY: ["something", "something_else"] fieldZ: ["foo", "bar", "baz"]
    • wildcard : * 문자를 사용하여 유사값을 매칭 시킬수있는 방식
    • filter: - query: wildcard: field: "foo*bar"
    • range : 숫자형식 필드에 대해 범위를 지정하는 방식
    • filter: - range: status_code: from: 500 to: 599
    • Negation, and, or : Elasticsearch 2.x 버전에서 사용되는 방식이었으나 5.x버전 이상부터는 작동되지 않고 query_string 방식을 사용한다.
# rule.yaml
 
 
# Alert when the rate of events exceeds a threshold
 
# (Optional)
# Elasticsearch host
es_host: test-es
 
# (Optional)
# Elasticsearch port
es_port: 9200
 
# (OptionaL) Connect with SSL to Elasticsearch
#use_ssl: True
 
# (Optional) basic-auth username and password for Elasticsearch
#es_username: someusername
#es_password: somepassword
 
# (Required)
# Rule name, must be unique
name: DigDag Alert Rule
 
# (Required)
# Type of alert.
# the frequency rule type alerts when num_events events occur with timeframe time
type: frequency
 
# (Required)
# Index to search, wildcard supported
index: digdag*
 
# (Required, frequency specific)
# Alert when this many documents matching the query occur within a timeframe
num_events: 1
 
# (Required, frequency specific)
# num_events must occur within this amount of time to trigger an alert
timeframe:
#  hours: 1
  seconds: 10
 
alert_text_args: ["errMsg", "path"]
alert_text: "errMsg: {0}\n\n\npath: {1}"
alert_text_type: alert_text_only

# minutes : 0분으로 하면 놓치는 얼럿 없이 다 보냄 
realert:
  minutes: 0
  
# (Required)
# A list of Elasticsearch filters used for find events
# These filters are joined with AND and nested in a filtered query
# For more info: http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl.html
filter:
- query:
    query_string:
      query: "*"
 
# (Required)
# The alert is use when a match is found
alert:
- "slack"
slack:
slack_webhook_url: "https://hooks.slack.com/services/T02BEABAP/test/asd123"
#slack_webhook_url: "https://hooks.slack.com/services/T02BEABAP/teast/asd123"
slack_username_override: "ErrAlert-Bot"
slack_channel_override: "notification"
#slack_channel_override: "testchannel1"
slack_emoji_override: ":stest:"
#slack_msg_color: "danger"

 

5. 모든 설정이 끝났다면 커맨드 실행

nohup elastalert --verbose --start NOW --config /usr/local/elastalert/alertScript/config.yaml --rule /usr/local/elastalert/alertScript/rule.yaml &
728x90
300x250
728x90
반응형

Index Template에 ILM 정책에 대한 rollover alias 지정 (legacy index template 용이 아님)

PUT _index_template/app_log
{
  "template": {
    "settings": {
      "index": {
        "lifecycle": {
          "name": "testILM",
          "rollover_alias": "test-alias"
        }
      }
    }
  },
  "index_patterns": [
    "app_log*"
  ],
  "composed_of": []
}

geo_point 추가

POST /_template/access
{
  "mappings": {
    "properties": {
      "geoip": {
        "dynamic": true,
        "type": "object",
        "properties": {
          "location": {
            "type": "geo_point"
          },
          "latitude":{
            "type": "float"
          },
          "longitude":{
            "type": "float"
          }
        }
      }
    }
 },
  "aliases": {}

}


PUT access
{
  "mappings": {
    "properties": {
      "location": {
        "type": "geo_point"
      }
    }
  }
}

인덱스의 쌓인 Document 수 확인

GET /app_log/_count
{
  "query" : {
    "term": { "@timestamp" : "2021-03-09" } /* 하루 쌓이는 document 양 */
  }
}

기존 인덱스에 매핑 등록

PUT sre-www-2023.05
{
  "mappings": {
    "s.type": {
      "full_name": "s.type",
      "mapping": {
        "type": {
          "type": "keyword"
        }
      }
    }
  }
}

새로운 인덱스 생성 및 매핑 등록

PUT sre-www-2023.05-backup
{
  "mappings": {
    "properties": {
      "s.type": {
        "type": "keyword"
      }
    }
  }
}

인덱스의 매핑 필드 정보 보기

GET sre-*/_mapping/field/s.type

인덱스 삭제

DELETE sre-www-2023.05-backup

Reindex 하기

POST /_reindex?wait_for_completion=false
{
  "source": {
    "index": "sre-www-2023.05"
  },
  "dest": {
    "index": "sre-www-2023.05-backup"
  }
}

진행 Task 결과 보기

GET /_tasks

GET /_tasks/H-hNeNJFSCq0J1WPJocVeg:2335496579

POST /_tasks/H-hNeNJFSCq0J1WPJocVeg:2335882225/_cancel

매핑 정보 안들가 있는 인덱스에 넣기

PUT sre-www-2023.02/_mapping
{
  "properties": {
    "s.type": {
      "type": "keyword"
    }
  }
}

기존에 없는 Field 삽입

POST sre-www-2023.02/_update_by_query?conflicts=proceed
{
  "script": {
    "lang": "painless",
    "source": """
      if (ctx._source.s.domain == 'abc.co.kr' || ctx._source.s.domain == 'www.abc.co.kr') {
        ctx._source['s.type'] = 'abc PC';
      } else if(ctx._source.s.domain == 'm.abc.co.kr' || ctx._source.s.domain == 'brandapp-m.abc.co.kr') {
        ctx._source['s.type'] = 'abc 모바일';
      }
    """
  },
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "s.domain": "abc.co.kr"
          }
        },
        {
          "term": {
            "s.domain": "www.abc.co.kr"
          }
        },
        {
          "term": {
            "s.domain": "m.abc.co.kr"
          }
        },
        {
          "term": {
            "s.domain": "brandapp-m.abc.co.kr"
          }
        }
      ]
    }
  }
}

기존에 field의 type이 맞지 않게 들어갔거나 field 나중에 추가된 경우 이전에 것도 Aggreation 하려면 필요한 절차들 이다

728x90
300x250
728x90
반응형
  • Kibana Dashboard 사용시 Index Pattern Id를 변경 해야 할 때,

 

Index Pattern ID 검색

GET .kibana/_search
{
  "_source": ["index-pattern.title"],
  "query": {
    "term": {
      "type": "index-pattern"
    }
  }
}

 

원하는 Visualize 에서 Inspect 한다. 그런 후

# 레퍼런스에 아래 내용 기입
# id: 는 변경 할 Index Pattern ID
[
  { "name": "kibanaSavedObjectMeta.searchSourceJSON.index",
    "type": "index-pattern", "id": "8e2f3600-87d3-11eb-86dd-f13a798c7e8e"
    },
  { "name": "kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index",
    "type": "index-pattern", "id": "8e2f3600-87d3-11eb-86dd-f13a798c7e8e"
  }
]
728x90
300x250
728x90
반응형

workflow

 : input(로그 입력) → filter(로그 가공) → output (로그 출력)

 : Filebeat를 통해 input을 하며, Logstash에서 가공하고, Elasticsearch에서 받고 Kibana로 출력하는 흐름

 

수집로그

  : 수집하는 로그는 다음과 같다

  : Nginx(Access, Error), OS(auth, message), MongoDB (Slowquery)

 

logstash 폴더 구조

➜  logstash ls -ltr
total 526032
-rw-r--r--  1 park_hyungkyu  admin       2019  1 29 12:26 jvm.options
-rw-r--r--  1 park_hyungkyu  admin       9097  1 29 12:26 log4j2.properties
-rw-r--r--  1 park_hyungkyu  admin        342  1 29 12:26 logstash-sample.conf
-rw-r--r--  1 park_hyungkyu  admin       1696  1 29 12:26 startup.options
-rw-r--r--  1 park_hyungkyu  admin  267069440  2  1 10:25 core.alpha.tar
-rw-r--r--  1 park_hyungkyu  admin       1763  2  1 18:06 logstash.conf_fail
-rw-r--r--  1 park_hyungkyu  admin       2494  2  2 11:14 logstash.conf.org
-rw-r--r--  1 park_hyungkyu  admin       3697  2  2 11:34 pipelines.yml.org
-rw-r--r--  1 park_hyungkyu  admin      11250  2  2 12:49 logstash.yml
-rw-r--r--  1 park_hyungkyu  admin        259  2  2 12:54 pipelines.yml
-rw-------  1 root           admin      86198  2  2 12:55 nohup.out
drwxr-xr-x  5 park_hyungkyu  admin        160  2  2 15:08 conf.d

- 기본적으로 logstash 명령어 실행 시 아무 옵션 주지 않았을 때, pipelines.yml을 읽는다.

- logstash.yml 파일은 pipeline에 대한 공통된 튜닝 옵션을 제공한다. pipelines.yml에서 별도 옵션을 주지 않으면 기본적으로 logstash.yml에 등록된 옵션을 사용한다.

- conf.d 폴더는 임의로 생성하였으며, 각 로그수집의 설정값을 저장한다.

 

pipelins.yml

➜  logstash cat pipelines.yml
- pipeline.id: aplogs
  path.config: "/etc/logstash/conf.d/aplogs.conf"

 

logstash.yml

➜  logstash cat logstash.yml
path.data: /var/lib/logstash
pipeline.workers: 2
pipeline.batch.size: 125
pipeline.batch.delay: 50
pipeline.unsafe_shutdown: false
pipeline.ordered: auto
config.reload.automatic: true
config.reload.interval: 60s
http.enabled: true
http.port: 9600
dead_letter_queue.enable: false
 
dead_letter_queue.max_bytes: 1024mb
 
 
path.logs: /var/log/logstash

 

Logstash 의 config 파일

 

conf.d/nginx.conf

input {
  beats {
    port => 5044
    host => "0.0.0.0"
    include_codec_tag => false
  }
}
filter {
    if "access" in [tags] {
      grok {
        match => { "message" => ["%{IPORHOST:[nginx][access][remote_addr]}, %{IPORHOST:[nginx][access][lb_addr]} - %{USERNAME:[nginx][access][remote_user]} \[%{HTTPDATE:[nginx][access][time_local]} T:%{DATA:[nginx][access][request_time]}\] \"%{WORD:[nginx][access][request]} %{DATA:[nginx][access][url]} HTTP/%{NUMBER:[nginx][access][http_version]}\" %{INT:[nginx][access][status]} %{NUMBER:[nginx][access][body_bytes_sent]} \"%{DATA:[nginx][access][http_referer]}\" \"%{DATA:[nginx][access][http_accept_encoding]}\" \"%{DATA:[nginx][access][sent_http_content_encoding]}\" \"%{DATA:[nginx][access][http_user_agent]}\" \"%{DATA:[nginx][access][sent_http_content_type]}\" \"%{DATA:[nginx][access][http_ca_http_header]}\""] }
        remove_field => "message"
      }
      mutate {
        add_field => { "read_timestamp" => "%{@timestamp}" }
        convert => {
         "[nginx][access][http][version]" => "float"
         "[nginx][access][user_agent][magor]" => "integer"
         "[nginx][access][body_bytes_sent]" => "integer"
         "[nginx][access][user_agent][minor]" => "integer"
         "[nginx][access][request_time]" => "float"
        }
      }
      date {
        match => [ "[nginx][access][time]", "dd/MMM/YYYY:H:m:s Z" ]
        remove_field => "[nginx][access][time]"
      }
      useragent {
        source => "[nginx][access][http_user_agent]"
        target => "[nginx][access][user_agent]"
        remove_field => "[nginx][access][http_user_agent]"
      }
      geoip {
        source => "[nginx][access][remote_addr]"
        #target => "[nginx][access][geoip]"
      }
      mutate {
        remove_field => "[geoip][timezone]"
        remove_field => "[geoip][contry_code2]"
        remove_field => "[geoip][contry_code3]"
        remove_field => "[geoip][contry_name]"
        remove_field => "[geoip][continent_code]"
      }
      if "_grokparsefailure" in [tags] {
           drop { }
       }
    }
    else if "error" in [tags] {
      grok {
        #match => { "message" => ["%{DATA:[nginx][error][time]} \[%{DATA:[nginx][error][level]}\] %{NUMBER:[nginx][error][pid]}#%{NUMBER:[nginx][error][tid]}: (\*%{NUMBER:[nginx][error][connection_id]} )?%{GREEDYDATA:[nginx][error][message]}"] }
        match => { "message" => ["(?<[nginx][error][time_local]>%{YEAR}[./-]%{MONTHNUM}[./-]%{MONTHDAY}[- ]%{TIME}) \[%{LOGLEVEL:[nginx][error][severity]}\] %{POSINT:[nginx][error][pid]}#%{NUMBER:[nginx][error][tid]}: (\*%{NUMBER:[nginx][error][connection_id]} )%{GREEDYDATA:[nginx][error][message]}(?:, client: (?<[nginx][error][clientip]>%{IP}|%{HOSTNAME}))(?:, server: %{IPORHOST:[nginx][error][server]}?)(?:, request: %{QS:[nginx][error][request]})?(?:, upstream: (?<[nginx][error][upstream]>\"%{URI}\"|%{QS}))?(?:, host: %{QS:[nginx][error][request_host]})?(?:, referrer: \"%{URI:[nginx][error][referrer]}\")?"] }
        remove_field => "message"
      }
      mutate {
        rename => { "@timestamp" => "read_timestamp" }
        convert => {
          "[nginx][error][pid]" => "integer"
          "[nginx][error][tid]" => "integer"
          "[nginx][error][connection_id]" => "integer"
 
        }
      }
      #date {
      #  match => [ "[nginx][error][time]", "YYYY/MM/dd H:m:s" ]
      #  remove_field => "[nginx][error][time]"
      #}
    }
    else if "app_log" in [tags] {
        mutate {
          gsub => [ "message", "\\n\\s\\s\\s\\s\\s\\s\\s\\s|\\n\\s\\s", "\\s" ]
       }
        grok {
          match => { "message" => ["(?<timestamp>^.{23})\s(?<class>[^ ]*)\s(?<loglevel>.[^.]*)\s(?<location>.[^ ]*)\s-\s(?<description>(.|\n^.{23})+)"] }
          remove_field => "message"
       }
        if "_grokparsefailure" in [tags] {
          drop { }
       }
    }
    else if "auth" in [tags] {
      grok {
        match => { "message" => ["%{SYSLOGTIMESTAMP:system.auth.timestamp.} %{SYSLOGHOST:[system][auth][hostname]} sshd(?:\[%{POSINT:[system][auth][pid]}\])?: %{DATA:[system][auth][ssh][event]} %{DATA:[system][auth][ssh][method]} for (invalid user )?%{DATA:[system][auth][user]} from %{IPORHOST:[system][auth][ssh][ip]} port %{NUMBER:[system][auth][ssh][port]} ssh2(: %{GREEDYDATA:[system][auth][ssh][signature]})?"] }
        pattern_definitions => {
          "GREEDYMULTILINE"=> "(.|\n)*"
        }
      }
      date {
        match => [ "time_local", "UNIX" ]
      }
      geoip {
        source => "[system][auth][ssh][ip]"
        #target => "[system][auth][ssh][geoip]"
      }
    }
    else if "syslog" in [tags] {
      grok {
        match => { "message" => ["%{SYSLOGTIMESTAMP:[system][syslog][timestamp]} %{SYSLOGHOST:[system][syslog][hostname]} %{DATA:[system][syslog][program]}(?:\[%{POSINT:[system][syslog][pid]}\])?: %{GREEDYMULTILINE:[system][syslog][message]}"] }
        pattern_definitions => { "GREEDYMULTILINE" => "(.|\n)*" }
        remove_field => "message"
      }
      date {
        match => [ "time_local", "UNIX" ]
      }
    }
    else if "mongo" in [tags] {
      grok {
        match => { "message" => ["(?<timestamp>^.{23})Z\s(?<serverity>[^ ]*)\s(?<component>[^ ]+)\s\s(?<context>[^ ]+)\s(?<process>[^ ]+)\s(?<DB>[^ ]+)\scommand:\s(?<query>[^ ]+)\s(?<total>[^ ].+)\s(?<planSummary>planSummary.+)protocol:op_msg\s(?<op_msg>.+)ms"] }
        remove_field => "message"
        }
      if "_grokparsefailure" in [tags] {
           drop { }
       }
      mutate {
        #remove_field => "total"
        convert => {
         "op_msg" => "integer"
        }
      }
    }
    else if "digdag_log" in [tags] {
      grok {
        match => { "message" => ["(?<path>[^ ]+):(?<errMsg>[^*]+)"] }
        remove_field => "message"
        }
      if "_grokparsefailure" in [tags] {
           drop { }
       }
    }
}
 
output {
  if "access" in [tags] {
    elasticsearch {
        hosts => ["test:9200"]
        manage_template => false
        index => "access-%{+yyyy.MM.dd}"
        ecs_compatibility => disabled
        }
    }
   else if "error" in [tags] {
    elasticsearch {
        hosts => ["test:9200"]
        manage_template => false
        index => "error-%{+yyyy.MM.dd}"
        ecs_compatibility => disabled
        }
    }
    else if "app_log" in [tags] {
    elasticsearch {
        hosts => ["test:9200"]
        manage_template => false
        index => "app_log-%{+yyyy.MM.dd}"
        ecs_compatibility => disabled
        }
    }
   else if "auth" in [tags] {
    elasticsearch {
        hosts => ["test:9200"]
        manage_template => false
        ecs_compatibility => disabled
        index => "auth-%{+yyyy.MM.dd}"
        }
    }
   else if "syslog" in [tags] {
    elasticsearch {
        hosts => ["test:9200"]
        manage_template => false
        index => "syslog-%{+yyyy.MM.dd}"
        ecs_compatibility => disabled
        }
    }
   else if "mongo" in [tags] {
    elasticsearch {
        hosts => ["test:9200"]
        manage_template => false
        index => "mongo-%{+yyyy.MM.dd}"
        ecs_compatibility => disabled
        }
    }
   else if "digdag_log" in [tags] {
    elasticsearch {
        hosts => ["test:9200"]
        manage_template => false
        index => "digdag-%{+yyyy.MM.dd}"
        ecs_compatibility => disabled
        }
    }
}

Nginx Access Log와 Error Log, System log, MongoDb SlowQuery, DigDag Log 에 대해 filter grok pattern/regex 사용하여 파싱

 

filebeat 설치

  • filebeat.yml 파일로 filebeat를 설정하고, modules.d에서 모듈 관리 각 로그에 대한 모듈를 저장/관리
-- 다운로드 및 설치
wget https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.9.2-x86_64.rpm
rpm -ivh filebeat-7.9.2-x86_64.rpm
 
-- 설치 확인
rpm -qa | grep filebeat
filebeat-7.9.2-1.x86_64

 

filebeat 설정

# cd /etc/filebeat
 
[root@abcd filebeat]# ls
fields.yml  filebeat.reference.yml  filebeat.yml  modules.d
 
 
# cat filebeat.yml
 
filebeat.inputs:
 - type: log
   enabled: true
   paths:
     - /tmp/test.log
   tags: ["app_log"]
   symlinks: true
   exclude_lines: ["DEBUG|INFO|TRACE|WARN"]
 
 - type: log
   enabled: true
   paths:
     - /var/log/nginx/access.log
   tags: ["access"]
   exclude_lines: [".*l7check.*"]
 
 - type: log
   enabled: true
   paths:
     - /var/log/nginx/error.log
   tags: ["error"]
 
 - type: log
   enabled: true
   paths:
     - /var/log/message*
   tags: ["syslog"]
 
 - type: log
   enabled: true
   paths:
     - /var/log/secure*
   tags: ["auth"]
 
 - type: log
   enabled: true
   paths:
     - /data/mongodb/router/log/mongos.log
   tags: ["mongo"]
 
filebeat.config.modules:
  path: ${path.config}/modules.d/*.yml
  reload.enable: true
 
setup.template.settings:
  index.number_of_shards: 1
 
setup.kibana:
  host: "test:5601"
 
output.logstash:
  hosts: ["test:5044"]
 
#output.elasticsearch:
#  hosts: ["test-es:9200"]
 
processors:
#  - add_host_metadata: ~
#  - add_cloud_metadata: ~
#  - add_docker_metadata: ~
#  - add_kubernetes_metadata: ~
   - drop_fields:
       fields: ["agent.ephemeral_id", "agent.hostname", "agent.id", "agent.type", "agent.version", "ecs.version", "input.type", "log.offset", "version"]
 
logging.level: info
#logging.level: debug
 
 
 
# filebeat 모듈은 선택에 따라 사용하는 것으로 함
 
# filebeat 실행
nohup filebeat -e -c /etc/filebeat/filebeat.yml &

 

728x90
300x250

+ Recent posts