Logstash - Mutate filter 사용법

2021. 6. 21. 11:00ELK Stack

Raw data를 다른 프로그램으로 혹은 Local에 내려받기 할때 우리가 원하는 모양으로

가공해 줄 필요가 있다. 이때 이 가공해주는 항목이 Logstash에서 Filter를 이용하는데 

그중 mutate filter를 활용하는 방법에 대하여 알아보자 

공식문서 를 참고하여도 무방하다. 

 

1. Mutate filter 목록 

mutate filter plugin 의 옵션으로는 아래와 같다.

  1. convert
  2. copy
  3. gsub
  4. join
  5. split
  6. lowercase, uppercase
  7. capitalize
  8. merge
  9. coerce
  10. update
  11. replace
  12. strip
  13. rename

1. Convert

--> 해당 필드를 변형한다.

input {
  stdin{
    codec => json
  }
}

filter {
  mutate {
    convert => {
      "field1" => "integer"
      "field2" => "integer_eu"
      "field3" => "float"
      "field4" => "float_eu"
      "field5" => "string"
      "field6" => "boolean"  
    }
  }
}

output {
  stdout{}
}

1) “field1” => “integer”

Convert 실행결과 1

 

2) “field2” => “integer_eu”

Convert 실행결과 2

3) “field3” => “float”

Convert 실행결과 3

4) “field4” => “float_eu”

Convert 실행결과 4

5) “field5” => “string”

Convert 실행결과 5

6) “field6” => “boolean”

Convert 실행결과 6

  • false: 0, 0.0, "0", "0.0", "false", "f", "no", "n"
  • true: 1, 1.0, "1", "1.0", “true”, "t", "yes", "y"

2. Copy

--> 필드 값을 복제한다.

input { ... }

filter {
  mutate {
    copy => {
      "field1" => "field1_copied"
    }
  }
}

output { ... }

input / output

Copy 실행결과

3. gsub

정규식으로 일치하는 항목을 다른 문자열로 대체 

input { ... }

filter {
  mutate {
    gsub => [
      "field1", "/", "_",
      "field2", "[\\?#-]", "."
    ]
  }
}

output { ... }

input / output

gsub 실행 결과

  • field1: / --> _
  • field2: ?, #, - --> .

4. join

배열을 하나의 문자로 합친다. 

input { ... }

filter {
   mutate {
     join => { "field1" => "," }
   }
 }

output { ... }

input / output

join 실행결과

5. Split

하나의 문자를 배열로 쪼갠다. 

input { ... }

filter {
  mutate {
    split => { "field1" => "," }
  }
}

output { ... }

input / output

Split 실행결과

구분자가 해당 필드에 존재하지 않는 경우에도 필드는 배열로 바뀌는 것을 알 수 있다.

join 옵션과 반대 개념이다.

 

6. Lowercase, Uppercase

소문자 변경(Lowercase), 대문자 변경(Uppercase)

input { ... }

filter {
  mutate {
    lowercase => [ "field1", "field3" ]
    uppercase => [ "field4" ]
  }
}

output { ... }

input / output

lowercase/uppercase 결과

7. Capitalize

첫 글자를 대문자화, 이외는 소문자화 한다.

input { ... }

filter {
  mutate {
    capitalize => [ "field1" ]
  }
}

output { ... }

input / output

capitalize 실행 결과

8. Merge

해당 필드 값들을 다른 필드에 포함시킨다.

input { ... }

filter {
  mutate {
    merge => { "field2" => "field1" }
  }
}

output { ... }

input / output

merge 실행 결과

  • "banana" + ["apple", "melon"] => ["apple", "melon", "banana"]
  • ["banana", "mango"] + ["apple", "melon"] => ["apple", "melon", "banana", "mango"]
  • "banana" + "apple" => ["banana", "apple"]
  • ["banana", "mango"] + “apple” => ["apple", "banana", "mango"]

9. Coerce

필드 값이 null인 경우에 기본값을 넣어준다.

input { ... }

filter {
  mutate {
    coerce => { "field2" => "empty" }
  }
}

output { ... }

input / output

coerce 실행 결과

단, input에 해당 필드가 key로 존재하지 않는 경우에는 기본값을 넣지 않는다. ( null 값이 있는 경우에는 대체 함.)

ex. input이 { "username": "bactoria" } 인 경우 field1 필드가 생성되지 않음.

 

10. Update

해당 필드의 값을 특정값으로 대체한다. 

input { ... }

filter {
  mutate {
    update => { "message" => "%{source_host}: My new message" }
  }
}

output { ... }

input / output

Update 실행 결과

input에서 message 필드가 들어오지 않는 경우 message 필드를 생성하지 않는다. (replace옵션은 필드를 생성함)

ex) input이 { } , { "source_host": "54.17.150.184" } 인 경우 field1 필드가 생성되지 않았다.

11. Replace

해당 필드의 값을 특정값으로 대체한다. 

input { ... }

filter {
  mutate {
    replace => { "message" => "%{source_host}: My new message" }
  }
}

output { ... }

input / output

replace 실행 결과

input에서 message 필드가 들어오지 않는 경우 message 필드를 생성하여 대체한다. (update옵션은 생성하지 않음)

ex) input이 { } , { "source_host": "54.17.150.184" }인 경우 message 필드가 대체되었다.

12. Strip

좌우 공백을 제거한다. 

input { ... }

filter {
  mutate {
      strip => ["searchKeyword", "username"]
  }
}

output { ... }

input / output

Strip 실행 결과

trim() 함수와 같은 기능이다.

참고로 단어 사이의 공백은 제거되지 않는다. ex) 박토리 아

13. Rename

해당 필드의 이름을 변경한다.

input { ... }

filter {
  mutate {
    rename => { "HOSTORIP" => "client_ip" }
  }
}

output { ... }

input / output

rename 실행 결과

2. 옵션의 실행 순서

Mutate 옵션은 내부 함수들이 실행되는 순서가 있다. 

input { ... }

filter {
  mutate {
    copy => {
      "field" => "field_copied"
    }
    uppercase => [ "field" ]
  }
}

output { ... }

input / output

 

위의 결과는 순차적으로 처리된다면 { "field": "ABCD", "field_copied": "abcd" } 일 것이다.

공교롭게도 결과는 { "field": "ABCD", "field_copied": "ABCD" } 이다.

 

그 이유는 옵션 별로 실행 순서가 정해져 있어 uppercase 옵션 실행 이후에 copy 옵션이 실행되기 때문이다.

실행 순서에 대해서는 공식문서에 나와있다.

 

만약 copy 옵션을 먼저 실행하고자 한다면 어떻게 해야 할까?

아래와 같이 mutation을 따로 선언해주면 copy 옵션 실행 이후에 uppercase 옵션이 실행된다.

 

input { ... }

filter {
  mutate {
    copy => {
      "field" => "field_copied"
    }
  }
  mutate {
    uppercase => [ "field" ]
  }
}

output { ... }

input / output

 

참고 자료 : https://bactoria.github.io/2020/04/12/%EB%A1%9C%EA%B7%B8%EC%8A%A4%ED%83%9C%EC%8B%9C-mutate-filter-plugin-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0/

'ELK Stack' 카테고리의 다른 글

Logstash - Input Kafka  (0) 2021.07.09
Logstash - Output Kafka  (0) 2021.07.09