Google Distributed Cloud(GDC)エアギャップ アプライアンスのログクエリを使用すると、ログを収集した後に、プロジェクト ワークロード全体の運用イベントと監査イベントを検査できます。Grafana ログパネルで、Log Query Language(LogQL)式を使用してログストリームをフィルタ、可視化、エクスポートできます。プログラムによるワークフローの場合は、標準の API アクセス方法に従って、HTTP または gRPC 経由で組織の Log Query API をクエリします。
始める前に
Grafana ユーザー インターフェースでログをクエリして可視化するために必要な権限を取得するには、組織の IAM 管理者またはプロジェクトの IAM 管理者に、事前定義された組織の Grafana 閲覧者ロールまたはプロジェクトの Grafana 閲覧者ロールのいずれかを付与するよう依頼します。必要なアクセスレベルと権限に応じて、組織またはプロジェクトで Grafana ロールを取得できます。
または、Log Query API からログをクエリするために必要な権限を取得するには、プロジェクトの IAM 管理者に、プロジェクトの名前空間で Log Query API クエリ実行者のロールを付与するよう依頼します。
これらのロールの詳細については、IAM 権限を準備するをご覧ください。
ログのクエリを作成する
システム モニタリング インスタンスの UI からログをクエリすると、プロジェクトから運用ログを取得するデータソースを選択し、クエリの統合ビューを取得できます。結果をフィルタするには、クエリ言語式を使用してラベルでログを検索します。たとえば、クエリの cluster ラベルと namespace ラベルを、クラスタとプロジェクトの名前空間を識別する値に設定できます。
システム モニタリング インスタンスのエンドポイント
アプリケーション オペレーター(AO)向け
次の URL は、プロジェクトのモニタリング インスタンスのエンドポイントです。
https://GDC_URL/PROJECT_NAMESPACE/grafana
次のように置き換えます。
- GDC_URL: GDC の組織の URL。
- PROJECT_NAMESPACE: プロジェクトの Namespace。
プラットフォーム管理者(PA)向け
次の URL は、プロジェクトのモニタリング インスタンスのエンドポイントです。
https://GDC_URL/platform-obs/grafana
GDC_URL は、GDC の組織の URL に置き換えます。
ログのクエリとフィルタ
次のいずれかの方法を選択して、クエリを作成し、プロジェクト ワークロードからログをフィルタします。
このセクションでは、Grafana の [Log] パネルを使用してログにアクセスする方法について説明します。
Grafana エンドポイントを特定する
アプリケーション オペレーター(AO)向け
次の URL は、プロジェクトのモニタリング インスタンスのエンドポイントです。
https://GDC_URL/PROJECT_NAMESPACE/grafana
次のように置き換えます。
- GDC_URL: GDC の組織の URL。
- PROJECT_NAMESPACE: プロジェクトの Namespace。
プラットフォーム管理者(PA)向け
次の URL は、プロジェクトのモニタリング インスタンスのエンドポイントです。
https://GDC_URL/platform-obs/grafana
GDC_URL は、GDC の組織の URL に置き換えます。
Grafana ユーザー インターフェースでログを表示する
Grafana ユーザー インターフェースでログをクエリします。
- GDC コンソールで、プロジェクトを選択します。
- ナビゲーション メニューで、[オペレーション] > [ロギング] を選択します。
- [View all in Grafana Loki] をクリックします。
新しいページが開き、Grafana エンドポイントとユーザー インターフェースが表示されます。
- ユーザー インターフェースで、ナビゲーション メニューから explore [Explore] をクリックして、[Explore] ページを開きます。
- [Explore] バーのメニューから、ユニバース タイプに応じて、ログを取得するデータソースを選択します。
シングルゾーン ユニバース: 次のいずれかのデータソースを選択して、ユニバースのシングルゾーンのロギングデータを表示します。
オペレーション ログ: オペレーション ログを表示します。
監査ログ: 監査ログを表示します。
オペレーション ログ ZONE_NAME: 特定のゾーンのオペレーション ログを表示します。
監査ログ ZONE_NAME: 特定のゾーンの監査ログを表示します。
また、1 つのダッシュボードでゾーン間のデータを可視化し、クエリに複数のゾーンを追加するには、データソースとして [混合] を選択します。
LogQL(Log Query Language)式を使用して、[ログ] パネルからログを検索するクエリを入力します。この手順は、次のいずれかの方法で行います。
- インタラクティブなクエリビルダー インターフェースを使用します。[クエリを実行] をクリックします。
- テキスト フィールドにクエリを直接入力し、Shift+Enter キーを押してクエリを実行します。
クエリに一致するログがページに表示されます。ログをクエリした後、ログをエクスポートできます。[エクスポート] をクリックして、ログを書式なしテキスト形式または CSV 形式でダウンロードします。ログの期間を選択することもできます。
![監査ログを取得するために、[Explore] ページで [Audit logs] オプションが選択されている。](https://docs.cloud.google.com/static/distributed-cloud/hosted/docs/latest/appliance/platform/images/audit-logs-ui.png?hl=ja)
図 1. Grafana ユーザー インターフェースから監査ログをクエリするメニュー オプション。
図 1 の [Audit logs] オプションには、Grafana からクエリを作成して監査ログを取得するためのインターフェースが表示されています。
さまざまなログをクエリするためのラベルと値の例については、サンプルクエリとラベルをご覧ください。
ログの期間を選択する
特定の期間のログをクエリする手順は次のとおりです。
Grafana で [Time Picker] メニューをクリックします。
メニューから、次のいずれかの操作を行います。
- 相対的な期間オプション(過去 30 分など)を選択します。
- カレンダーから特定の日時を選択し、[期間を適用] をクリックして、カスタムの絶対期間を設定します。
必要に応じて、[時間設定を変更] をクリックして、期間コントロールから [タイムゾーン] と [会計年度] の設定を変更します。
時間設定はダッシュボードごとに保存されます。期間にわたるクエリの詳細については、https://grafana.com/docs/loki/latest/reference/api/#query-loki-over-a-range-of-time をご覧ください。
クエリを送信する
HTTP または gRPC クライアントを使用して、Log Query API エンドポイントにクエリを送信します。
HTTP
HTTP クライアントを使用して API に直接アクセスするの手順に沿って操作します。
kubectlを使用して認証を管理することも、認証を自分で処理することもできます。curl、wgetなどの HTTP クライアント、または作成して管理する HTTP クライアントを使用して、Log Query API にクエリを実行します。次の例では、curlツールを使用して API をクエリします。wgetコマンドでも同様の形式を使用できます。cURL リクエストを認証します。
- gdcloud CLI をダウンロードしてインストールします。
gdcloud
core/organization_console_urlプロパティを設定します。gdcloud config set core/organization_console_url https://GDC_URLGDC_URLは、GDC の組織の URL に置き換えます。-
gdcloud auth login ユーザー名とパスワードを使用して認証し、ログインします。
指定したアカウントの ID トークンを環境変数にエクスポートします。
export TOKEN="$($HOME/gdcloud auth print-identity-token --audiences=https://LOG_QUERY_API_ENDPOINT)"LOG_QUERY_API_ENDPOINTは、ログをクエリする Log Query API エンドポイントと、接続するドメインに置き換えます。したがって、audiencesフラグの値はhttps://operational-log-query-api.org-1.zone1.google.gdch.testなどになります。ログインが成功すると、
gdcloud auth print-identity-tokenコマンドを使用して cURL リクエストで認証ヘッダーを使用できます。詳細については、gdcloud auth print-identity-token をご覧ください。
プロジェクトのすべてのラベルを一覧表示するには、次のクエリを送信します。
curl -H "Authorization: Bearer ${TOKEN}" \ https://LOG_QUERY_API_ENDPOINT/v1/projects/PROJECT_NAMESPACE/labels \ -H "Content-Type: application/json" -v次のように置き換えます。
LOG_QUERY_API_ENDPOINT: ログをクエリする Log Query API エンドポイント。PROJECT_NAMESPACE: プロジェクトの名前空間。
プロジェクトの特定のラベル値を一覧表示するには、次のクエリを送信します。
curl -H "Authorization: Bearer ${TOKEN}" \ https://LOG_QUERY_API_ENDPOINT/v1/projects/PROJECT_NAMESPACE/labels/labels/LABEL/values \ -H "Content-Type: application/json" -v次のように置き換えます。
LOG_QUERY_API_ENDPOINT: ログをクエリする Log Query API エンドポイント。PROJECT_NAMESPACE: プロジェクトの名前空間。LABEL: 値をクエリする特定のラベル。
特定のプロジェクトのログをクエリする場合は、
logs_filterクエリを作成してリクエストの本文に含めます。curl -X GET -H "Authorization: Bearer ${TOKEN}" \ https://LOG_QUERY_API_ENDPOINT/v1/projects/PROJECT_NAMESPACE/logs \ -H "Content-Type: application/json" -d \ '{"logs_filter": {"labels_equal": {"LABEL": "LABEL_VALUE"}}}' -v次のように置き換えます。
LOG_QUERY_API_ENDPOINT: ログをクエリする Log Query API エンドポイント。PROJECT_NAMESPACE: プロジェクトの名前空間。LABEL: ログをクエリする特定のラベル。LABEL_VALUE: ログをクエリするラベル値。
logs_filterクエリを作成するためのすべてのオプションについては、API ドキュメントをご覧ください。
gRPC
gRPC はプログラミング言語全体で広くサポートされており、HTTP クライアントと比較してより効率的な通信方法を提供します。
gRPC を使用してログをクエリするには、次の前提条件を満たす必要があります。
- Google が提供するプロトコル バッファに基づいて独自のクライアント ライブラリを作成する。
- クライアントに認証を実装します。
- 再試行を実装する。
プロトコル バッファの詳細については、API ドキュメントをご覧ください。
次の例は、認証されていない gRPC クライアントを使用して Go プログラムからログをクエリする方法を示しています。この例では、コードの依存関係をインポートする Bazel ビルドファイルを含む golang パッケージを作成したことを前提としています。
次のコードを
client.goという名前の Go プログラムに保存します。package main import ( "context" "crypto/tls" "flag" "fmt" "google.golang.org/grpc/credentials" "google.golang.org/grpc/metadata" pb "<import path to generated log query api protos>/pkg/apis/public/logging/v1/proto" "google.golang.org/grpc" ) var serverAddr = flag.String("server", "localhost:8080", "server address") func main() { flag.Parse() tc := credentials.NewTLS(&tls.Config{InsecureSkipVerify: true}) conn, err := grpc.Dial(*serverAddr, grpc.WithTransportCredentials(tc)) if err != nil { panic(error.Error(fmt.Errorf("create client connection failed: %v", err))) } defer conn.Close() c := pb.NewLogsClient(conn) md := metadata.Pairs("clienttest", "test") ctx := metadata.NewOutgoingContext(context.Background(), md) err = listLabels(ctx, c, "project-foo") if err != nil { panic(error.Error(err)) } if err := listLabelValues(ctx, c, "project-foo", "resource-bar"); err != nil { panic(error.Error(err)) } if err := listLogs(ctx, c, "project-foo", &pb.ListLogsFilter{ LabelsEqual: map[string]string{"resource-bar": "resource-bar-value"}, OrderAscending: true, }); err != nil { panic(error.Error(err)) } } // List all labels for a project. func listLabels(ctx context.Context, c pb.LogsClient, project string) error { lbr := &pb.ListLabelsRequest{ Parent: project, PageSize: 1000, // PageSize can be configured to limit the number of responses per page. } resp, err := c.ListLabels(ctx, lbr) if err != nil { return fmt.Errorf("list labels: %v", err) } fmt.Printf("%v", resp) return nil } // List specific label values for a project. func listLabelValues(ctx context.Context, c pb.LogsClient, project string, label string) error { lbr := &pb.ListLabelValuesRequest{ Parent: project, Label: label, PageSize: 1000, // PageSize can be configured to limit the number of responses per page. } resp, err := c.ListLabelValues(ctx, lbr) if err != nil { return fmt.Errorf("list label values: %v", err) } fmt.Printf("%v", resp) return nil } // List logs for a specific project. func listLogs(ctx context.Context, c pb.LogsClient, project string, lf *pb.ListLogsFilter) error { lbr := &pb.ListLogsRequest{ Parent: project, LogsFilter: lf, PageSize: 5, // PageSize can be configured to limit the number of responses per page. } resp, err := c.ListLogs(ctx, lbr) if err != nil { return fmt.Errorf("list logs: %v", err) } fmt.Printf("logs: %v", resp) return nil }Go プログラムを実行します。
go run PATH_TO_API/client.go -server=LOG_QUERY_API_ENDPOINT:443次のように置き換えます。
PATH_TO_API: API ファイルのパス。LOG_QUERY_API_ENDPOINT: ログをクエリする Log Query API エンドポイント。
サーバーフラグが指定されていない場合、デフォルトのリクエストは
localhostに送信されます。
サンプルクエリとラベル
ログのクエリに使用できるデフォルトのラベルの一部を次に示します。
cluster: クラスタの名前。namespace: プロジェクトの名前空間。node: ノード名。pod: Pod 名。container: コンテナ名。
次のコードサンプルは、ラベルと値を使用してさまざまなログをクエリする方法を示しています。
サーバーログを選択します。
{cluster="admin", namespace="kube-system", resources="k8s_container", container="kube-apiserver"}クラスタ監査ログを選択します。
{cluster="admin", resources="k8s_audit"}