検索ジョブ API について
検索ジョブ API はエンタープライズ アカウントで利用できます。検索ジョブ API では、サードパーティ スクリプトやアプリケーションからアクセス キー/アクセス ID 認証によってログ データにアクセスできます。この API は Representational State Transfer (REST) パターンに従い、使いやすさと一貫性を実現するために最適化されています。
検索ジョブの要件
検索ジョブの実行中は、検索ジョブ ID に基づいてジョブ ステータスをリクエストする必要があります。API は、ステータスのポーリングまたは結果の収集によって検索ジョブの動作を継続します。検索ジョブが API リクエストによって継続されないと、5 分後にキャンセルされます。何も処理が行われずに 5 分経過して検索ジョブがキャンセルされると、404 ステータスが返されます。
検索ジョブに対する以降のリクエストでは、Cookie を有効にする必要があります。以降のリクエストで 404 ステータス (Page Not Found) が返される理由としては、Cookie が有効ではないことが考えられます。
API がポーリングやリクエストを継続していても、クエリは 8 時間でタイムアウトとなります。実行しているクエリ数が非常に少なければもう少し長く存続する場合もありますが、大半のクエリは 8 時間でタイムアウトとなります。
まとめると、次の 2 つの状況では 404 ステータスとなります。
- Cookie が無効である場合
- クエリ セッションがキャンセルされた場合
API アクセス用のエンドポイント
Sumo Logic には複数のデプロイがあり、アカウントが作成された地理的位置と日付に応じて割り当てられます。API を使用したアクセスでは、手動で API クライアントを正しい Sumo Logic API URL にダイレクトする必要があります。
URL のリストについては「Sumo Logic エンドポイント」を参照してください。
API 認証
レート制限の調整
- ユーザからのすべての API コールには、最大で毎秒 4 件 (毎分 240 件) の API リクエストというレート制限が適用されます。
- また、同じアクセス キーには、どの API エンドポイントでも最大で同時に 10 件のリクエストというレート制限が適用されます。
このレートを超えると、rate limit exceeded (レート制限超過) の 429 ステータス コードが返されます。
- 組織に適用される同時に実行できる検索ジョブ数の上限は 200 件です。
実行中の検索ジョブが 200 件に達した状態で新たな検索を実行しようとすると、429 Too Many Requests (リクエストが多すぎます) のエラーとなり、検索ジョブの上限に達したことが通知されます。
この制限は検索ジョブ API による検索にのみ適用され、Sumo UI から実行した検索、Scheduled Search、またはダッシュボード パネルから実行した検索が同時に存在していても、それらには適用されません。検索ジョブが API リクエストによって継続されないと、5 分後にキャンセルされます。
実際の検索ジョブ数を減らすには、結果を受信した後で検索を明示的に削除してください。検索を削除することで、アクティブな検索ジョブ数が減るため、検索ジョブ API の上限に達する可能性を抑えることができます。詳細については「検索ジョブの削除」を参照してください。
プロセス フロー
検索ジョブのプロセス フローを下図に示します。
- リクエスト。クエリと時間範囲を指定することで、検索ジョブをリクエストします。
- 応答。Sumo がジョブ ID を返します。リクエストに問題がある場合は、エラー コードが返されます (図の下にあるエラー コード表を参照してください)。
- リクエスト。ジョブ ID を使用してサーチ ステータスをリクエストします。何も処理が行われないために検索セッションがキャンセルされないように、最低でも 5 分に 1 回は行う必要があります。
- 応答。Sumo がジョブ ステータスを返します。リクエストを完了できない場合は、エラー コード (404) が返されます。
ステータスには、検索ジョブの現在のステータス (結果の収集中、実行完了など) が含まれます。また、検索中に見つかったメッセージの件数や、結果から生成されたレコードの件数も含まれます。非集計クエリの場合はメッセージ件数のみが返されます。非集計クエリの場合は、生成されたレコード件数も返されます。検索ジョブ ステータスを見ると、検索ジョブで指定された時間範囲で見つかったメッセージの分布を知ることができます。実行中や実行後に、API を使用して、返されたメッセージやレコードをページ単位で見ることができます。 - リクエスト。結果を要求します。サーチが完了する前でも結果を要求できます。このプロセスは非同期に行われます。リクエストは必要なだけ何度でも繰り返すことができ、最新の結果を見ることができます。ただし、レート制限には注意してください。検索ジョブ API は、検索クエリごとに最大 1000 万件のレコードを返します。
- 応答。Sumo は、リクエストに応じて JSON 形式の検索結果を返します。API では、部分的な結果をページ単位で見ることができ、その間も新しい結果が追加されます。結果に問題がある場合はエラー コードが返されます (図の下にある表を参照してください)。
エラー
すべての API に適用される一般エラー
コード | エラー | 説明 |
301 | moved | リクエストされたリソースには、ロケーション ヘッダで返された URI でアクセスする必要があります。 |
401 | unauthorized | 資格情報を検証できませんでした。 |
403 | forbidden | ユーザのアカウント タイプではこの操作は禁止されています。 |
404 | not found | リクエストされたリソースが見つかりませんでした。 |
405 | method.unsupported | URL に対してサポートされていないメソッドです。 |
415 | contenttype.invalid | コンテンツ タイプが無効です。 |
429 | rate.limit.exceeded | API のリクエスト レートが毎秒 4 件を超えたか、組織の同時にアクティブな検索ジョブ数が制限の 200 を超えました。 |
500 | internal.error | 内部のサーバ エラーです。 |
503 | service.unavailable | 現在、サービスを利用できません。 |
検索クエリの作成 (プロセス フローの 2) で発生するエラー
コード | エラー | 説明 |
400 | generic | 一般エラー。 |
400 | invalid.timestamp.to | to フィールドの時間が無効です。 |
400 | invalid.timestamp.from | from フィールドの時間が無効です。 |
400 | to.smaller.than.from | from フィールドの時間は to フィールドの時間より前でなければなりません。 |
400 | unknown.timezone | timezone 値が既知のタイム ゾーンではありません。タイム ゾーン コードのリストについては、この Wikipedia 記事を参照してください。 |
400 | empty.timezone | timezone フィールドには値が必要です。 |
400 | no.query | query パラメータがありません。 |
400 | unknown.time.type | 時間タイプが無効です。 |
400 | parse.error | クエリを parse できません。 |
ステータスのリクエスト (プロセス フローの 3) で発生するエラー
コード | エラー | 説明 |
404 | "jobid.invalid" | "Job ID is invalid." |
結果セットのページ単位表示 (プロセス フローの 5) で発生するエラー
コード | エラー | 説明 |
400 | "jobid.invalid" | "Job ID is invalid." |
400 | "offset.missing" | "Offset is missing." |
400 | "offset.negative" | "Offset cannot be negative." |
400 | "limit.missing" | "Limit is missing." |
400 | "limit.zero" | "Limit cannot be 0." |
400 | "limit.negative" | "Limit cannot be negative." |
400 | "no.records.not.an.aggregation.query" | "No records; query is not an aggregation" |
検索ジョブ メソッド
検索ジョブの作成
検索ジョブを作成するには (プロセス フローの手順 1)、検索ジョブ エンドポイントに JSON リクエストを送信します。
メソッド: POST
エンドポイントの例:
https://api.sumologic.com/api/v1/search/jobs
ヘッダ
ヘッダ | 値 |
Content-Type | application/json |
Accept | application/json |
クエリ パラメータ
パラメータ | タイプ | 必須 | 説明 |
query | 文字列 | はい | 実際の検索式。クエリは有効な JSON 形式で、特定の文字をエスケープする必要があります。 |
from | 文字列 | はい | ISO 8601 形式で、検索を開始する日付と時刻を指定します。 たとえば、2017 年 7 月 16 日であれば、YYYY-MM-DDTHH:mm:ss または 2017-07-16T00:00:00 と指定します。 エポック時刻からのミリ秒数で指定することもできます。 |
to | 文字列 | はい | ISO 8601 形式で、検索を終了する日付と時刻を指定します。 たとえば、2017 年 7 月 26 日であれば、YYYY-MM-DDTHH:mm:ss または 2017-07-26T00:00:00 と指定します。 エポック時刻からのミリ秒数で指定することもできます。 |
timeZone | 文字列 | はい | from と to がミリ秒数ではない場合にタイム ゾーンを指定します。 タイム ゾーン コードのリストについては、この Wikipedia 記事を参照してください。 |
byReceiptTime | ブール | 不可 | true と指定すると、受信時刻を使用して検索を実行します。デフォルトでは受信時刻を使用して検索を行いません。 |
ステータス コード
コード | テキスト | 説明 |
202 | Accepted (受け入れ) | 検索ジョブが正常に作成されました。 |
400 | Bad Request (無効なリクエスト) | クライアントによる一般リクエスト エラー。 |
415 | Unsupported Media Type (サポートされていないメディア タイプ) | Content-Type が application/json に設定されていません。 |
応答ヘッダ
ヘッダ | 値 |
ロケーション |
https://api.sumologic.com/api/v1/search/jobs/SEARCH_JOB_ID |
結果
新たに作成された検索ジョブの ID を含む JSON ドキュメント。この ID は、検索ジョブに関連するすべての API インタラクションで使用します。
エラー応答の例:
{ "status" : 400, "id" : "IUUQI-DGH5I-TJ045", "code" : "searchjob.invalid.timestamp.from", "message" : "The 'from' field contains an invalid time." }
セッション例
以下のセッション例では cURL を使用しています。検索ジョブ API では、クライアント側で Cookie が有効であることが要件となります。curl -b cookies.txt -c cookies.txtoptions を使用して、API が設定した Cookie を受信、格納、および送り返します。
curl -b cookies.txt -c cookies.txt -H 'Content-type: application/json' -H 'Accept: application/json' -X POST -T createSearchJob.json --user <ACCESSID>:<ACCESSKEY> https://api.sumologic.com/api/v1/search/jobs
createSearchJob.json ファイルの内容は次のようになります。
{ "query": "| count _sourceCategory", "from": "2019-05-03T12:00:00", "to": "2019-05-03T12:05:00", "timeZone": "IST", "byReceiptTime": true }
Sumo Logic からの応答では、「ロケーション」ヘッダとして次の形式で検索ジョブ ID が返されます。
https://api.sumologic.com/api/v1/search/jobs/SEARCH_JOB_ID
現在の検索ジョブ ステータスの取得
検索ジョブ ID を使用して、検索ジョブの現在のステータスを取得します (プロセス フローの手順 4)。
メソッド: GET
エンドポイントの例:
https://api.sumologic.com/api/v1/search/jobs/SEARCH_JOB_ID
クエリ パラメータ
パラメータ | タイプ | 必須 | 説明 |
searchJobId | 文字列 | はい | 検索ジョブの ID。 |
結果
結果は、検索ジョブ ステータス、現時点までに見つかったメッセージ件数、現時点までに生成されたレコード件数、保留中の警告やエラー、およびヒストグラム バケットを含む JSON ドキュメントです。
セッション例
curl -v --trace-ascii - -b cookies.txt -c cookies.txt -H 'Accept: application/json' --user <ACCESSID>:<ACCESSKEY> https://api.sumologic.com/api/v1/search/jobs/37589506F194FC80
フォーマットされた結果ドキュメントは次のようになります。
{ "state":"DONE GATHERING RESULTS", "messageCount":90, "histogramBuckets":[ { "length":60000, "count":1, "startTimestamp":1359404820000 }, { "length":60000, "count":1, "startTimestamp":1359405480000 }, ... { "length":60000, "count":1, "startTimestamp":1359404340000 } ], "pendingErrors":[ ], "pendingWarnings":[ ], "recordCount":1 }
サンプル結果ジョブのステータスは DONE GATHERING RESULTS (結果の収集完了) になっています。返されるステータスを下表に示します。
ステータス | 説明 |
NOT STARTED (開始されていません) | 検索ジョブがまだ開始されていません。 |
GATHERING RESULTS (結果の収集中) | 検索ジョブは結果の収集を続けていますが、すでに結果が表示可能である場合もあります。 |
FORCE PAUSED (強制停止) | システムによってクエリが強制的に一時停止されています。非集計クエリに限り、100K の上限で一時停止されます。この上限は動的であり、ユーザ環境によって異なります。 |
DONE GATHERING RESULTS (結果の収集完了) | 検索ジョブが結果の収集を完了しました。指定された時間範囲全体で検索が完了しました。 |
CANCELLED | 検索ジョブがキャンセルされました。綴りの L の文字が 2 つあることに注意してください。 |
結果の詳細
messageCount と recordCount の値は、現時点までに見つかったメッセージの件数と生成されたレコードの件数を示します。メッセージは未処理のログ メッセージで、レコードは集計データです。
aggregation operator を含まないクエリの場合はメッセージのみが返されます。クエリに集計が含まれる場合 (例: count by _sourceCategory) は (SQL データベースから返される結果と同じように) メッセージと集計結果のレコードの両方が返されます。
pendingErrors と pendingWarnings の値には、前回のステータスのリクエスト時から蓄積している保留中のエラー文字列または警告文字列が含まれます。
エラーと警告は保存されません。エラーや警告を取っておく必要がある場合は、ローカルに保存してください。
histogramBuckets 値には、ヒストグラム バケットのリストが返されます。ヒストグラム バケットは、バケット開始時のタイムスタンプ (ミリ秒数) とバケットの幅を表す長さ (ミリ秒数) で定義されます。timestampplus 長は、バケットの終了タイムスタンプであるため、カウントはバケット内のメッセージ数となります。
ヒストグラムに対応するヒストグラム バケットは、Sumo Logic のインタラクティブ アナリティクス API に表示されます。ヒストグラム バケットは保存されません。ステータス API は前回のステータス リクエスト以降に発見された新しいバケットしか返しませんので、バケットを使用する予定がある場合は、クライアント側で保存する必要があります。Sumo Logic バックエンドの検索ジョブは、常に指定された時間範囲の最後から最初に向かって、一致するメッセージを発見して処理することで実行されます。このプロセスにおいて、ヒストグラム バケットが検出されて返されます。
検索ジョブで検出されたメッセージのページング
検索ジョブのステータスには、検出されたメッセージの件数が含まれます。メッセージは、ページング API コールでリクエストできます (プロセス フローの手順 6)。メッセージは、常に _messageTime 値の順番になります。
メソッド: GET
エンドポイントの例:
https://api.sumologic.com/api/v1/search/jobs/SEARCH_JOB_ID/messages?offset=OFFSET&limit=LIMIT
クエリ パラメータ
パラメータ | タイプ | 必須 | 説明 |
searchJobId | 文字列 | はい | 検索ジョブの ID。 |
offset | 整数 | はい | このオフセット以降のメッセージを返します。 |
limit | 整数 | はい | オフセット以降で返すメッセージの数。最大値はメッセージ 10,000 件または合計サイズ 100 MB であり、先にサイズが上限に達した場合には返される、メッセージが 10,000 件未満となる場合もあります。 |
セッション例
curl -b cookies.txt -c cookies.txt -H 'Accept: application/json' --user <ACCESSID>:<ACCESSKEY> 'https://api.sumologic.com/api/v1/search/jobs/37589506F194FC80/messages?offset=0&limit=10'
フォーマットされた結果ドキュメントは次のようになります。
{ "fields":[ { "name":"_messageid", "fieldType":"long", "keyField":false }, { "name":"_sourceid", "fieldType":"long", "keyField":false }, { "name":"_sourcename", "fieldType":"string", "keyField":false }, { "name":"_sourcehost", "fieldType":"string", "keyField":false }, { "name":"_sourcecategory", "fieldType":"string", "keyField":false }, { "name":"_format", "fieldType":"string", "keyField":false }, { "name":"_size", "fieldType":"long", "keyField":false }, { "name":"_messagetime", "fieldType":"long", "keyField":false }, { "name":"_receipttime", "fieldType":"long", "keyField":false }, { "name":"_messagecount", "fieldType":"int", "keyField":false }, { "name":"_raw", "fieldType":"string", "keyField":false }, { "name":"_source", "fieldType":"string", "keyField":false }, { "name":"_collectorid", "fieldType":"long", "keyField":false }, { "name":"_collector", "fieldType":"string", "keyField":false }, { "name":"_blockid", "fieldType":"long", "keyField":false } ], "messages":[ { "map":{ "_receipttime":"1359407350899", "_source":"service", "_collector":"local", "_format":"plain:atp:o:0:l:29:p:yyyy-MM-dd HH:mm:ss,SSS ZZZZ", "_blockid":"-9223372036854775669", "_messageid":"-9223372036854773763", "_messagetime":"1359407350333", "_collectorid":"1579", "_sourcename":"/Users/christian/Development/sumo/ops/assemblies/latest/service-20.1-SNAPSHOT/logs/service.log", "_sourcehost":"Chiapet.local", "_raw":"2013-01-28 13:09:10,333 -0800 INFO [module=SERVICE] [logger=util.scala.zk.discovery.AWSServiceRegistry] [thread=pool-1-thread-1] FINISHED findRunningInstances(ListBuffer((Service: name: elasticache-1, defaultProps: Map()), (Service: name: userAndOrgCache, defaultProps: Map()), (Service: name: rds_cloudcollector, defaultProps: Map()))) returning Map((Service: name: elasticache-1, defaultProps: Map()) -> [], (Service: name: userAndOrgCache, defaultProps: Map()) -> [], (Service: name: rds_cloudcollector, defaultProps: Map()) -> []) after 1515 ms", "_size":"549", "_sourcecategory":"service", "_sourceid":"1640", "_messagecount":"2044" } }, ... { "map":{ "_receipttime":"1359407051885", "_source":"service", "_collector":"local", "_format":"plain:atp:o:0:l:29:p:yyyy-MM-dd HH:mm:ss,SSS ZZZZ", "_blockid":"-9223372036854775674", "_messageid":"-9223372036854773772", "_messagetime":"1359407049529", "_collectorid":"1579", "_sourcename":"/Users/christian/Development/sumo/ops/assemblies/latest/service-20.1-SNAPSHOT/logs/service.log", "_sourcehost":"Chiapet.local", "_raw":"2013-01-28 13:04:09,529 -0800 INFO [module=SERVICE] [logger=com.netflix.config.sources.DynamoDbConfigurationSource] [thread=pollingConfigurationSource] Successfully polled Dynamo for a new configuration based on table:raychaser-chiapetProperties", "_size":"246", "_sourcecategory":"service", "_sourceid":"1640", "_messagecount":"2035" } } ] }
結果の詳細
結果には fields と messages の 2 つのリストがあります。
- fields には、返された各メッセージで定義されているすべてのフィールドのリストが含まれます。各フィールドについて、フィールド名とフィールド タイプが返されます。
- messages には、マップのリストが含まれ、各メッセージについて 1 つのマップとなります。各マップは、fields に含まれるフィールドからメッセージの実際の値にマップします。
たとえば、_raw フィールドには、収集された未処理のログメッセージが含まれます。
_messagetime は、メッセージ自身から抽出したタイムスタンプの、エポック時刻からのミリ秒数です。
_receipttime は、メッセージが Sumo Logic システムに到着したタイムスタンプの、エポック時刻からのミリ秒数です。
Sumo Logic でも使用されているメタデータ フィールドの _sourcehost、_sourcename、および _sourcecategory は、ここでも使用されます。
検索ジョブで検出されたレコードのページング
クエリで集計を実行する場合、検索ジョブのステータスには、生成されたレコードの件数が含まれます。これらのレコードは、メッセージのリクエスト時と同じように、ページング API コールでリクエストできます (プロセス フローの手順 6)。
メソッド: GET
エンドポイントの例:
https://api.sumologic.com/api/v1/search/jobs/SEARCH_JOB_ID/records?offset=OFFSET&limit=LIMIT
クエリ パラメータ
パラメータ | タイプ | 必須 | 説明 |
searchJobId | 文字列 | はい | 検索ジョブの ID。 |
offset | 整数 | はい | このオフセット以降のレコードを返します。 |
limit | 整数 | はい | オフセット以降で返すレコードの数。上限は 10,000 レコードです。 |
セッション例
curl -b cookies.txt -c cookies.txt -H 'Accept: application/json' --user <ACCESSID>:<ACCESSKEY> 'https://api.sumologic.com/api/v1/search/jobs/37589506F194FC80/records?offset=0&limit=1'
フォーマットされた結果ドキュメントは次のようになります。
{ "fields":[ { "name":"_sourcecategory", "fieldType":"string", "keyField":true }, { "name":"_count", "fieldType":"int", "keyField":false } ], "records":[ { "map":{ "_count":"90", "_sourcecategory":"service" } } ] }
返されるドキュメントは、メッセージ ページング API と同様です。返されるレコードのスキーマは、fields 要素の一部であるフィールド リストによって記述されます。レコード自身はマップのリストです。
検索ジョブの削除
検索ジョブは最終的には Sumo Logic バックエンドでタイムアウトとなりますが、不要になった検索ジョブは明示的にキャンセルするのがよいでしょう。
メソッド: DELETE
エンドポイントの例:
https://api.sumologic.com/api/v1/search/jobs/SEARCH_JOB_ID
クエリ パラメータ
パラメータ | タイプ | 必須 | 説明 |
searchJobId | 文字列 | はい | 検索ジョブの ID。 |
セッション例
curl -b cookies.txt -c cookies.txt -X DELETE -H 'Accept: application/json' --user <ACCESSID>:<ACCESSKEY> https://api.sumologic.com/api/v1/search/jobs/37589506F194FC80
検索ジョブの Bash
以下のスクリプトを使用して API を実行できます。
#!/bin/bash # Variables. PROTOCOL=$1 # HTTPS is the only acceptable PROTOCOL HOST=$2 # Use your Sumo endpoint as the HOST ACCESSID=$3 # Authenticate with an access id and key ACCESSKEY=$4 OPTIONS="--silent -b cookies.txt -c cookies.txt" #OPTIONS="-v -b cookies.txt -c cookies.txt" #OPTIONS="-v --trace-ascii -b cookies.txt -c cookies.txt" # # Create a search job from a JSON file. # RESULT=$(curl $OPTIONS \ -H "Content-type: application/json" \ -H "Accept: application/json" \ -d @createSearchJob.json \ --user $ACCESSID:$ACCESSKEY \ "$PROTOCOL://$HOST/api/v1/search/jobs") JOB_ID=$(echo $RESULT | perl -pe 's|.*"id":"(.*?)"[,}].*|\1|') echo Search job created, id: $JOB_ID # # Wait until the search job is done. # STATE="" until [ "$STATE" = "DONE GATHERING RESULTS" ]; do sleep 5 RESULT=$(curl $OPTIONS \ -H "Accept: application/json" \ --user $ACCESSID:$ACCESSKEY \ "$PROTOCOL://$HOST/api/v1/search/jobs/$JOB_ID") STATE=$(echo $RESULT | sed 's/.*"state":"\(.*\)"[,}].*/\1/') MESSAGES=$(echo $RESULT | perl -pe 's|.*"messageCount":(.*?)[,}].*|\1|') RECORDS=$(echo $RESULT | perl -pe 's|.*"recordCount":(.*?)[,}].*|\1|') echo Search job state: $STATE, message count: $MESSAGES, record count: $RECORDS done # # Get the first ten messages. # RESULT=$(curl $OPTIONS \ -H "Accept: application/json" \ --user $ACCESSID:$ACCESSKEY \ "$PROTOCOL://$HOST/api/v1/search/jobs/$JOB_ID/messages?offset=0&limit=10") echo Messages: echo $RESULT # # Get the first 2 records. # RESULT=$(curl $OPTIONS \ -H "Accept: application/json" \ --user $ACCESSID:$ACCESSKEY \ "$PROTOCOL://$HOST/api/v1/search/jobs/$JOB_ID/records?offset=0&limit=1") echo Records: echo $RESULT # # Delete the search job. # RESULT=$(curl $OPTIONS \ -X DELETE \ -H "Accept: application/json" \ --user $ACCESSID:$ACCESSKEY \ "$PROTOCOL://$HOST/api/v1/search/jobs/$JOB_ID") JOB_ID=$(echo $RESULT | sed 's/^.*"id":"\(.*\)".*$/\1/') echo Search job deleted, id: $JOB_ID