본문 바로가기
WIKI 기술 지식 베이스

파싱 (Parsing)

원문 보기 위키 갱신

Datadog는 JSON 형식 로그를 자동으로 파싱해요. 그 외 형식은 Grok Parser를 사용해 로그를 보강할 수 있어요. Grok 문법은 순수 정규식보다 로그를 파싱하기 더 쉬운 방법을 제공하고, Grok Parser는 반구조화(semi-structured) 텍스트 메시지에서 속성을 추출할 수 있게 해줘요.

출처: 문서

본문

Learning Center에서 Grok 파싱 체험하기

로그 파이프라인을 만들고 수정하는 방법, Pipeline Scanner로 관리하는 방법, 처리된 로그 전반에서 속성 이름을 일관되게 표준화하는 방법을 배워보세요.

지금 등록하기

개요

Datadog는 JSON 형식 로그를 자동으로 파싱해요. 다른 형식의 로그는 Grok Parser 덕분에 보강할 수 있어요. Grok 문법은 순수 정규식보다 로그를 파싱하기 쉬운 방법을 제공해요. Grok Parser는 반구조화 텍스트 메시지에서 속성을 추출할 수 있게 해주죠.

Grok에는 정수, IP 주소, 호스트네임 등을 파싱하는 재사용 가능한 패턴이 내장되어 있어요. 이러한 값은 문자열로 grok parser에 전달해야 해요.

%{MATCHER:EXTRACT:FILTER} 문법으로 파싱 규칙을 작성할 수 있어요:

  • Matcher: 무엇을 기대할지(number, word, notSpace 등)를 설명하는 규칙(다른 토큰 규칙에 대한 참조일 수도 있음)이에요.
  • Extract (선택): Matcher가 매칭한 텍스트 조각의 캡처 대상을 나타내는 식별자예요.
  • Filter (선택): 매칭 결과를 변환하는 후처리기(post-processor)예요.

전형적인 비구조화 로그 예시:

john connected on 11/08/2017

다음 파싱 규칙을 사용하면:

MyParsingRule %{word:user} connected on %{date("MM/dd/yyyy"):date}

처리 후 다음 구조화된 로그가 생성돼요:

{
  "user": "john",
  "date": 1575590400000
}

참고:

  • 단일 Grok 파서에 여러 파싱 규칙이 있으면:
    • 주어진 로그에 일치하는 규칙은 하나뿐이에요. 위에서 아래로 첫 번째로 일치하는 규칙이 파싱을 수행해요.
    • 각 규칙은 목록에서 자기 위에 정의된 파싱 규칙을 참조할 수 있어요.
  • 같은 Grok 파서 안에서 규칙 이름은 유니크해야 해요.
  • 규칙 이름에는 영숫자 문자, _, .만 포함할 수 있어요. 영숫자 문자로 시작해야 해요.
  • null이거나 비어 있는 값을 가진 속성은 표시되지 않아요.
  • 각 규칙은 로그의 시작부터 끝까지 적용되므로 파싱 규칙이 로그 항목 전체와 일치하도록 정의해야 해요.
  • 일부 로그는 큰 공백 간격을 만들 수 있어요. 줄바꿈과 공백을 처리하려면 \n과 \s+를 사용하세요.

매처와 필터

경고: 쿼리 시점(query-time, Log Explorer에서)에 사용할 수 있는 Grok 파싱 기능은 제한된 매처(data, integer, notSpace, number, word)와 필터(number, integer) 하위 집합을 지원해요. 아래의 전체 매처·필터 집합은 수집 시점(ingest-time) Grok Parser 기능에 특화된 것이에요.

Datadog가 기본 구현한 모든 매처와 필터 목록이에요:

매처 (Matchers)

쿼리 시점 및 수집 시점 매처:

다음 매처는 쿼리 시점 파싱(Log Explorer)과 수집 시점 파싱(Grok Parser) 모두에서 사용할 수 있어요:

word : 단어 경계로 시작하고 a-z, A-Z, 0-9 문자와 _(밑줄) 문자를 포함하며 단어 경계로 끝나는 word와 일치해요. 정규식의 \b\w+\b와 동일해요.

notSpace : 다음 공백까지의 모든 문자열과 일치해요.

number : 십진 부동소수점 숫자와 일치하고 double precision 숫자로 파싱해요.

integer : 정수와 일치하고 정수로 파싱해요.

data : 공백과 줄바꿈을 포함한 모든 문자열과 일치해요. 정규식의 .*와 동일해요. 위 패턴이 모두 적절하지 않을 때 사용해요.

