2024년 5월 23일 목요일

엘라스틱 필드 유형 변환

로그스태시는 별도 설정이 없는 한, 숫자를 포함한 모든 데이터를 텍스트로 처리한다.
dissect {
 mapping => {"message" => "%{} %{} %{} %{} %{} %{} %{} %{} %{} %{} %{} %{status} %{}"}
}
{
     "status" => "200",
    "message" => "2011-01-12 20:44:18 192.168.48.11 POST /book/index.asp page=187 80 - 192.168.175.190 Mozilla/5.0+(Windows;+U;+Windows+NT+5.1;+zh-CN;+rv:1.8.1.2) - 200 0 0 0\r"
}

문자와 숫자는 특성이 다르기 때문에 데이터 활용 범위도 달라진다. 숫자의 특성을 활용하려면 텍스트 필드를 숫자 필드로 변환 필요.
dissect {
 mapping => {"message" => "%{} %{} %{} %{} %{} %{} %{} %{} %{} %{} %{} %{status} %{}"}
 convert_datatype => {"status" => "int"}
}
{
     "status" => 200,
    "message" => "2011-01-12 20:44:18 192.168.48.11 POST /book/index.asp page=187 80 - 192.168.175.190 Mozilla/5.0+(Windows;+U;+Windows+NT+5.1;+zh-CN;+rv:1.8.1.2) - 200 0 0 0\r"
}

IP 주소 필드 추출

IP 주소 역시 텍스트로 저장된다. IP 주소의 특성을 활용하기 힘든 환경. 그런데 로그스태시는 숫자 외의 데이터 형변환을 지원하지 않는다.
dissect {
 mapping => {"message" => "%{} %{} %{} %{} %{} %{} %{} %{} %{clientip} %{} %{} %{status} %{}"}
 convert_datatype => {"status" => "int"}
}
{
    "clientip" => "192.168.175.190",
      "status" => 200,
     "message" => "2011-01-12 20:44:18 192.168.48.11 POST /book/index.asp page=187 80 - 192.168.175.190 Mozilla/5.0+(Windows;+U;+Windows+NT+5.1;+zh-CN;+rv:1.8.1.2) - 200 0 0 0\r"
}


원하는 유형 필드를 미리 만들어놔야 함.
PUT _index_template/test
{
  "index_patterns": ["test*"],
  "template": {
    "mappings": {
      "properties": {
        "clientip": {
          "type": "ip"
        }
      }
    }
  }
}

IP 주소를 IP 데이터 유형으로 저장하면 뭐가 좋을까?


무려 대역 검색이 된다!


물론 텍스트 유형이어도 와일드카드 검색을 통해 비슷한 결과를 가져올 수 있지만, IP 유형은 서브넷마스크를 이용한 대역 검색 세분화가 가능하니 환경에 따라 매우 유용한 기능이 될 듯.

참고로 ingest pipeline은 

로그스태시와 똑같이 동작하고, beat는 사전 정의된 필드 템플릿 없으면 모두 텍스트로 저장한다. 일단 사용자 인덱스명 지정 환경.
PUT _index_template/test
{
  "index_patterns": ["test*"], 
  "template": {
    "mappings": {
      "properties": {
        "status": {
          "type": "integer"
        },
        "clientip": {
          "type": "ip"
        }
      }
    }
  }
}
setup.ilm.enabled: false
setup.template.name: "test"
setup.template.pattern: "test*"
output.elasticsearch:
  hosts: ["192.168.56.1:9200"]
  index: "test"

processors:
  - include_fields:
      fields: "message"
  - dissect:
      tokenizer: "%{} %{} %{} %{} %{} %{} %{} %{} %{clientip} %{} %{} %{status} %{}"
      field: "message"
      target_prefix: ""
  - convert:
      fields:
        - {from: "clientip", to: "clientip", type:"ip"}
        - {from: "status", to: "status", type:"integer"}


beat 기본 템플릿을 사용하면 더 쉽게도 가능. ECS 필드 이름을 사용하면 다른 설정 필요 없이 알아서 사전 정의된 데이터 유형으로 저장된다. 빈 껍데기 필드 폭탄은 덤
processors:
  - include_fields:
      fields: "message"
  - dissect:
      tokenizer: "%{} %{} %{} %{} %{} %{} %{} %{} %{client.ip} %{} %{} %{http.response.status_code} %{}"
      field: "message"
      target_prefix: ""


댓글 없음:

댓글 쓰기

크리에이티브 커먼즈 라이선스