- 필수 기능
- 시작하기
- Glossary
- 표준 속성
- Guides
- Agent
- 통합
- 개방형텔레메트리
- 개발자
- Administrator's Guide
- API
- Datadog Mobile App
- CoScreen
- Cloudcraft
- 앱 내
- 서비스 관리
- 인프라스트럭처
- 애플리케이션 성능
- APM
- Continuous Profiler
- 스팬 시각화
- 데이터 스트림 모니터링
- 데이터 작업 모니터링
- 디지털 경험
- 소프트웨어 제공
- 보안
- AI Observability
- 로그 관리
- 관리
Pipeline Scanner를 통해 로그 파이프라인을 빌드 및 수정하고, 관리하는 방법을 알아보세요. 일관성을 위해 처리된 로그 간 속성 이름을 표준화하는 방법도 알아보세요.
Datadog는 JSON 형식의 로그를 자동으로 파싱합니다. 다른 형식의 경우, Datadog에서는 Grok 파서를 통해 로그를 보강할 수 있도록 지원합니다. Grok 구문은 순수 정규 표현식보다 로그를 더 쉽게 파싱할 수 있는 방법을 제공합니다. Grok 파서를 사용하면 반구조화된 텍스트 메시지에서 속성을 추출할 수 있습니다.
Grok에는 정수, IP 주소, 호스트 이름 등을 파싱하는 재사용 가능한 패턴이 포함되어 있습니다. 이러한 값은 문자열로 Grok 구파서에 보내야 합니다.
%{MATCHER:EXTRACT:FILTER}
구문을 사용하여 파싱 규칙을 작성할 수 있습니다.
Matcher: 예상되는 내용(숫자, 단어, notSpace 등)을 설명하는 규칙(다른 토큰 규칙에 대한 참조일 수 있음)입니다.
Extract (선택 사항): Matcher와 일치하는 텍스트 조각의 캡처 대상을 나타내는 식별자입니다.
필터(옵션): 매치를 변환하는 포스트-프로세서입니다.
구조화되지 않은 전형적인 로그 예시:
john connected on 11/08/2017
다음 파싱 규칙을 사용합니다.
MyParsingRule %{word:user} connected on %{date("MM/dd/yyyy"):date}
처리 후 다음 구조화된 로그가 생성됩니다.
참고:
_
, .
만 포함해야 하며, 반드시 영숫자로 시작해야 합니다.^
과 $
를 적용하여 문자열의 시작과 끝이 매칭되도록 합니다.\n
및 \s+
을 사용하여 줄 바꿈과 공백을 고려하세요.다음은 Datadog에서 기본적으로 구현된 모든 일치기와 필터 목록을 보여줍니다.
date("pattern"[, "timezoneId"[, "localeId"]])
regex("pattern")
notSpace
boolean("truePattern", "falsePattern")
true
및 false
로 대소문자 무시).numberStr
number
numberExtStr
numberExt
integerStr
integer
integerExtStr
integerExt
word
_
(밑줄) 문자와 a-z, A-Z, 0-9의 문자를 포함하는 _word_와 일치합니다. 정규식에서 \b\w+\b
에 해당합니다.doubleQuotedString
singleQuotedString
quotedString
uuid
mac
ipv4
ipv6
ip
hostname
ipOrHost
port
data
.*
에 해당합니다. 위의 패턴 중 어느 것도 적절하지 않을 때 사용합니다.number
integer
boolean
nullIf("value")
json
rubyhash
{name => "John", "job" => {"company" => "Big Company", "title" => "CTO"}}
useragent([decodeuricomponent:true/false])
querystring
?productId=superproduct&promotionCode=superpromo
)에 있는 모든 키-값 쌍을 추출합니다.decodeuricomponent
%2Fservice%2Ftest
를 /service/test
로 변환합니다.lowercase
uppercase
keyvalue([separatorStr[, characterAllowList[, quotingStr[, delimiter]]]])
xml
csv(headers[, separator[, quotingcharacter]])
scale(factor)
array([[openCloseStr, ] separator][, subRuleOrFilter)
url
Grok 프로세서 타일의 하단에는 고급 설정 섹션이 있습니다.
다음에서 추출 소스 필드를 사용하여 기본 message
속성 대신 지정된 텍스트 속성에 Grok 프로세서를 적용합니다.
예를 들어 키 값으로 파싱해야 하는 command.line
속성이 포함된 로그를 생각해 봅니다. 다음과 같이 파싱할 수 있습니다.
도우미 규칙 필드를 사용하여 파싱 규칙에 대한 토큰을 정의하세요. 도우미 규칙 도움말을 사용하면 파싱 규칙에서 Grok 패턴을 인수 분해할 수 있습니다. 이 기능은 동일한 Grok Parser에 동일한 토큰을 사용하는 여러 개의 규칙이 있을 때 유용합니다.
구조화되지 않은 전형적인 로그 예시:
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}
파싱기 사용 방법을 보여주는 몇 가지 예제입니다:
키-값 핵심 필터: keyvalue([separatorStr[, characterAllowList[, quotingStr[, delimiter]]]])
조건:
separatorStr
키와 값 사이의 구분 기호를 정의합니다. 기본값은 =
입니다.characterAllowList
는 기본값 \\w.\\-_@
외에 이스케이프 처리되지 않은 값 문자를 추가로 정의합니다. 따옴표로 묶지 않은 값(예: key=@valueStr
)에만 사용됩니다.quotingStr
는 따옴표를 정의하여 기본 따옴표 감지를 대체합니다: <>
, ""
, ''
.delimiter
는 서로 다른 키 값 쌍 사이의 구분 기호를 정의합니다(예: |
는 key1=value1|key2=value2
의 구분 기호입니다). 기본값은
(normal space), ,
and ;
입니다.keyvalue 등 필터를 사용하면 문자열을 키값 또는 로그값 형식의 속성에 더 쉽게 매핑할 수 있습니다:
로그:
user=john connect_date=11/08/2017 id=123 action=click
규칙:
rule %{data::keyvalue}
파라미터의 이름은 이미 로그에 포함되어 있으므로 지정할 필요가 없습니다.
규칙 패턴에 extract 속성 my_attribute
을 추가하면 표시됩니다.
키와 값 사이의 기본 구분 기호가 =
가 아닌 경우 파싱 규칙에 파라미터를 구분 기호와 함께 추가하세요.
로그:
user: john connect_date: 11/08/2017 id: 123 action: click
규칙:
rule %{data::keyvalue(": ")}
예를 들어 로그에 /
와 같은 속성 값에 특수 문자가 포함된 경우 파싱 규칙의 허용 목록에 추가합니다.
로그:
url=https://app.datadoghq.com/event/stream user=john
규칙:
rule %{data::keyvalue("=","/:")}
기타 예시:
원시 문자열 | 파싱 규칙 | 결과 |
---|---|---|
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”} |
/key:/valueStr | %{data::keyvalue(":", "/")} | {"/key": “/valueStr”} |
key:={valueStr} | %{data::keyvalue(":=", "", "{}")} | {“key”: “valueStr”} |
key1=value1|key2=value2 | %{data::keyvalue("=", "", "", "|")} | {“key1”: “value1”, “key2”: “value2”} |
key1=“value1”|key2=“value2” | %{data::keyvalue("=", "", "", "|")} | {“key1”: “value1”, “key2”: “value2”} |
다중 인용 문자열 예제: 여러 인용 문자열이 정의된 경우 기본 동작은 정의된 인용 문자로 대체됩니다.
키-값은 quotingStr
에 지정된 내용에 관계없이 항상 따옴표 문자가 없는 입력과 매칭됩니다. 따옴표 문자를 사용하면 따옴표 문자 사이의 모든 내용이 추출되므로 characterAllowList
는 무시됩니다.
로그:
key1:=valueStr key2:=</valueStr2> key3:="valueStr3"
규칙:
rule %{data::keyvalue(":=","","<>")}
결과:
{"key1": "valueStr", "key2": "/valueStr2"}
참고:
key=
) 또는 null
값(key=null
)은 출력 JSON에 표시되지 않습니다.data
객체에 keyvalue 필터를 정의하고 이 필터가 매칭되지 않으면 빈 JSON {}
이 반환됩니다(예: 입력: key:=valueStr
, 파싱 규칙: rule_test %{data::keyvalue("=")}
, 출력: {}
).""
을 quotingStr
으로 정의하면 인용 시 기본값 설정이 유지됩니다.날짜 일치기는 타임스탬프를 EPOCH 형식(밀리초 측정 단위)으로 변환합니다.
원시 문자열 | 파싱 규칙 | 결과 |
---|---|---|
14:20:15 | %{date("HH:mm:ss"):date} | {“date”: 51615000} |
02:20:15 PM | %{date("hh:mm:ss a"):date} | {“date”: 51615000} |
2014/10/11 | %{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
+h
, +hh
, +hh:mm
, -hh:mm
, +hhmm
, -hhmm
, +hh:mm:ss
, -hh:mm:ss
, +hhmmss
또는 -hhmmss
. 지원되는 최대 범위는 +18:00부터 -18:00까지입니다.UTC+
, UTC-
, GMT+
, GMT-
, UT+
또는 UT-
로 시작하는 시간대 최대 지원 범위는 +18:00 ~ -18:00(포함)입니다.참고: 파싱 날짜는 그 값을 로그를 공식 날짜로 설정하지 않습니다. 이를 위해 후속 프로세서에서 로그 날짜 리매퍼를 사용하세요.
속성이 하나만 다른 두 가지 가능한 형식의 로그가 있는 경우 (<REGEX_1>|<REGEX_2>)
을 번갈아 사용하여 단일 규칙을 설정합니다. 이 규칙은 부울 연산자인 OR과 동일합니다.
로그:
john connected on 11/08/2017
12345 connected on 11/08/2017
규칙: ‘id’는 문자열이 아닌 정수라는 점에 유의하세요.
내 파싱 규칙 (%{정수:사용자.id}|%{단어:사용자.이름}) %{date("MM/dd/yyyy"):connect_date}에 연결됨
결과:
일부 로그에는 일부만 표시되는 값이 포함되어 있습니다. 이 경우 ()?
를 사용하여 부수적인 속성 추출을 수행합니다.
로그:
john 1234 connected on 11/08/2017
규칙:
내 파싱 규칙 %{워드:사용자.이름} (%{정수:사용자.id} )?연결된 %{날짜("MM/dd/yyyy"):연결_날짜}
참고: 선택 섹션의 첫 단어 뒤에 공백을 포함하면 규칙이 매칭되지 않습니다.
json
필터를 사용하여 원시 텍스트 접두사 뒤에 중첩된 JSON 객체를 파싱합니다:
로그:
Sep 06 09:13:38 vagrant program[123]: server.1 {"method":"GET", "status_code":200, "url":"https://app.datadoghq.com/logs/pipelines", "duration":123456}
규칙:
parsing_rule %{date("MMM dd HH:mm:ss"):timestamp} %{word:vm} %{word:app}\[%{number:logger.thread_id}\]: %{notSpace:server} %{data::json}
로그:
john_1a2b3c4 connected on 11/08/2017
규칙:
MyParsingRule %{regex("[a-z]*"):user.firstname}_%{regex("[a-zA-Z0-9]*"):user.id} .*
array([[openCloseStr, ] separator][, subRuleOrFilter)
필터를 사용하여 목록을 단일 속성의 배열로 추출합니다. subRuleOrFilter
는 선택 항목이며 이러한 필터를 허용합니다.
로그:
Users [John, Oliver, Marc, Tom] have been added to the database
규칙:
myParsingRule Users %{data:users:array("[]",",")} have been added to the database
로그:
Users {John-Oliver-Marc-Tom} have been added to the database
규칙:
myParsingRule Users %{data:users:array("{}","-")} have been added to the database
규칙 사용 subRuleOrFilter
:
myParsingRule Users %{data:users:array("{}","-", uppercase)} have been added to the database
쿠버네티스(Kubernetes) 구성 요소는 때때로 glog
형식으로 로그를 남깁니다. 이 예제는 파이프라인의 Kube 스케줄러 항목 라이브러리에서 가져온 것입니다.
예시 로그 라인:
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 형식의 메시지를 JSON으로 변환합니다.
로그:
<book category="CHILDREN">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
</book>
규칙:
rule %{data::xml}
결과:
{
"book": {
"year": "2005",
"author": "J K. Rowling",
"category": "CHILDREN",
"title": {
"lang": "en",
"value": "Harry Potter"
}
}
}
참고:
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(headers[, separator[, quotingcharacter]])
로 정의됩니다.
headers
: ,
로 구분된 키 이름을 정의합니다. 키 이름은 알파벳 문자로 시작해야 하며 _
외에 영숫자 문자를 포함할 수 있습니다.separator
: 서로 다른 값을 구분하는 데 사용되는 구분 기호를 정의합니다. 한 문자만 허용됩니다. 기본값: ,
. 참고: separator
에 tab
를 사용하여 TSV의 표 문자를 나타냅니다.quotingcharacter
: 인용 문자를 정의합니다. 하나의 문자만 허용됩니다. 기본값은 "
입니다.참고:
""
은 "
을 나타냅니다.로그:
John,Doe,120,Jefferson St.,Riverside
규칙:
myParsingRule %{data:user:csv("first_name,name,st_nb,st_name,city")}
결과:
{
"user": {
"first_name": "John",
"name": "Doe",
"st_nb": 120,
"st_name": "Jefferson St.",
"city": "Riverside"
}
}
기타 예시:
원시 문자열 | 파싱 규칙 | 결과 |
---|---|---|
John,Doe | %{data::csv("firstname,name")} | {“name”: “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
일치기를 사용하여 끝에 있는 %
를 삭제할 수 있습니다.
로그:
Usage: 24.3%
규칙:
내 파싱 규칙 사용\:\s+%{번호:사용}%{데이터:무시}
결과:
{
"usage": 24.3,
"ignore": "%"
}
로그에 ASCII 제어 문자가 포함된 경우, 수집 시 직렬화됩니다. 이러한 문자는 Grok 파서 내에서 직렬화된 값을 명시적으로 이스케이프하여 처리할 수 있습니다.