수집 시점 전용 매처:

다음 매처는 Grok Parser 프로세서로 수집 시점 파싱할 때만 사용할 수 있고 Log Explorer에서는 사용할 수 없어요:

date("pattern"[, "timezoneId"[, "localeId"]]) : 지정한 패턴의 날짜와 일치하고 Unix 타임스탬프로 파싱해요. date 매처 예시를 참고하세요.

regex("pattern") : 정규식과 일치해요. regex 매처 예시를 확인하세요.

boolean("truePattern", "falsePattern") : Boolean을 매칭·파싱하며, true와 false 패턴을 선택적으로 정의할 수 있어요(기본값은 true와 false, 대소문자 무시).

numberStr : 십진 부동소수점 숫자와 일치하고 문자열로 파싱해요.

numberExtStr : 부동소수점 숫자(지수 표기 지원)와 일치하고 문자열로 파싱해요.

numberExt : 부동소수점 숫자(지수 표기 지원)와 일치하고 double precision 숫자로 파싱해요.

integerStr : 정수와 일치하고 문자열로 파싱해요.

integerExtStr : 정수(지수 표기 지원)와 일치하고 문자열로 파싱해요.

integerExt : 정수(지수 표기 지원)와 일치하고 정수로 파싱해요.

doubleQuotedString : 큰따옴표로 묶인 문자열과 일치해요.

singleQuotedString : 작은따옴표로 묶인 문자열과 일치해요.

quotedString : 큰따옴표 또는 작은따옴표로 묶인 문자열과 일치해요.

uuid : UUID와 일치해요.

mac : MAC 주소와 일치해요.

ipv4 : IPV4와 일치해요.

ipv6 : IPV6와 일치해요.

ip : IP(v4 또는 v6)와 일치해요.

hostname : 호스트네임과 일치해요.

ipOrHost : 호스트네임 또는 IP와 일치해요.

port : 포트 번호와 일치해요.

필터 (Filters)

쿼리 시점 및 수집 시점 필터:

다음 필터는 쿼리 시점 파싱(Log Explorer)과 수집 시점 파싱(Grok Parser) 모두에서 사용할 수 있어요:

number : 매칭 결과를 double precision 숫자로 파싱해요.

integer : 매칭 결과를 정수로 파싱해요.

수집 시점 전용 필터:

다음 필터는 Grok Parser 프로세서로 수집 시점 파싱할 때만 사용할 수 있고 Log Explorer에서는 사용할 수 없어요:

boolean : 'true'와 'false' 문자열을 대소문자를 무시하고 boolean으로 파싱해요.

nullIf("value") : 매칭 결과가 지정한 값과 같으면 null을 반환해요.

json : 올바르게 포맷된 JSON을 파싱해요.

rubyhash : {name => "John", "job" => {"company" => "Big Company", "title" => "CTO"}}처럼 올바르게 포맷된 Ruby 해시를 파싱해요.

useragent([decodeuricomponent:true/false]) : user-agent를 파싱하고 에이전트가 나타내는 기기, OS, 브라우저를 담은 JSON 객체를 반환해요. User Agent 프로세서를 확인하세요.

querystring : 일치하는 URL 쿼리 문자열에서 모든 키-값 쌍을 추출해요(예: ?productId=superproduct&promotionCode=superpromo).

decodeuricomponent : URI 구성 요소를 디코딩해요. 예를 들어 %2Fservice%2Ftest를 /service/test로 변환해요.

lowercase : 소문자로 변환된 문자열을 반환해요.

uppercase : 대문자로 변환된 문자열을 반환해요.

keyvalue([separatorStr[, characterAllowList[, quotingStr[, delimiter]]]]) : 키-값 패턴을 추출하고 JSON 객체를 반환해요. key-value 필터 예시를 참고하세요.

xml : 올바르게 포맷된 XML을 파싱해요. XML 필터 예시를 참고하세요.

csv(headers[, separator[, quotingcharacter]]) : 올바르게 포맷된 CSV 또는 TSV 라인을 파싱해요. CSV 필터 예시를 참고하세요.

scale(factor) : 기대하는 숫자 값에 지정한 factor를 곱해요.

