非同步 Search API
Google Security Operations 的搜尋平台可讓您使用非同步 API,執行長時間執行的查詢,傳回最多 100 萬筆結果的大型結果集。這些 API 可讓您在不封鎖應用程式的情況下,跨資料來源 (包括 Unified Data Model (UDM) 事件、偵測結果、資料表和 Entity Context Graph (ECG)) 啟動搜尋。使用長時間執行的作業 (LRO) API 執行搜尋查詢時,您會收到作業 ID。您可以使用這個 ID 監控作業狀態,並逐頁取得結果。
必要條件
如要使用長時間執行的作業 API,呼叫主體必須具備特定的 Identity and Access Management (IAM) 權限。
您必須具備相應的身分與存取權管理權限,才能執行下列動作:
- 發起搜尋:
chronicle.searchSessions.search - 清單結果:
SearchSession資源上的chronicle.searchedResults.list。
請確認呼叫主體具備授予這些權限的角色,例如 Chronicle API 檢視者、Chronicle API 編輯者或 Chronicle API 管理員角色。
使用 LRO API 執行搜尋
請按照下列步驟,使用 LRO API 執行搜尋:
開始搜尋
向 Google SecOps 執行個體上的 search 自訂方法傳送 POST 要求。
- 端點:
POST /{$api_version}/projects/{project}/locations/{location}/instances/{instance}:search - 方法:
Search - 要求主體:
SearchRequest
以下範例顯示 SearchRequest 物件:
{
"parent": "projects/PROJECT_NUMBER/locations/LOCATION/instances/INSTANCE_ID",
"query": "metadata.event_type = \"USER_LOGIN\"",
"time_range": {},
"start_time": "2026-03-16T14:40:13Z",
"endTime": "2026-03-16T15:40:13Z",
"dialect": "YL2"
}
要求需要下列重要參數:
query:搜尋查詢字串。time_range:搜尋的時間間隔。dialect:將語言方言指定為YL2。- 使用
ListSearchedResults(searchedResults.list) 非同步擷取 LRO 結果時,不支援SQL方言。 RAW_LOG方言目前為預先發布版,如果執行個體未啟用,可能會傳回501 UNIMPLEMENTED錯誤。
- 使用
result_limit:選用。要具體化的資料列數量上限。預設值為10000,最大值為1000000。simulated_data_visibility(或 JSON 中的simulatedDataVisibility):選用。控管搜尋結果是否包含模擬事件。設為SIMULATED_DATA_INCLUDED,即可在搜尋結果中納入模擬事件。如未指定,這個參數會預設為SIMULATED_DATA_EXCLUDED,排除模擬事件。
這項呼叫會傳回 google.longrunning.Operation 物件。
以下範例顯示作業成功的回應:
{
"name": "projects/PROJECT_NUMBER/locations/LOCATION/instances/INSTANCE_ID/operations/OPERATION_ID",
"metadata": {
"@type": "[type.googleapis.com/google.cloud.chronicle.v1main.SearchOperationMetadata](https://type.googleapis.com/google.cloud.chronicle.v1main.SearchOperationMetadata)",
"state": "RUNNING",
"start_time": "2026-03-13T10:00:00Z"
}
}
state: RUNNING 欄位表示搜尋作業正在進行中。
監控作業
使用 google.longrunning.Operations 服務中的標準 GetOperation 方法,輪詢 LRO 的狀態。使用先前回應中的 name 值。
- 端點:
GET /{$api_version}/projects/{project}/locations/{location}/instances/{instance}/operations/{operationID}
持續輪詢,直到 GetOperation 回應中的 done 欄位傳回 true 為止。
- 如果作業成功,
metadata.state欄位會傳回SUCCEEDED,且回應欄位會包含建立的SearchSession資源。 - 如果作業失敗,
done欄位會傳回true,且錯誤欄位會包含相關失敗詳細資料。
以下範例顯示成功的 GetOperation 回應:
{
"name": "projects/PROJECT_NUMBER/locations/LOCATION/instances/INSTANCE_ID/operations/OPERATION_ID",
"metadata": {
"@type": "[type.googleapis.com/google.cloud.chronicle.v1main.SearchOperation](https://type.googleapis.com/google.cloud.chronicle.v1main.SearchOperation) Metadata",
"state": "SUCCEEDED",
"startTime": "2026-03-16T15:42:11.037506921Z"
},
"endTime": "2026-03-16T15:42:17.504730842Z",
"expireTime": "2026-03-17T15:42:17.504731874Z",
"progress": 100,
"done": true,
"response": {
"@type": "[type.googleapis.com/google.cloud.chronicle.v1main.SearchSession](https://type.googleapis.com/google.cloud.chronicle.v1main.SearchSession)",
"name": "projects/PROJECT_NUMBER/locations/LOCATION/instances/INSTANCE_ID/searchSessions/SEARCH_SESSION_ID",
"query": "metadata.event_type = \"USER_LOGIN\"",
"timeRange": {},
"startTime": "2026-03-16T14:40:13Z",
"endTime": "2026-03-16T15:40:13Z",
"dialect": "YL2",
"metadata": {
"operationId": "OPERATION_ID",
"startTime": "2026-03-16T15:42:11.037506921Z",
"endTime": "2026-03-16T15:42:17.504730842Z",
"expireTime": "2026-03-17T15:42:17.504731874Z",
"resultRowCount": 10000,
"moreDataAvailable": true
}
}
}
SearchSession 資源名稱格式為 projects/{project}/locations/{location}/instances/{instance}/searchSessions/{search_session}。
成功的回應包含下列重要欄位:
done:設為true時,代表作業已完成。state:設為SUCCEEDED時,搜尋作業已順利完成。response.name:SearchSession的資源名稱。在下一個步驟中,將這個值做為父項屬性。response.metadata.resultRowCount:表示找到的資料列總數。response.metadata.moreDataAvailable:表示可用的結果數量超過定義的傳回限制。
列出 LRO 作業
如要列出 LRO 作業,請使用 google.longrunning.Operations 服務中的 ListOperations 方法。使用先前回應中的 name 值。
- 端點:
GET /{$api_version}/projects/{project}/locations/{location}/instances/{instance}
如要列出過去 24 小時內的搜尋 LRO 作業,請指定 name:"operations/s-lro-" 篩選器,包括結尾的連字號。
以下範例顯示成功的 ListOperations 要求:
google.longrunning.ListOperationsRequest {
name: "projects/PROJECT_NUMBER/locations/LOCATION/instances/INSTANCE_ID"
filter: "name:\"operations/s-lro-\""
page_size: 100
}
以下範例顯示成功的 ListOperations 回應:
{
operations {
name: "projects/PROJECT_NUMBER/locations/LOCATION/instances/INSTANCE_ID/operations/OPERATION_ID_1"
metadata {
type_url: "[type.googleapis.com/google.cloud.chronicle.v1main.SearchOperation](https://type.googleapis.com/google.cloud.chronicle.v1main.SearchOperation) Metadata"
value: "\b\002\022\f\b\367\304\363\316\006\020\317\352\232\240\003\032\f\b\237\307\363\316\006\020\326\334\351\311\001\"\f\b\237\352\370\316\006\020\352\342\351\311\001(d"
}
done: true
response {
type_url: "[type.googleapis.com/google.cloud.chronicle.v1main.SearchSession](https://type.googleapis.com/google.cloud.chronicle.v1main.SearchSession)"
value: "\n\213\001projects/PROJECT_NUMBER/locations/LOCATION/instances/INSTANCE_ID/searchSessions/OPERATION_ID_11022\bip != \"\"\032\020\n\006\b\251\255\334\316\006\022\006\b\351\345\336\316\006\0012\\\n*OPERATION_ID_1\022\f\b\367\304\363\316\006\020\317\352\232\240\003\032\f\b\237\307\363\316\006\020\326\334\351\311\001\"\f\b\237\352\370\316\006\020\352\342\351\311\001(\300\204=0\001"
}
}
operations {
name: "projects/PROJECT_NUMBER/locations/LOCATION/instances/INSTANCE_ID/operations/OPERATION_ID_2"
metadata {
type_url: "[type.googleapis.com/google.cloud.chronicle.v1main.SearchOperationMetadata](https://type.googleapis.com/google.cloud.chronicle.v1main.SearchOperationMetadata)"
value: "\b\002\022\f\b\200\305\363\316\006\020\324\262\367\225\001\032\v\b\241\307\363\316\006\020\321\261\333?\"\v\b\241\352\370\316\006\020\317\264\333?(d"
}
done: true
response {
type_url: "[type.googleapis.com/google.cloud.chronicle.v1main.SearchSession](https://type.googleapis.com/google.cloud.chronicle.v1main.SearchSession)"
value: "\n\213\001projects/PROJECT_NUMBER/locations/LOCATION/instances/INSTANCE_ID/searchSessions/OPERATION_ID_2\022\bip != \"\"\0321020\n\006\b\251\255\334\316\006\022\006\b\351\345\336\316\006\0012Z\n*OPERATION_ID_2\022\f\b\200\305\363\316\006\0201324\262\367\225\001\032\v\b\241\307\363\316\006\020\321\261\333?\"\v\b\241\352\370\316\006\020\317\264\333?(\300\204=0\001"
}
}
}
擷取結果
作業狀態傳回 SUCCEEDED 後,請使用 ListSearchedResults() 方法擷取搜尋結果。
- 端點:
GET /{$api_version}/{parent=projects/*/locations/*/instances/*/searchSessions/*}/searchedResults - 方法:
ListSearchedResults - 要求參數:
ListSearchedResultsRequest
以下範例顯示 ListSearchedResultsRequest 擷取三個結果,並略過前五個結果:
// GET
/v1alpha/projects/PROJECT_NUMBER/locations/LOCATION/instances/INSTANCE_ID/searchSessions/SEARCH_SESSION_ID/searchedResults?page_size=3&skip=5
這項要求支援下列查詢參數:
page_size:每頁傳回的結果數量上限。預設值為 100,最大值為 10000。page_token:先前ListSearchedResultsResponse的權杖,用於擷取下一頁。order_by(或 JSON 中的orderBy):選用。用於排序結果的欄位。如果省略order_by,UDM 事件結果預設會依udm.metadata.event_timestamp遞減排序,最先傳回最近的事件。在order_by中指定欄位路徑時,如果沒有方向後置字串 (例如udm.principal.hostname),結果預設會依遞增順序排序。請勿附加asc,因為系統不支援asc尾碼,會傳回400 INVALID_ARGUMENT錯誤。如要以遞減順序排序結果,請在欄位路徑附加desc後置字串,例如udm.metadata.event_timestamp desc。不支援多欄排序。UDM events (eventRecord):在udm欄位中使用完整路徑,例如udm.metadata.event_timestamp desc或udm.principal.hostname。系統也支援hostname、user、process name和event type等資料欄名稱。預設排列順序為
udm.metadata.event_timestamp遞減,會先傳回最近的事件。Entities / ECG (entityContextRecord):使用entity欄位中的路徑,例如graph.entity.ip或graph.entity.ip desc。data tables (dataTableRecord):請使用%<table_alias>.<column_name>格式。例如:%dt.user desc。預設值為第一個資料表欄。
Detections (DetectionRecord):使用關鍵字detection,後面加上路徑,例如detection.id。彙整:針對事件和實體,請使用定義這些項目的預留位置變數。所有其他來源的格式則維持不變。
例如:
- ECG (UDM-ECG 彙整):實體:
$e1.graph.entity.hostname - UDM (所有與 UDM 的彙整):
$e1.principal.ip - 資料表 (UDM 資料表彙整):
%<table_alias>.<column_name>
系統也支援預先定義的別名,例如
hostname、user、process name和event type。這時請使用$e1.hostname.at格式。- ECG (UDM-ECG 彙整):實體:
skip:選用。要略過的結果數量。請勿將這項參數與page_token搭配使用。- 如果事件的時間戳記相同,預設排序 (
udm.metadata.event_timestamp) 就不是不重複。此外,搜尋結果的排列順序是在第一個ListSearchedResults(searchedResults.list) 呼叫中設定。 - 使用
skip分頁時,尤其是在平行要求中,請在order_by參數中指定不重複的排序欄位,例如udm.metadata.id。或者,您也可以先擷取第一頁,再傳送平行skip要求,這樣就能預先設定排列順序。
- 如果事件的時間戳記相同,預設排序 (
以下範例顯示成功的 ListSearchedResultsResponse 回應:
{
"searchedResults": [
{
"name":
"projects/PROJECT_NUMBER/locations/LOCATION/instances/INSTANCE_ID/searchSessions/SEARCH_SESSION_ID/searchedResults/
RESULT_ID",
"resultRow": {
"eventRecord": {
"event": {
"name":
"projects/PROJECT_NUMBER/locations/LOCATION/instances/INSTANCE_ID/events/EVENT_ID",
"udm": {
"metadata": {
"eventTimestamp": "2026-03-16T14:45:18Z",
"eventType": "USER_LOGIN",
"vendorName": "Microsoft",
"productName": "Azure AD"
}
},
//... other UDM fields
}
//... other UDM fields
"eventLogToken":
"EVENT_LOG_TOKEN"
}
},
{ }
},
{
"name": "projects/PROJECT_NUMBER/locations/
LOCATION/instances/INSTANCE_ID</span>
/searchSessions/SEARCH_SESSION_ID/searchedResults/RESULT_ID", "resultRow": {
"eventRecord": {
//... Similar UDM event structure...
}
}
},
{
""name": "projects/PROJECT_NUMBER/locations/
LOCATION/instances/INSTANCE_ID</span>
/searchSessions/SEARCH_SESSION_ID/searchedResults/RESULT_ID", "resultRow": {
"eventRecord": {
//... Similar UDM event structure...
}
}
}
],
"totalSize": 10000,
"columnNames": [],
"columnSchema": {},
"nextPageToken": "CAKYASAB"
}
如要擷取後續的結果頁面,請在下一個 ListSearchedResults 要求的 page_token 查詢參數中使用傳回的 nextPageToken 值。resultRow 欄位包含實際資料。
繼續呼叫 ListSearchedResults,並使用各個回應中的 next_page_token 值。當 next_page_token 傳回空白時,表示已擷取所有結果。
後續步驟
如要進一步瞭解方法、要求和回應欄位,以及類型,請參閱下列 API 參考文件:
還有其他問題嗎?向社群成員和 Google SecOps 專業人員尋求解答。