ログが Logstore に書き込まれる前に、インジェストプロセッサを使用してログを処理します。たとえば、フィールドの変更、フィールドの解析、データフィルタリング、データマスキングなどにインジェストプロセッサを利用できます。本トピックでは、インジェストプロセッサの設定方法について説明します。また、インジェストプロセッサが使用されるユースケースについても解説します。
前提条件
プロジェクトと標準 Logstore が作成され、ログ収集設定が構成されています。詳細については、「プロジェクトの作成」、「Logstore の作成」、および「データ収集」をご参照ください。
ユースケース
生ログから request_method、request_uri、および status フィールドを抽出するには、以下の手順を実行します。
生ログ
body_bytes_sent: 22646
host: www.example.com
http_protocol: HTTP/1.1
remote_addr: 192.168.31.1
remote_user: Elisa
request_length: 42450
request_method: GET
request_time: 675
request_uri: /index.html
status: 200
time_local: 2024-12-04T13:47:54+08:00操作手順
インジェストプロセッサを作成します。
Simple Log Service コンソールにログインします。
プロジェクト一覧で、対象のプロジェクトをクリックします。
左側のナビゲーションウィンドウで、 を選択します。
インジェストプロセッサ タブで、作成 をクリックし、パラメーターを設定して 保存 をクリックします。以下の表にパラメーターを示します。
パラメーター
説明
プロセッサ名
プロセッサの名前を入力します。例:
nginx-logs-text。SPL
Simple Log Service Processing Language (SPL) 文。例:
* | project request_method, request_uri, status詳細については、「SPL 命令」をご参照ください。
エラー処理
SPL によるデータ処理が失敗した場合の動作です。有効な値は以下のとおりです。
生データを保持
生データを破棄
説明本トピックにおける SPL によるデータ処理の失敗とは、SPL 文の実行失敗を指します。たとえば、無効なデータ入力により SPL 文が実行できない場合などが該当します。無効な SPL 構文による失敗は含まれません。
SPL 構文の設定が無効であるためにデータの解析に失敗した場合、デフォルトで生データが保持されます。
インジェストプロセッサを Logstore に関連付けます。
管理対象のプロジェクトの左側ナビゲーションウィンドウで、ログストレージ をクリックし、対象の Logstore の上にポインターを合わせて、。 を選択します。
Logstore 属性 ページの右上隅で、インジェストプロセッサ を選択し、編集 をクリックして、ドロップダウンリストから関連付けるインジェストプロセッサを選択します。その後、保存 をクリックします。
説明関連付けられたインジェストプロセッサは、増分ログに対してのみ有効になります。インジェストプロセッサが有効になるまで、約 1 分かかります。
その他のユースケース
フィールドの変更
project、project-away、project-rename、extendなどの SPL 命令を使用して、データフィールドの追加、削除、変更を行います。以下は、生ログの例です。body_bytes_sent: 22646 host: www.example.com http_protocol: HTTP/1.1 referer: www.example.com remote_addr: 192.168.31.1 remote_user: Elisa request_length: 42450 request_method: PUT request_time: 675 request_uri: /request/path-1/file-6?query=123456 status: 200 time_local: 2024-12-04T13:47:54+08:00ユースケース
要件の説明
SPL 文
結果
特定のフィールドを保持
以下のフィールドのみを保持します。
request_methodrequest_uristatus
* | project request_method, request_uri, statusrequest_method: PUT request_uri: /request/path-1/file-6?query=123456 status: 200以下のフィールドのみを保持し、結果のフィールド名を変更します。
request_methodをmethodに変更。request_uriをuriに変更。status
* | project method=request_method, uri=request_uri, statusmethod: PUT uri: /request/path-1/file-6?query=123456 status: 200request_で始まるすべてのフィールドを保持します。* | project -wildcard "request_*"request_length: 42450 request_method: PUT request_time: 675 request_uri: /request/path-1/file-6?query=123456特定のフィールドを削除
以下のフィールドを削除します。
http_protocolrefererremote_addrremote_user
* | project-away http_protocol, referer, remote_addr, remote_userbody_bytes_sent: 22646 host: www.example.com request_length: 42450 request_method: PUT request_time: 675 request_uri: /request/path-1/file-6?query=123456 status: 200 time_local: 2024-12-04T13:47:54+08:00request_で始まるすべてのフィールドを削除します。* | project-away -wildcard "request_*"body_bytes_sent: 22646 host: www.example.com http_protocol: HTTP/1.1 referer: www.example.com remote_addr: 192.168.31.1 remote_user: Elisa status: 200 time_local: 2024-12-04T13:47:54+08:00フィールドの作成
appという名前のフィールドを追加し、その値をtest-appに設定します。* | extend app='test-app'app: test-app body_bytes_sent: 22646 host: www.example.com http_protocol: HTTP/1.1 referer: www.example.com remote_addr: 192.168.31.1 remote_user: Elisa request_length: 42450 request_method: PUT request_time: 675 request_uri: /request/path-1/file-6?query=123456 status: 200 time_local: 2024-12-04T13:47:54+08:00request_queryという名前のフィールドを追加し、その値をrequest_uriフィールドから抽出します。* | extend request_query=url_extract_query(request_uri)body_bytes_sent: 22646 host: www.example.com http_protocol: HTTP/1.1 referer: www.example.com remote_addr: 192.168.31.1 remote_user: Elisa request_length: 42450 request_method: PUT request_query: query=123456 request_time: 675 request_uri: /request/path-1/file-6?query=123456 status: 200 time_local: 2024-12-04T13:47:54+08:00フィールド名の変更
time_localフィールドをtimeに変更します。* | project-rename time=time_localbody_bytes_sent: 22646 host: www.example.com http_protocol: HTTP/1.1 referer: www.example.com remote_addr: 192.168.31.1 remote_user: Elisa request_length: 42450 request_method: PUT request_time: 675 request_uri: /request/path-1/file-6?query=123456 status: 200 time: 2024-12-04T13:47:54+08:00フィールド値の変更
request_uriフィールドを処理し、パス部分のみを保持してパラメーターを破棄します。* | extend request_uri=url_extract_path(request_uri)または
* | extend request_uri=regexp_replace(request_uri, '\?.*', '')body_bytes_sent: 22646 host: www.example.com http_protocol: HTTP/1.1 referer: www.example.com remote_addr: 192.168.31.1 remote_user: Elisa request_length: 42450 request_method: PUT request_time: 675 request_uri: /request/path-1/file-6 status: 200 time_local: 2024-12-04T13:47:54+08:00フィールドの解析
parse-regexp、parse-json、parse-csvなどの SPL 命令および正規表現や JSON 用の SQL 関数を使用して、データフィールドを解析・抽出します。ユースケース
生データ
要件の説明
SPL 文
結果
正規表現モードでのデータ解析
content: 192.168.1.75 - David [2024-07-31T14:27:24+08:00] "PUT /request/path-0/file-8 HTTP/1.1" 819 21577 403 73895 www.example.com www.example.com "Mozilla/5.0 (Windows NT 5.2; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.41 Safari/535.1"正規表現を使用して NGINX アクセスログからフィールドを抽出し、元の
contentフィールドを破棄します。* | parse-regexp content, '(\S+)\s-\s(\S+)\s\[(\S+)\]\s"(\S+)\s(\S+)\s(\S+)"\s(\d+)\s(\d+)\s(\d+)\s(\d+)\s(\S+)\s(\S+)\s"(.*)"' as remote_addr, remote_user, time_local, request_method, request_uri, http_protocol, request_time, request_length, status, body_bytes_sent, host, referer, user_agent | project-away contentbody_bytes_sent: 73895 host: www.example.com http_protocol: HTTP/1.1 referer: www.example.com remote_addr: 192.168.1.75 remote_user: David request_length: 21577 request_method: PUT request_time: 819 request_uri: /request/path-0/file-8 status: 403 time_local: 2024-07-31T14:27:24+08:00 user_agent: Mozilla/5.0 (Windows NT 5.2; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.41 Safari/535.1request_method: PUT request_uri: /request/path-0/file-8 status: 200file-8をrequest_uriフィールドから抽出し、新しいフィールド名をfileとします。* | extend file=regexp_extract(request_uri, 'file-.*')file: file-8 request_method: PUT request_uri: /request/path-0/file-8 status: 200JSON モードでのデータ解析
headers: {"Authorization": "bearer xxxxx", "X-Request-ID": "29bbe977-9a62-4e4a-b2f4-5cf7b65d508f"}headersフィールドを JSON として解析し、元のheadersフィールドを破棄します。* | parse-json headers | project-away headersAuthorization: bearer xxxxx X-Request-ID: 29bbe977-9a62-4e4a-b2f4-5cf7b65d508fheadersフィールドから特定のフィールドを抽出します。たとえば、Authorizationフィールドを抽出し、新しいフィールド名をtokenとします。* | extend token=json_extract_scalar(headers, 'Authorization')headers: {"Authorization": "bearer xxxxx", "X-Request-ID": "29bbe977-9a62-4e4a-b2f4-5cf7b65d508f"} token: bearer xxxxxrequest: {"body": {"user_id": 12345, "user_name": "Alice"}}bodyサブフィールドをrequestフィールド内から JSON として解析します。* | parse-json -path='$.body' requestrequest: {"body": {"user_id": 12345, "user_name": "Alice"}} user_id: 12345 user_name: Alice区切り文字モードでのデータ解析
content: 192.168.0.100,"10/Jun/2019:11:32:16,127 +0800",www.example.comカンマでフィールドを分割し、元の
contentフィールドを破棄します。* | parse-csv -quote='"' content as ip, time, host | project-away contenthost: www.example.com ip: 192.168.0.100 time: 10/Jun/2019:11:32:16,127 +0800content: 192.168.0.100||10/Jun/2019:11:32:16,127 +0800||www.example.com区切り文字として
||を使用してフィールドを分割し、元のcontentフィールドを破棄します。* | parse-csv -delim='||' content as ip, time, host | project-away contenthost: www.example.com ip: 192.168.0.100 time: 10/Jun/2019:11:32:16,127 +0800データフィルタリング
where命令を使用してデータをフィルタリングします。SPL によるデータ処理中は、生データ内のすべてのフィールドがデフォルトでテキストとして扱われることに注意してください。数値を処理する前に、必要なフィールドの値をデータの型変換関数で変換する必要があります。詳細については、「データの型変換関数」をご参照ください。
生データ
要件の説明
SPL 文
結果
request_id: ddbde824-7c3e-4ff1-a6d1-c3a53fd4a919 status: 200 --- request_id: 7f9dad20-bc57-4aa7-af0e-436621f1f51d status: 500statusが200のデータのみを保持します。* | where status='200'または
* | where cast(status as bigint)=200request_id: ddbde824-7c3e-4ff1-a6d1-c3a53fd4a919 status: 200request_id: ddbde824-7c3e-4ff1-a6d1-c3a53fd4a919 status: 200 --- request_id: 7f9dad20-bc57-4aa7-af0e-436621f1f51d status: 500 error: something wrongerrorフィールドを含まないデータのみを保持します。* | where error is nullrequest_id: ddbde824-7c3e-4ff1-a6d1-c3a53fd4a919 status: 200errorフィールドを含むデータのみを保持します。* | where error is not nullrequest_id: 7f9dad20-bc57-4aa7-af0e-436621f1f51d status: 500 error: something wrongmethod: POST request_uri: /app/login --- method: GET request_uri: /user/1/profile status: 404 --- method: GET request_uri: /user/2/profile status: 200request_uriが/user/で始まるデータのみを保持します。* | where regexp_like(request_uri, '^\/user\/')method: GET request_uri: /user/1/profile status: 404 --- method: GET request_uri: /user/2/profile status: 200request_uriが/user/で始まり、かつstatusが200のデータを保持します。* | where regexp_like(request_uri, '^\/user\/') and status='200'method: GET request_uri: /user/2/profile status: 200データマスキング
マスク関数の使用
マスク関数 は、組み込みルールおよびキーワード一致をサポートしており、構造化データおよび非構造化データを正確にマスクできます。
生データ
要件の説明
SPL 文
結果
client_ip: 192.168.1.123 latency: 100IP アドレスをマスクします。
* | extend client_ip = mask(client_ip,'[ {"mode":"buildin","types":["IP_ADDRESS"],"maskChar":"*","keepPrefix":3,"keepSuffix":3} ]')client_ip: 192*****123 latency: 1002025-08-20 18:04:40,998 INFO blockchain-event-poller-3 [10.0.1.20] [com.service.listener.TransactionStatusListener:65] [TransactionStatusListener#handleSuccessfulTransaction]{"message":"On-chain transaction successfully confirmed","confirmationDetails":{"transactionHash":"0x2baf892e9a164b1979","status":"success","blockNumber":45101239,"gasUsed":189543,"effectiveGasPrice":"58.2 Gwei","userProfileSnapshot":{"wallet":"0x71C7656EC7a5f6d8A7C4","sourceIp":"203.0.113.55","phone":"19901012345","address":"123 Main St, Anytown, USA","birthday":null}}}ウォレットアドレス、住所情報、ソース IP、電話番号、トランザクションハッシュなど、ログ内の機密フィールドをマスクします。
*| extend content = mask(content,'[ {"mode":"keyword","keys":["wallet","address","sourceIp","phone","transactionHash"], "maskChar":"*","keepPrefix":3,"keepSuffix":3} ]')2025-08-20 18:04: 40, 998 INFO blockchain-event-poller-3 [10.0.1.20][com.service.listener.TransactionStatusListener: 65]][TransactionStatusListener#handleSuccessfulTransaction]{"message": "オンチェーンでのトランザクションが正常に確認されました", "confirmationDetails": {"transactionHash": "0×2**************979", "status": "success", "blockNumber": 45101239, "gasUsed": 189543, "effectiveGasPrice": "58.2 Gwei", "userProfileSnapshot": {"wallet": "0x7****************7C4", "sourceIp": "203******.55", "phone": "199*****345", "address": "Shanghai*********No. 00", "birthday": null}}}正規表現の使用
SPL の
extend命令と、正規表現、文字列、URL 用の SQL 関数を併用してデータをマスクします。regexp_replace関数を使用して正規表現に基づいてフィールド値を置き換える場合、キャプチャグループを使用します。置換値を指定する際には、\1、\2などを使用して、それぞれ第 1、第 2、以降のキャプチャグループの値を表します。たとえば、
regexp_replace('192.168.1.1', '(\d+)\.(\d+)\.\d+\.\d+', '\1.\2.*.*')の結果は192.168.*.*となります。生データ
要件の説明
SPL 文
結果
request_uri: /api/v1/resources?user=123&ticket=abc status: 200request_uriパラメーターには機密情報が含まれており、これを削除する必要があります。* | extend request_uri=url_extract_path(request_uri)または
* | extend request_uri=regexp_replace(request_uri, '\?.*', '')request_uri: /api/v1/resources status: 200client_ip: 192.168.1.123 latency: 100IP アドレスの中間 2 オクテットをアスタリスク (*) でマスクします。
* | extend client_ip=regexp_replace(client_ip, '(\d+)\.\d+\.\d+\.(\d+)', '\1.*.*.\2')client_ip: 192.*.*.123 latency: 100sql: SELECT id, name, config FROM app_info WHERE name="test-app" result_size: 1024sqlフィールドには機密情報が含まれている可能性があるため、操作と対応するテーブル名のみを保持する必要があります。* | extend table=regexp_extract(sql, '\bFROM\s+([^\s;]+)|\bINTO\s+([^\s;]+)|\bUPDATE\s+([^\s;]+)', 1) | extend action=regexp_extract(sql,'\b(SELECT|INSERT|UPDATE|DELETE|CREATE|DROP|ALTER)\b', 1) | project-away sqlaction: SELECT table: app_info result_size: 1024