array([[openCloseStr, ] separator][, subRuleOrFilter) : 토큰 문자열 시퀀스를 파싱하고 배열로 반환해요. list to array 예시를 참고하세요.

url : URL을 파싱하고 분해된 모든 구성 요소(도메인, 쿼리 파라미터, 포트 등)를 JSON 객체로 반환해요. URL 파싱 방법에 대한 자세한 정보

고급 설정

Grok 프로세서 하단의 Advanced Settings 섹션을 사용하면 기본 message 속성 대신 특정 속성을 파싱하거나, 여러 파싱 규칙에서 공통 패턴을 재사용하는 헬퍼 규칙을 정의할 수 있어요.

특정 텍스트 속성 파싱하기

Extract from 필드를 사용해 기본 message 속성 대신 지정한 텍스트 속성에 Grok 프로세서를 적용할 수 있어요.

예를 들어 키-값으로 파싱해야 하는 command.line 속성이 포함된 로그를 생각해보세요. command.line에서 Extract하여 내용을 파싱하고 커맨드 데이터에서 구조화된 속성을 만들 수 있어요.

헬퍼 규칙으로 공통 패턴 재사용하기

Helper Rules 필드를 사용해 파싱 규칙의 토큰을 정의할 수 있어요. 헬퍼 규칙을 쓰면 공통 Grok 패턴을 여러 파싱 규칙에서 재사용할 수 있어요. 같은 Grok 파서에 같은 토큰을 쓰는 규칙이 여러 개 있을 때 유용하죠.

전형적인 비구조화 로그 예시:

john id:12345 connected on 11/08/2017 on server XYZ in production

다음 파싱 규칙을 사용해요:

MyParsingRule %{user} %{connection} %{server}

다음 헬퍼를 사용하면:

user %{word:user.name} id:%{integer:user.id}
connection connected on %{date("MM/dd/yyyy"):connect_date}
server on server %{notSpace:server.name} in %{notSpace:server.env}

예시

파서를 사용하는 방법을 보여주는 예시 몇 가지예요:

  • 키-값 또는 logfmt
  • 날짜 파싱
  • 교대 패턴(Alternating patterns)
  • 선택 속성(Optional attribute)
  • 중첩 JSON
  • 정규식
  • 목록과 배열
  • Glog 형식
  • XML
  • CSV

키-값 또는 logfmt

이것은 키-값 코어 필터예요: keyvalue([separatorStr[, characterAllowList[, quotingStr[, delimiter]]]]) 여기서:

  • separatorStr: 키와 값 사이의 구분자를 정의해요. 기본값은 =예요.
  • characterAllowList: 기본 \w.\-_@에 추가로 이스케이프하지 않는 값 문자를 정의해요. 따옴표가 없는 값(예: key=@valueStr)에만 사용해요.
  • quotingStr: 따옴표를 정의하고 기본 따옴표 감지(<>, "", '')를 대체해요.
  • delimiter: 서로 다른 키-값 쌍 사이의 구분자를 정의해요(예: key1=value1|key2=value2에서 |가 구분자예요). 기본값은 (일반 공백), ,, ;예요.

keyvalue 같은 필터를 사용하면 keyvalue 또는 logfmt 형식의 문자열을 속성으로 더 쉽게 매핑할 수 있어요:

Log (로그):

user=john connect_date=11/08/2017 id=123 action=click

Rule (규칙):

rule %{data::keyvalue}

파라미터 이름은 로그에 이미 포함되어 있으므로 지정할 필요가 없어요. 규칙 패턴에 extract 속성 my_attribute를 추가하면 다음과 같이 보여요:

{
  "my_attribute": {
    "user": "john",
    "id": 123,
    "action": "click"
  }
}

=가 키와 값 사이의 기본 구분자가 아니라면, 파싱 규칙에 구분자를 가진 파라미터를 추가해요.

Log (로그):

user: john connect_date: 11/08/2017 id: 123 action: click

Rule (규칙):

rule %{data::keyvalue(": ")}

로그의 속성 값에 / 같은 특수 문자가 포함되어 있다면(예: url), 파싱 규칙의 allowlist에 추가해요:

Log (로그):

url=https://app.datadoghq.com/event/stream user=john

Rule (규칙):

rule %{data::keyvalue("=","/:")}

다른 예시:

Raw string Parsing rule Result
key=valueStr %{data::keyvalue} {"key": "valueStr"}
key= %{data::keyvalue} {"key": "valueStr"}
"key"="valueStr" %{data::keyvalue} {"key": "valueStr"}
key:valueStr %{data::keyvalue(":")} {"key": "valueStr"}
key:"/valueStr" %{data::keyvalue(":", "/")} {"key": "/valueStr"}
/key:/valueStr %{data::keyvalue(":", "/")} {"/key": "/valueStr"}
key:={valueStr} %{data::keyvalue(":=", "", "{}")} {"key": "valueStr"}
key1=value1 key2=value2 `%{data::keyvalue("=", "", "", "
key1="value1" key2="value2" `%{data::keyvalue("=", "", "", "

여러 QuotingString 예시: 여러 quotingstring을 정의하면 기본 동작이 정의된 quoting 문자로 대체돼요. key-value는 quotingStr에 지정된 것과 관계없이 항상 quoting 문자가 없는 입력과 일치해요. quoting 문자가 사용되면 quoting 문자 사이의 모든 것이 추출되므로 characterAllowList는 무시돼요.

Log (로그):

key1:=valueStr key2:=</valueStr2> key3:="valueStr3"

Rule (규칙):

rule %{data::keyvalue(":=","","<>")}

Result (결과):

{"key1": "valueStr", "key2": "/valueStr2"}

참고:

  • 빈 값(key=)이나 null 값(key=null)은 출력 JSON에 표시되지 않아요.
  • data 객체에 keyvalue 필터를 정의했는데 일치하지 않으면 빈 JSON {}이 반환돼요(예: 입력 key:=valueStr, 파싱 규칙 rule_test %{data::keyvalue("=")}, 출력 {}).
  • quotingStr로 ""를 정의하면 따옴표에 기본 구성을 유지해요.

날짜 파싱

date 매처는 타임스탬프를 EPOCH 형식(단위 밀리초)으로 변환해요.

Raw string Parsing rule Result
14:20:15 %{date("HH:mm:ss"):date} {"date": 51615000}
02:20:15 PM %{date("hh:mm:ss a"):date} {"date": 51615000}
11/10/2014 %{date("dd/MM/yyyy"):date} {"date": 1412978400000}
Thu Jun 16 08:29:03 2016 %{date("EEE MMM dd HH:mm:ss yyyy"):date} {"date": 1466065743000}
Tue Nov 1 08:29:03 2016 %{date("EEE MMM d HH:mm:ss yyyy"):date} {"date": 1466065743000}
06/Mar/2013:01:36:30 +0900 %{date("dd/MMM/yyyy:HH:mm:ss Z"):date} {"date": 1362501390000}
2016-11-29T16:21:36.431+0000 %{date("yyyy-MM-dd'T'HH:mm:ss.SSSZ"):date} {"date": 1480436496431}
2016-11-29T16:21:36.431+00:00 %{date("yyyy-MM-dd'T'HH:mm:ss.SSSZZ"):date} {"date": 1480436496431}
06/Feb/2009:12:14:14.655 %{date("dd/MMM/yyyy:HH:mm:ss.SSS"):date} {"date": 1233922454655}
2007-08-31 19:22:22.427 ADT %{date("yyyy-MM-dd HH:mm:ss.SSS z"):date} {"date": 1188598942427}
Thu Jun 16 08:29:03 20161 %{date("EEE MMM dd HH:mm:ss yyyy","Europe/Paris"):date} {"date": 1466058543000}
Thu Jun 16 08:29:03 20161 %{date("EEE MMM dd HH:mm:ss yyyy","UTC+5"):date} {"date": 1466047743000}
Thu Jun 16 08:29:03 20161 %{date("EEE MMM dd HH:mm:ss yyyy","+3"):date} {"date": 1466054943000}

1 자체 현지화를 수행하고 타임스탬프가 UTC가 아니라면 timezone 파라미터를 사용하세요. 지원되는 시간대 형식은 다음과 같아요:

  • GMT, UTC, UT 또는 Z
  • +hh:mm, -hh:mm, +hhmm, -hhmm. 최대 지원 범위는 +18:00부터 -18:00까지(포함)예요.
  • UTC+, UTC-, GMT+, GMT-, UT+ 또는 UT-로 시작하는 시간대. 최대 지원 범위는 +18:00부터 -18:00까지(포함)예요.
  • TZ 데이터베이스에서 가져온 시간대 ID. 자세한 내용은 TZ database 이름을 참고하세요.

참고: 날짜를 파싱한다고 해서 그 값이 로그의 공식 날짜로 설정되지는 않아요. 그러려면 후속 프로세서에서 Log Date Remapper를 사용하세요.

교대 패턴

단지 하나의 속성만 다른 두 가지 형식의 로그가 있다면, (<REGEX_1>|<REGEX_2>)를 사용한 교대(alternating)로 단일 규칙을 설정할 수 있어요. 이 규칙은 Boolean OR과 동일해요.

Log (로그):

john connected on 11/08/2017
12345 connected on 11/08/2017

Rule (규칙): "id"는 문자열이 아니라 정수라는 점을 주목하세요.

MyParsingRule (%{integer:user.id}|%{word:user.firstname}) connected on %{date("MM/dd/yyyy"):connect_date}

Results (결과): %{integer:user.id}

{
  "user": {
    "id": 12345
  },
  "connect_date": 1510099200000
}

%{word:user.firstname}

{
  "user": {
    "firstname": "john"
  },
  "connect_date": 1510099200000
}

선택 속성

일부 로그에는 특정 경우에만 나타나는 값이 있어요. 이 경우 ()?로 속성 추출을 선택적으로 만들 수 있어요.

Log (로그):

john 1234 connected on 11/08/2017
john connected on 11/08/2017

Rule (규칙):

MyParsingRule %{word:user.firstname} (%{integer:user.id} )?connected on %{date("MM/dd/yyyy"):connect_date}

참고: 선택 섹션의 첫 단어 뒤에 공백을 넣으면 규칙이 일치하지 않아요.

Result (결과): (%{integer:user.id} )?

{
  "user": {
    "firstname": "john",
    "id": 1234
  },
  "connect_date": 1510099200000
}

%{word:user.firstname} (%{integer:user.id} )?

{
  "user": {
    "firstname": "john",
  },
  "connect_date": 1510099200000
}

중첩 JSON

json 필터를 사용해 원시 텍스트 접두어 뒤에 오는 중첩 JSON 객체를 파싱할 수 있어요:

Log (로그):

Sep 06 09:13:38 vagrant program[123]: server.1 {"method":"GET", "status_code":200, "url":"https://app.datadoghq.com/logs/pipelines", "duration":123456}

Rule (규칙):

parsing_rule %{date("MMM dd HH:mm:ss"):timestamp} %{word:vm} %{word:app}\[%{number:logger.thread_id}\]: %{notSpace:server} %{data::json}

Result (결과):

{
  "timestamp": 1567761218000,
  "vm": "vagrant",
  "app": "program",
  "logger": {
    "thread_id": 123
  },
  "server": "server.1",
  "method": "GET",
  "status_code": 200,
  "url": "https://app.datadoghq.com/logs/pipelines",
  "duration": 123456
}

정규식 (Regex)

Log (로그):

john_1a2b3c4 connected on 11/08/2017

Rule (규칙):

MyParsingRule %{regex("[a-z]*"):user.firstname}_%{regex("[a-zA-Z0-9]*"):user.id} .*

Result (결과):

{
  "user": {
    "firstname": "john",
    "id": "1a2b3c4"
  }
}

목록을 배열로

array([[openCloseStr, ] separator][, subRuleOrFilter) 필터를 사용해 목록을 단일 속성의 배열로 추출할 수 있어요. subRuleOrFilter는 선택 사항이며 다음 필터를 받아들여요.

Log (로그):

Users [John, Oliver, Marc, Tom] have been added to the database

Rule (규칙):

myParsingRule Users %{data:users:array("[]",",")} have been added to the database

Result (결과):

{
  "users": [
    "John",
    " Oliver",
    " Marc",
    " Tom"
  ]
}

Log (로그):

Users {John-Oliver-Marc-Tom} have been added to the database

Rule (규칙):

myParsingRule Users %{data:users:array("{}","-")} have been added to the database

subRuleOrFilter를 사용한 규칙:

myParsingRule Users %{data:users:array("{}","-", uppercase)} have been added to the database

Glog 형식

Kubernetes 구성 요소는 때때로 glog 형식으로 로깅해요. 이 예시는 Pipeline Library의 Kube Scheduler 항목에서 가져온 것이에요.

예시 로그 라인:

W0424 11:47:41.605188       1 authorization.go:47] Authorization is disabled

파싱 규칙:

kube_scheduler %{regex("\\w"):level}%{date("MMdd HH:mm:ss.SSSSSS"):timestamp}\s+%{number:logger.thread_id} %{notSpace:logger.name}:%{number:logger.lineno}\] %{data:msg}

그리고 추출된 JSON:

{
  "level": "W",
  "timestamp": 1587728861605,
  "logger": {
    "thread_id": 1,
    "name": "authorization.go"
  },
  "lineno": 47,
  "msg": "Authorization is disabled"
}

XML 파싱

XML 파서는 XML 형식 메시지를 JSON으로 변환해요.

Log (로그):

<book category="CHILDREN">
  <title lang="en">Harry Potter</title>
  <author>J K. Rowling</author>
  <year>2005</year>
</book>

Rule (규칙):

rule %{data::xml}

Result (결과):

{
"book": {
  "year": "2005",
  "author": "J K. Rowling",
  "category": "CHILDREN",
  "title": {
    "lang": "en",
    "value": "Harry Potter"
  }
}
}

참고:

  • XML에 속성과 두 태그 사이의 문자열 값이 모두 있는 태그가 포함되어 있으면 value 속성이 생성돼요. 예: <title lang="en">Harry Potter</title>은 {"title": {"lang": "en", "value": "Harry Potter" } }로 변환돼요.
  • 반복되는 태그는 자동으로 배열로 변환돼요. 예: <bookstore><book>Harry Potter</book><book>Everyday Italian</book></bookstore>은 { "bookstore": { "book": [ "Harry Potter", "Everyday Italian" ] } }로 변환돼요.

CSV 파싱

csv 필터를 사용하면 지정한 문자(기본값 ,)로 구분된 문자열을 속성에 더 쉽게 매핑할 수 있어요.

CSV 필터는 csv(headers[, separator[, quotingcharacter]])로 정의돼요. 여기서:

  • headers: ,로 구분된 키 이름을 정의해요. 키 이름은 알파벳 문자로 시작해야 하고 _와 함께 모든 영숫자 문자를 포함할 수 있어요.
  • separator: 서로 다른 값을 구분하는 데 사용되는 구분자를 정의해요. 한 문자만 허용돼요. 기본값: ,. 참고: TSV에서는 tab 문자를 나타내기 위해 separator로 tab을 사용하세요.
  • quotingcharacter: quoting 문자를 정의해요. 한 문자만 허용돼요. 기본값: "

참고:

  • 구분자 문자를 포함하는 값은 따옴표로 묶어야 해요.
  • quoting 문자를 포함하는 따옴표로 묶인 값은 quoting 문자로 이스케이프해야 해요. 예를 들어 따옴표로 묶인 값 안의 ""는 "를 나타내요.
  • 로그에 헤더의 키 수와 같은 수의 값이 포함되어 있지 않으면 CSV 파서는 앞의 값들을 먼저 매칭해요.
  • 가능한 경우 Integer와 Double은 자동으로 캐스팅돼요.

Log (로그):

John,Doe,120,Jefferson St.,Riverside

Rule (규칙):

myParsingRule %{data:user:csv("first_name,name,st_nb,st_name,city")}

Result (결과):

{
  "user": {
    "first_name": "John",
    "name": "Doe",
    "st_nb": 120,
    "st_name": "Jefferson St.",
    "city": "Riverside"
  }
}

다른 예시:

Raw string Parsing rule Result
John,Doe %{data::csv("firstname,name")} {"firstname": "John", "name":"Doe"}
"John ""Da Man""",Doe %{data::csv("firstname,name")} {"firstname": "John "Da Man"", "name":"Doe"}
'John ''Da Man''',Doe %{data::csv("firstname,name",",","'")} {"firstname": "John 'Da Man'", "name":"Doe"}
`John Doe` `%{data::csv("firstname,name","
value1,value2,value3 %{data::csv("key1,key2")} {"key1": "value1", "key2":"value2"}
value1,value2 %{data::csv("key1,key2,key3")} {"key1": "value1", "key2":"value2"}
value1,,value3 %{data::csv("key1,key2,key3")} {"key1": "value1", "key3":"value3"}
Value1 Value2 Value3 (TSV) %{data::csv("key1,key2,key3","tab")} {"key1": "value1", "key2": "value2", "key3":"value3"}

data 매처로 불필요한 텍스트 버리기

필요한 부분을 파싱했고 그 이후의 텍스트는 버려도 안전하다는 것을 아는 로그가 있다면, data 매처를 사용해 버릴 수 있어요. 다음 로그 예시에서는 data 매처를 사용해 끝의 %를 버릴 수 있어요.

Log (로그):

Usage: 24.3%

Rule (규칙):

MyParsingRule Usage\:\s+%{number:usage}%{data:ignore}

Result (결과):

{
  "usage": 24.3,
  "ignore": "%"
}

ASCII 제어 문자

로그에 ASCII 제어 문자가 포함되어 있으면 수집 시 직렬화돼요. 이것은 grok 파서 안에서 직렬화된 값을 명시적으로 이스케이프해서 처리할 수 있어요.

더 알아보기 (Learn more)

추가로 도움이 되는 문서, 링크, 아티클: