このドキュメントには、 プロジェクトに保存されているトレースデータをクエリするための サンプルクエリが含まれています。 Google Cloud
SQL 言語のサポート
[オブザーバビリティ分析] ページで使用されるクエリは、一部の例外を除き、GoogleSQL 関数をサポートしています。
[オブザーバビリティ分析] ページを使用して発行された SQL クエリでは、次の SQL コマンドはサポートされていません。
- DDL コマンドと DML コマンド
- JavaScript ユーザー定義関数
- BigQuery ML 関数
- SQL 変数
以下は、[BigQuery Studio] ページ、[Looker Studio] ページ、または bq コマンドライン ツールを使用してリンク済みデータセットをクエリする場合にのみサポートされます。
- JavaScript ユーザー定義関数
- BigQuery ML 関数
- SQL 変数
ベスト プラクティス
クエリの期間を設定するには、期間セレクタを使用することをおすすめします。たとえば、過去 1 週間のデータを表示するには、期間セレクタで [過去 7 日間] を選択します。また、期間セレクタを使用して、開始時刻と終了時刻の指定、表示時間の指定、タイムゾーンの変更を行うこともできます。
WHERE 句に start_time フィールドを含めると、期間セレクタの設定は使用されません。次の例では、TIMESTAMP_SUB 関数を使用してデータをフィルタリングします。この関数を使用すると、現在の時刻から遡る間隔を指定できます。
WHERE
start_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR)
時間でフィルタする方法の詳細については、 時間関数とタイムスタンプ関数をご覧ください。
始める前に
- アカウントにログインします。 Google Cloud を初めて使用する場合は、 アカウントを作成して、実際のシナリオで Google プロダクトのパフォーマンスを評価してください。 Google Cloud新規のお客様には、ワークロードの実行、テスト、デプロイができる無料クレジット $300 分を差し上げます。
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
Enable the Observability API.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission. Learn how to grant roles.-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
Enable the Observability API.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission. Learn how to grant roles.-
[**オブザーバビリティ分析**] ページの読み込み、トレースデータに対する非公開クエリの作成、実行、保存に必要な権限を取得するには、次の IAM ロールを付与するよう管理者に依頼します。
-
オブザーバビリティ閲覧アクセサー (
roles/observability.viewAccessor)クエリするオブザーバビリティ ビューに対する。このロールは IAM 条件をサポートしており、特定のビューへの付与を制限できます。ロール付与に条件を付加しない場合、プリンシパルはすべてのオブザーバビリティ ビューにアクセスできます。 -
オブザーバビリティ分析ユーザー (
roles/observability.analyticsUser)プロジェクトに対する。このロールには、非公開クエリの保存と実行、共有クエリの実行に必要な権限が含まれています。 -
ログビューア (
roles/logging.viewer)プロジェクトに対する。
ロールの付与については、プロジェクト、フォルダ、組織へのアクセス権の管理をご覧ください。
-
オブザーバビリティ閲覧アクセサー (
このページのクエリの使用方法
-
コンソールで、 manage_search[**ログ分析**] ページに移動します。 Google Cloud
このページを検索バーで検索する場合は、小見出しが「Logging」の結果を選択します。
In the [Query] pane, click the code [SQL], and then copy and paste a query into the SQL クエリ pane.
次に、
_AllSpansビューをクエリするためのFROM句の形式を示します。FROM `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`FROM句には次のフィールドが含まれます。- PROJECT_ID: プロジェクトの ID。
- LOCATION: オブザーバビリティ バケットのロケーション。
_Traceはオブザーバビリティ バケットの名前です。Spansはデータセットの名前です。_AllSpansはビューの名前です。
このドキュメントに示すクエリを [BigQuery Studio] ページで使用する場合や、[bq コマンドライン ツール] を使用する場合は、FROM 句を編集して、リンクされたデータセットへのパスを入力します。たとえば、プロジェクト myproject にある my_linked_dataset という名前のリンクされたデータセットで
_AllSpans ビューをクエリする場合、パスは
`myproject.my_linked_dataset._AllSpans` です。
一般的なユースケース
このセクションでは、カスタムクエリの作成に役立つ一般的なユースケースをいくつか紹介します。
すべてのトレースデータを表示する
_AllSpans ビューをクエリするには、次のクエリを実行します。
-- Display all data.
SELECT *
FROM `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
-- Limit to 10 entries.
LIMIT 10
一般的なスパン情報を表示する
開始時刻や期間などの一般的なスパン情報を表示するには、次のクエリを実行します。
SELECT
start_time,
-- Set the value of service name based on the first non-null value in the list.
COALESCE(
JSON_VALUE(resource.attributes, '$."service.name"'),
JSON_VALUE(attributes, '$."service.name"'),
JSON_VALUE(attributes, '$."g.co/gae/app/module"')) AS service_name,
name AS span_name,
duration_nano,
status.code AS status,
trace_id,
span_id
FROM
`PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
LIMIT 10
詳細については、条件式をご覧ください。
スパン レイテンシの 50 パーセンタイルと 99 パーセンタイルを表示する
各 rpc サービスのレイテンシの 50 パーセンタイルと 99 パーセンタイルを表示するには、次のクエリを実行します。
SELECT
-- Compute 50th and 99th percentiles for each service
STRING(attributes['rpc.service']) || '/' || STRING(attributes['rpc.method']) AS rpc_service_method,
APPROX_QUANTILES(duration_nano, 100)[OFFSET(50)] AS duration_nano_p50,
APPROX_QUANTILES(duration_nano, 100)[OFFSET(99)] AS duration_nano_p99
FROM
`PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
WHERE
-- Matches spans whose kind field has a value of 2 (SPAN_KIND_SERVER).
kind = 2
GROUP BY rpc_service_method
列挙の詳細については、 OpenTelemetry: SpanKind のドキュメントをご覧ください。
結果をグラフで表示するには、ディメンションを rpc_service_method に設定したグラフを作成します。2 つの指標を追加できます。1 つは duration_nano_p50 値の平均、もう 1 つは duration_nano_p99 フィールドの平均です。
トレース エントリをフィルタする
クエリにフィルタを適用するには、WHERE 句を追加します。この句で使用する構文は、フィールドのデータ型によって異なります。このセクションでは、さまざまなデータ型の例をいくつか示します。
文字列データ型でフィルタする
フィールド name は String として保存されます。
nameが指定されているスパンのみを分析するには、次の句を使用します。-- Matches spans that have a name field. WHERE name IS NOT NULLnameの値が"POST"のスパンのみを分析するには、 次の句を使用します。-- Matches spans whose name is POST. WHERE STRPOS(name, "POST") > 0nameに値"POST"が含まれているスパンのみを分析するには、LIKE演算子をワイルドカードとともに使用します。-- Matches spans whose name contains POST. WHERE name LIKE "%POST%"
整数データ型でフィルタする
フィールド kind は整数で、0 ~ 5 の値を取ることができます。
kindが指定されているスパンのみを分析するには、次の句を使用します。-- Matches spans that have field named kind. WHERE kind IS NOT NULLkindの値が 1 または 2 のスパンを分析するには、次の句を使用します。-- Matches spans whose kind value is 1 or 2. WHERE kind IN (1, 2)
RECORD データ型でフィルタする
トレース スキーマの一部のフィールドのデータ型は RECORD です。これらのフィールドには、1 つ以上のデータ構造を保存することも、同じデータ構造の繰り返しエントリを保存することもできます。
ステータスまたはステータス コードでフィルタする
status フィールドは、データ型が RECORD のフィールドの例です。この
フィールドには、code と message というラベルの付いたメンバーを含む 1 つのデータ構造が保存されます。
status.codeフィールドの値が1の場合にのみスパンを分析するには、次の句を追加します。-- Matches spans that have a status.code field that has a value of 1. WHERE status.code = 1status.codeフィールドは整数として保存されます。statusフィールドがEMPTYでないスパンを分析するには、次の句を追加します。-- Matches spans that have status field. When the status field exists, it -- must contain a subfield named code. -- Don't compare status to NULL, because this field has a data type of RECORD. WHERE status.code IS NOT NULL
イベントまたはリンクでフィルタする
events フィールドと links フィールドは RECORD データ型で保存されますが、これらは繰り返しフィールドです。
1 つ以上のイベントがあるスパンを照合するには、次の句を使用します。
-- Matches spans that have at least one event. Don't compare events to NULL. -- The events field has data type of RECORD and contains a repeated fields. WHERE ARRAY_LENGTH(events) > 0nameフィールドの値がmessageのイベントがあるスパンを照合するには、次の句を使用します。WHERE -- Exists is true when any event in the array has a name field with the -- value of message. EXISTS( SELECT 1 FROM UNNEST(events) AS ev WHERE ev.name = 'message' )
JSON データ型でフィルタする
attributes フィールドの型は JSON です。個々の属性は Key-Value ペアです。
attributesが指定されているスパンのみを分析するには、次の句を使用します。-- Matches spans where at least one attribute is specified. WHERE attributes IS NOT NULLcomponentという名前の属性キーの値が"proxy"のスパンのみを分析するには、次の句を使用します。-- Matches spans that have an attribute named component with a value of proxy. WHERE attributes IS NOT NULL AND JSON_VALUE(attributes, '$.component') = 'proxy'ワイルドカードとともに
LIKEステートメントを使用して、包含テストを行うこともできます。-- Matches spans that have an attribute named component whose value contains proxy. WHERE attributes IS NOT NULL AND JSON_VALUE(attributes, '$.component') LIKE '%proxy%'
トレースデータをグループ化して集計する
このセクションでは、スパンをグループ化して集計する方法について説明します。グループ化を指定せずに集計を指定する場合は、SQL が WHERE 句を満たすすべてのエントリを 1 つのグループとして扱うため、1 つの結果が出力されます。
すべての SELECT 式は、グループ フィールドに含めるか、集計する必要があります。
開始時刻でスパンをグループ化する
開始時刻でデータをグループ化するには、関数
TIMESTAMP_TRUNCを使用します。
この関数は、HOURのような指定した粒度までタイムスタンプを切り詰めます。
SELECT
-- Truncate the start time to the hour. Count the number of spans per group.
TIMESTAMP_TRUNC(start_time, HOUR) AS hour,
status.code AS code,
COUNT(*) AS count
FROM
`PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
WHERE
-- Matches spans shows start time is within the previous 12 hours.
start_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 12 HOUR)
GROUP BY
-- Group by hour and status code.
hour, code
ORDER BY hour DESC
詳細については、TIMESTAMP_TRUNC ドキュメント
と 日時関数をご覧ください。
ステータス コードでスパンをカウントする
特定のステータス コードを持つスパンの数を表示するには、次のクエリを実行します。
SELECT
-- Count the number of spans for each status code.
status.code,
COUNT(*) AS count
FROM
`PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
WHERE status.code IS NOT NULL
GROUP BY status.code
status.code を kind に置き換えると、前のクエリは kind 列挙型の各値のスパン数を報告します。同様に、status.code を name に置き換えると、クエリ結果にはスパン名ごとのエントリ数が表示されます。
すべてのスパンの平均期間を計算する
スパン名を基準にスパンデータをグループ化した後、平均期間を表示するには、次のクエリを実行します。
SELECT
-- Group by name, and then compute the average duration for each group.
name,
AVG(duration_nano) AS nanosecs,
FROM
`PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
GROUP BY name
ORDER BY nanosecs DESC
サービス名ごとに平均期間とパーセンタイルを計算する
次のクエリは、サービスごとにスパン数とさまざまな統計情報を計算します。
SELECT
-- Set the service name by the first non-null value.
COALESCE(
JSON_VALUE(resource.attributes, '$."service.name"'),
JSON_VALUE(attributes, '$."service.name"'),
JSON_VALUE(attributes, '$."g.co/gae/app/module"')) AS service_name,
-- Count the number spans for each service name. Also compute statistics.
COUNT(*) AS span_count,
AVG(duration_nano) AS avg_duration_nano,
MIN(duration_nano) AS min_duration_nano,
MAX(duration_nano) AS max_duration_nano,
-- Calculate percentiles for duration
APPROX_QUANTILES(duration_nano, 100)[OFFSET(50)] AS p50_duration_nano,
APPROX_QUANTILES(duration_nano, 100)[OFFSET(95)] AS p95_duration_nano,
APPROX_QUANTILES(duration_nano, 100)[OFFSET(99)] AS p99_duration_nano,
-- Count the number of unique trace IDs. Also, collect up to 5 unique
-- span names and status codes.
COUNT(DISTINCT trace_id) AS distinct_trace_count,
ARRAY_AGG(DISTINCT name IGNORE NULLS LIMIT 5) AS sample_span_names,
ARRAY_AGG(DISTINCT status.code IGNORE NULLS LIMIT 5) AS sample_status_codes
FROM
`PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
GROUP BY service_name
ORDER BY span_count DESC
クロスカラム検索
このセクションでは、クエリを実行しているビューの複数の列を検索するために使用できる 2 つの方法について説明します。
トークンベース検索: 検索場所と検索クエリを指定し、
SEARCH関数を使用します。SEARCH関数にはデータの検索方法に関する特定のルールがあるため、SEARCHのドキュメントを一読することをおすすめします。部分文字列ベースの検索: 検索場所と文字列リテラルを指定し、
CONTAINS_SUBSTR関数を使用します。システムは、大文字と小文字を区別しないテストを実行して、文字列リテラルが式に存在するかどうかを判断します。CONTAINS_SUBSTR関数は、文字列リテラルが存在する場合はTRUEを返し、それ以外の場合はFALSEを返します。検索値はSTRINGリテラルである必要があり、リテラルNULLではありません。
複数のビューをクエリする
クエリ ステートメントは、1 つ以上のテーブルまたは式をスキャンし、計算結果の行を返します。たとえば、クエリ ステートメントを使用して、さまざまなテーブルやデータセットの SELECT ステートメントの結果をマージし、結合データから列を選択できます。
ビューを結合するには、次の制限が適用されます。
-
ビューのロケーションが次のいずれかを満たしている。
- すべてのビューが同じロケーションにある。
- すべてのビューが
globalまたはusロケーションにある。
-
ストレージ リソースで顧客管理の暗号鍵(CMEK)を使用している場合は、 次のいずれかが true になります。
- CMEK を使用するストレージ リソースは、同じ Cloud KMS 鍵を使用します。
- CMEK を使用するストレージ リソースには共通の祖先があり、その祖先はストレージ リソースと同じロケーションにあるデフォルトの Cloud KMS 鍵を指定します。
1 つ以上のストレージ リソースで CMEK を使用する場合、システムは結合によって生成された一時データを、共通の Cloud KMS 鍵または祖先のデフォルトの Cloud KMS 鍵で暗号化します。
たとえば、同じロケーションに 2 つのビューがあるとします。この場合、次のいずれかが true の場合に、これらのビューを結合できます。
- ストレージ リソースで CMEK を使用していない。
- 1 つのストレージ リソースで CMEK を使用し、もう 1 つは使用していない。
- 両方のストレージ リソースで CMEK を使用し、両方とも同じ Cloud KMS 鍵を使用している。
両方のストレージ リソースで CMEK を使用しているが、異なる鍵を使用している。ただし、リソースは、ストレ 101} ージ リソースと同じロケーションにあるデフォルトの Cloud KMS 鍵を指定する祖先を共有します。
たとえば、ログバケットとオブザーバビリティ バケットのリソース階層に同じ組織が含まれているとします。その組織で、ストレージ ロケーションに同じデフォルトの Cloud KMS 鍵を使用して、Cloud Logging とオブザーバビリティ バケットのデフォルト リソース設定を構成している場合は、これらのバケットのビューを結合できます。
トレース ID を使用してトレースデータとログデータを結合する
次のクエリは、スパン ID とトレース ID を使用してログデータとトレースデータを結合します。
SELECT
T.trace_id,
T.span_id,
T.name,
T.start_time,
T.duration_nano,
L.log_name,
L.severity,
L.json_payload
FROM
`PROJECT_ID.LOCATION._Trace.Spans._AllSpans` AS T
JOIN
`PROJECT_ID.LOCATION._Default._AllLogs` AS L
ON
-- Join log and trace data by both the span ID and trace ID.
-- Don't join only on span ID, this field isn't globally unique.
T.span_id = L.span_id
-- A regular expression is required because the storage format of the trace ID
-- differs between a log view and a trace view.
AND T.trace_id = REGEXP_EXTRACT(L.trace, r'/([^/]+)$')
WHERE T.duration_nano > 1000000
LIMIT 10
クエリのレスポンスには、トレース ID とスパン ID が一覧表示されます。これにより、個別にクエリして詳細情報を収集できます。また、結果にはログエントリの重大度と JSON ペイロードが一覧表示されます。
次のステップ
SQL リファレンス ドキュメントまたはその他の例については、次のドキュメントをご覧ください。