- 重要な情報
- はじめに
- 用語集
- ガイド
- エージェント
- インテグレーション
- OpenTelemetry
- 開発者
- API
- CoScreen
- アプリ内
- Service Management
- インフラストラクチャー
- アプリケーションパフォーマンス
- 継続的インテグレーション
- ログ管理
- セキュリティ
- UX モニタリング
- 管理
Datadog は JSON 形式のログを自動的にパースしますが、その他の形式の場合は、Grok パーサーを利用してログを補完できます。 Grok 構文は、標準の正規表現より簡単にログをパースする方法を提供します。Grok パーサーにより、半構造化されたテキストメッセージから属性を抽出できます。
Grok には、整数、IP アドレス、ホスト名などをパースするための再利用可能なパターンが付属しています。これらの値は文字列として grok パーサーに送られなければなりません。
パース規則は、%{MATCHER:EXTRACT:FILTER}
構文を使用して記述できます。
Matcher: 期待する内容 (数値、単語、スペース以外など) を記述する規則 (または別のトークン規則への参照)。
Extract (任意): Matcher と一致するテキストをキャプチャする対象を表す識別子。
Filter (任意): 一致したテキストを変換するためのポストプロセッサー。
典型的な非構造化ログの例
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")
numberStr
number
numberExtStr
numberExt
integerStr
integer
integerExtStr
integerExt
word
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
lowercase
uppercase
keyvalue([separatorStr[, characterAllowList[, quotingStr[, delimiter]]]])
xml
csv(headers[, separator[, quotingcharacter]])
scale(factor)
array([[openCloseStr, ] separator][, subRuleOrFilter)
url
Grok プロセッサータイルの下部に、Advanced Settings セクションがあります。
Extract from フィールドを使用して、デフォルトの message
属性ではなく、指定されたテキスト属性に Grok プロセッサを適用します。
たとえば、key-value としてパースされる必要のある command.line
属性を持つログを例に取ると、そのログは以下のようにパースできます。
パース規則に使用するトークンを定義するには、Helper Rules フィールドを使用します。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}
以下に、パーサーの具体的な使用例をいくつか挙げます。
これは key-value コアフィルター keyvalue([separatorStr[, characterAllowList[, quotingStr[, delimiter]]]])
です。
separatorStr
: キーと値を区切るセパレーターを定義します。デフォルト =
.characterAllowList
: デフォルトの \\w.\\-_@
に加え、追加の非エスケープ値文字を定義します。引用符で囲まれていない値 (例: key=@valueStr
) にのみ使用します。quotingStr
: 引用符を定義し、デフォルトの引用符検出(<>
、""
、''
)を置き換えます。delimiter
: 異なる key-value ペアのセパレーターを定義します(すなわち、|
は key1=value1|key2=value2
の区切り文字です)。デフォルトは
(通常のスペース)、,
および ;
です。keyvalue などのフィルターを使用すると、keyvalue または logfmt 形式の属性に文字列をより簡単にマップできます。
ログ:
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 の /
などの特殊文字が含まれる場合は、それをパース規則の許可リストに追加します。
ログ:
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”} |
Multiple QuotingString の例: 複数の引用文字列が定義されると、デフォルトの挙動が定義された引用文字に置き換えられます。
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 形式 (millisecond 計測単位) に変換します。
文字列の例 | パース規則 | 結果 |
---|---|---|
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
+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 までです。注: 日付をパースしても、その値は公式のログ日付として設定されません。設定するには、後続のプロセッサーで ログ日付リマッパーを使用してください。
ログの形式が 2 通りあり、そのうち 1 つの属性だけが異なる場合は、(<REGEX_1>|<REGEX_2>)
による交互条件を使用して 1 つの規則を設定します。この規則は Boolean OR と同じです。
ログの例
john connected on 11/08/2017
12345 connected on 11/08/2017
規則: “id” は整数です。文字列ではないので注意してください。
MyParsingRule (%{integer:user.id}|%{word:user.firstname}) connected on %{date("MM/dd/yyyy"):connect_date}
結果
必ずしも表示されない値がログに含まれることがあります。その場合は、()?
を使用して属性抽出を任意にします。
ログの例
john 1234 connected on 11/08/2017
規則の例
MyParsingRule %{word:user.firstname} (%{integer:user.id} )?connected on %{date("MM/dd/yyyy"):connect_date}
注: 任意のセクションで先頭の単語の後ろにスペースを含めると、規則は一致しません。
未処理のテキストプレフィックスの後でネストされている 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} .*
リストを 1 つの属性の配列に取り出すには 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 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 形式のメッセージを 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
: 異なる値の区切りに使用する区切り文字を定義します。1 文字のみ使用可能です。デフォルト: ,
。注: TSV のタブ文字を表すには、separator
に tab
を使用します。quotingcharacter
: 引用符を定義します。許可されるのは 1 文字だけです。デフォルトは "
。注:
""
は "
を意味します。ログの例
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")} | {“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","|")} | {“firstname”: “John”, “name”:“Doe”} |
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”} |
ログに ASCII 制御文字が含まれている場合、それは取り込み時にシリアル化されます。これは、grok パーサー内でシリアル化された値を明示的にエスケープすることで処理できます。