- 重要な情報
- はじめに
- 用語集
- ガイド
- エージェント
- インテグレーション
- OpenTelemetry
- 開発者
- API
- CoScreen
- アプリ内
- Service Management
- インフラストラクチャー
- アプリケーションパフォーマンス
- 継続的インテグレーション
- ログ管理
- セキュリティ
- UX モニタリング
- 管理
組織の規模が大きくなるとログの量が増えるため、下流のサービス (ログ管理ソリューション、SIEM など) で取り込みやインデックスを作成するコストも増加します。このガイドでは、観測可能性パイプラインの変換を使用してログ量を削減し、ログのサイズを切り詰めて、データがインフラストラクチャーやネットワークから離れる前にコストを管理する方法を説明します。
観測可能性パイプラインでは、変換はイベントを変更するアクションを実行します。イベントは、パイプラインを流れるログ、メトリクス、またはトレースです。
重複排除変換を使用して、パイプラインを通過するデータのコピーを削除するには、構成に次のコンポーネントを追加します。
transforms:
my_transform_id:
type: dedupe
inputs:
- my-source-or-transform-id
cache: null
fields: null
[transforms.my_transform_id]
type = "dedupe"
inputs = [ "my-source-or-transform-id" ]
{
"transforms": {
"my_transform_id": {
"type": "dedupe",
"inputs": [
"my-source-or-transform-id"
],
"cache": null,
"fields": null
}
}
}
観測可能性パイプラインワーカーは、重複排除されたイベントを追跡するために、すべてのイベントに一意の識別子を割り当てます。cache
オプションは、将来的に重複したデータをチェックするために、最近のイベントをキャッシュすることができます。fields
オプションは、イベントが重複しているかどうかを判断するためにどのフィールドを使用するかをリストアップします。
フィルター変換は、特定の条件を満たす特定のログのみをパイプラインのコンポーネントを通過させたい場合に使用します。例えば、それらの条件は、ログが含まれている場所となります。
env
のような特定のタグ。status
フィールドは 400
でなければなりません。そのような場合は、Vector Remap Language (VRL) または Datadog Log Search 構文を使用して条件を設定するログをフィルタリングするためのフィルター変換を含むコンポーネントを挿入してください。条件に一致しないログはドロップされます。
以下の例では、フィルター変換と Vector Remap Language を使って、status
が 500
のログのみを送信しています。
transforms:
my_transform_id:
type: filter
inputs:
- my-source-or-transform-id
condition:
type: "vrl"
source: ".status == 500"
[transforms.my_transform_id]
type = "filter"
inputs = [ "my-source-or-transform-id" ]
[transforms.my_transform_id.condition]
type = "vrl"
source = ".status == 500"
{
"transforms": {
"my_transform_id": {
"type": "filter",
"inputs": [
"my-source-or-transform-id"
],
"condition": {
"type": "vrl",
"source": ".status == 500"
}
}
}
}
CDN のログなど、大量に送られてくるデータやノイズを多く含むデータを分析する場合、すべてのログを送信先に送ることは不要です。代わりに、サンプル変換を使って、統計的に有意な分析を行うために必要なログのみを送信します。
exclude
フィールドは、サンプリングするイベントを除外し、VRL や Datadog Log Search 構文もサポートします。以下の例では、rate
で設定された 10 イベントごとにサンプリングする構成を示しています。
transforms:
my_transform_id:
type: sample
inputs:
- my-source-or-transform-id
exclude:
type: "datadog_search"
source: "*stack"
rate: 10
[transforms.my_transform_id]
type = "sample"
inputs = [ "my-source-or-transform-id" ]
rate = 10
[transforms.my_transform_id.exclude]
type = "datadog_search"
source = "*stack"
{
"transforms": {
"my_transform_id": {
"type": "sample",
"inputs": [
"my-source-or-transform-id"
],
"exclude": {
"type": "datadog_search",
"source": "*stack"
},
"rate": 10
}
}
}
時間の経過とともに振る舞いを理解したいシナリオでは、一連のログよりも、イベントのデータポイントに関連するメトリクスが有用です。ログがパイプラインを流れるとき、ログからメトリクスへの変換を使用して、特定のタグに基づいてメトリクスを生成することによって、ログの量を削減することができます。
4 種類のメトリクスを生成することができます。
以下の例では、counter
メトリクスを生成するための構成を示しています。metrics
はイベントに追加するキーと値のペアを定義します。
transforms:
my_transform_id:
type: log_to_metric
inputs:
- my-source-or-transform-id
metrics:
- type: counter
field: status
name: response_total
namespace: service
tags:
status: "{{status}}"
host: "{{host}}"
[transforms.my_transform_id]
type = "log_to_metric"
inputs = [ "my-source-or-transform-id" ]
[[transforms.my_transform_id.metrics]]
type = "counter"
field = "status"
name = "response_total"
namespace = "service"
[transforms.my_transform_id.metrics.tags]
status = "{{status}}"
host = "{{host}}"
{
"transforms": {
"my_transform_id": {
"type": "log_to_metric",
"inputs": [
"my-source-or-transform-id"
],
"metrics": [
{
"type": "counter",
"field": "status",
"name": "response_total",
"namespace": "service",
"tags": {
"status": "{{status}}",
"host": "{{host}}"
}
}
]
}
}
}
上記の構成で以下のようなログが流れた場合
{
"log": {
"host": "10.22.11.222",
"message": "Sent 200 in 54.2ms",
"status": 200
}
}
以下のメトリクスが生成されます。
{"metric":{"counter":{"value":1},"kind":"incremental","name":"response_total","namespace":"service","tags":{"host":"10.22.11.222","status":"200"}}}]
場合によっては、複数のログを 1 つのログに統合することも可能です。このように、ログ量を削減するもう一つの方法は、複数のログを 1 つのログに統合することです。複数のログを 1 つにまとめるには、縮小変換を使用します。
以下の例では、縮小変換の構成を使用して、複数の Ruby ログの例外イベントを統合しています。
transforms:
my_transform_id:
type: reduce
inputs:
- my-source-or-transform-id
group_by:
- host
- pid
- tid
merge_strategies:
message: concat_newline
starts_when: match(string!(.message), r'^[^\\s]')
[transforms.my_transform_id]
type = "reduce"
inputs = [ "my-source-or-transform-id" ]
group_by = [ "host", "pid", "tid" ]
starts_when = "match(string!(.message), r'^[^\\s]')"
[transforms.my_transform_id.merge_strategies]
message = "concat_newline"
{
"transforms": {
"my_transform_id": {
"type": "reduce",
"inputs": [
"my-source-or-transform-id"
],
"group_by": [
"host",
"pid",
"tid"
],
"merge_strategies": {
"message": "concat_newline"
},
"starts_when": "match(string!(.message), r'^[^\\s]')"
}
}
}
縮小変換では、group_by
はイベントをグループ化するために使用するフィールドの順序付きリストです。この例では、イベントは host
、pid
、tid
フィールドでグループ化されています。
merge_strategies
は、フィールド名とカスタム統合戦略の対応表です。各値を配列に追加する array
や、すべての数値を加算する sum
など、さまざまな統合戦略が存在します。この例では、concat_newline
を使用して、各文字列の値を連結し、改行で区切ります。
starts_when
はトランザクションの最初のイベントを区別するために使用される条件です。この条件があるイベントに対して true
に解決されると、前のトランザクションはこのイベントなしでフラッシュされ、新しいトランザクションが開始されます。この例では、^[^\\s]
正規表現条件にマッチしない .message
を持つイベントは、1 つのイベントにまとめられます。
上記の構成で、以下の Ruby の例外ログが渡された場合
[{"log":{
"host":"host-1.hostname.com",
"message":"foobar.rb:6:in `/': divided by 0(ZeroDivisionError)",
"pid":1234,
"tid":5678,
"timestamp":"2020-10-07T12:33:21.223543Z"}
},
{
"log":{
"host":"host-1.hostname.com",
"message":"from foobar.rb:6:in `bar'",
"pid":1234,
"tid":5678,
"timestamp":"2020-10-07T12:33:21.223543Z"}
},
{
"log":{
"host":"host-1.hostname.com",
"message":"from foobar.rb:2:in `foo'",
"pid":1234,
"tid":5678,
"timestamp":"2020-10-07T12:33:21.223543Z"}
},
{
"log":{
"host":"host-1.hostname.com",
"message":"from foobar.rb:9:in `\u003cmain\u003e'",
"pid":1234,"tid":5678,
"timestamp":"2020-10-07T12:33:21.223543Z"}
},
{
"log":{
"host":"host-1.hostname.com",
"message":"Hello world, I am a new log",
"pid":1234,
"tid":5678,
"timestamp":"2020-10-07T12:33:22.123528Z"
}}]
以下のログが生成されます。
[{
"log": {
"host":"host-1.hostname.com",
"message":"foobar.rb:6:in `/': divided by 0 (ZeroDivisionError)\n
from foobar.rb:6:in `bar'\n
from foobar.rb:2:in `foo'\n
from foobar.rb:9:in `\u003cmain\u003e'",
"pid":1234,
"tid":5678,
"timestamp":"2020-10-07T12:33:21.223543Z"}
},
{
"log":{
"host":"host-1.hostname.com",
"message":"Hello world, I am a new log",
"pid":1234,
"tid":5678,
"timestamp":"2020-10-07T12:33:22.123528Z"
}}]
ログには不要なフィールドが含まれることがあります。1 日に何テラバイトものデータを処理する場合、不要なフィールドを削除することで、取り込みとインデックス作成を行うログの総数を大幅に削減することができます。
不要なフィールドを削除するには、Vector Remap Language を使ってログデータをリマップします。次の例では、del
を使って不要なタグを削除しています。
transforms:
my_transform_id:
type: remap
inputs:
- my-source-or-transform-id
source: |-
del(.unecessary_env_field)
del(.unecessary_service_field)
del(.unecessary_tag_field)
[transforms.my_transform_id]
type = "remap"
inputs = [ "my-source-or-transform-id" ]
source = """
del(.unecessary_env_field)
del(.unecessary_service_field)
del(.unecessary_tag_field)"""
{
"transforms": {
"my_transform_id": {
"type": "remap",
"inputs": [
"my-source-or-transform-id"
],
"source": "del(.unecessary_env_field)\ndel(.unecessary_service_field)\ndel(.unecessary_tag_field)"
}
}
}
お役に立つドキュメント、リンクや記事: