OpenCensus によるカスタム指標

Stackdriver Monitoring は、非常に長いモニタリング対象リソースのリストから、1,000 を超える組み込み指標を自動的に収集します。しかし、これらの指標では、アプリケーション固有のデータやクライアント側のシステムデータを取得できません。これらの指標はバックエンド レイテンシやディスク使用量に関する情報を提供しますが、アプリケーションが生成したバックグラウンド ルーチンの数を示すことはできません。

アプリケーション固有の指標は、Stackdriver Monitoring の組み込み指標では取得できない情報を取得するために、ユーザーが定義して収集する指標です。ユーザーはこれらの指標を、コードを設定するためにライブラリによって提供されている API を使用して取得し、Stackdriver Monitoring などのバックエンド アプリケーションに送信します。

Stackdriver Monitoring では、アプリケーション固有の指標は通常「カスタム指標」と呼ばれます。これらの用語は区別なく使用されます。また、「ユーザー定義指標」とも呼ばれます。

Stackdriver Monitoring に関する限り、カスタム指標は組み込み指標のように使用できます。これらの指標をグラフ化したり、警告を設定したり、モニタリングしたりできます。異なる点は、ユーザーが指標を定義し、指標にデータを書き込み、指標を削除できるという点です。組み込み指標ではこれらの操作はできません。

カスタム指標を取得するには、ネイティブの Stackdriver Monitoring API を使用するなど多くの方法があります。Stackdriver では、カスタム指標を収集するコードを OpenCensus を使用して設定することをおすすめします。

OpenCensus とは

OpenCensus は無料のオープンソース プロジェクトで、そのライブラリによって次のことが可能になります。

  • 指標およびトレースデータをさまざまな言語で収集するための、ベンダーに依存しないサポートを提供できます。
  • 収集したデータを、Stackdriver を含むさまざまなバックエンド アプリケーションにエクスポートできます。

現在サポートされている言語の一覧については、Language Support をご覧ください。エクスポータが利用可能なバックエンド アプリケーションの現在のリストについては、Exporters をご覧ください。

OpenCensus を使うメリット

Stackdriver Monitoring はカスタム指標の定義と収集をサポートする API を提供しますが、これは低レベルの独自仕様の API です。OpenCensus はより汎用的な API を提供します。また、Monitoring API を通じて Stackdriver Monitoring に指標データを送信するエクスポータも用意しています。

さらに、OpenCensus はオープンソース プロジェクトであるため、独自仕様のライブラリではなく、ベンダーに依存しないライブラリを使用して、収集したデータをエクスポートできます。

OpenCensus は、アプリケーション トレースのための優れたサポートも備えています。一般的な概要については、OpenCensus のトレースをご覧ください。Stackdriver では、トレース手段として OpenCensus を使用することをおすすめします。ライブラリの単一の配布を使用して、指標とトレースデータの両方をサービスから収集できます。StackDriver Trace で OpenCensus を使用する方法については、Trace 用のクライアント ライブラリをご覧ください。

始める前に

Stackdriver Monitoring を使用するには、課金を有効にした GCP プロジェクトが必要です。また、プロジェクトは Stackdriver Workspace に関連付けられている必要があります。Stackdriver Monitoring はワークスペースを使用して、モニタリングされる GCP プロジェクトを編成します。

GCP プロジェクトがない場合は、以下を実行してください。

  1. Google アカウントにログインします。

    Google アカウントをまだお持ちでない場合は、新しいアカウントを登録します。

  2. GCP Console のプロジェクト セレクタのページで、GCP プロジェクトを選択または作成します。

    プロジェクト セレクタのページに移動

  3. Google Cloud Platform プロジェクトに対して課金が有効になっていることを確認します。 詳しくは、課金を有効にする方法をご覧ください。

プロジェクトをワークスペースに関連付けるには、ワークスペースをご覧ください。

カスタム指標は Stackdriver Monitoring の課金対象機能のため、指標の利用には料金が発生する場合があります。料金設定の詳細については、Stackdriver の料金をご覧ください。

OpenCensus のインストール

OpenCensus を使用するには、指標ライブラリと Stackdriver エクスポータを使用可能にする必要があります。

Go

OpenCensus を使用するには Go バージョン 1.11 以上が必要です。依存関係は自動的に処理されます。

Java

Maven 用に、pom.xml ファイル内の dependencies 要素に次のコードを追加します。
<dependency>
  <groupId>io.opencensus</groupId>
  <artifactId>opencensus-api</artifactId>
  <version>${opencensus.version}</version>
</dependency>
<dependency>
  <groupId>io.opencensus</groupId>
  <artifactId>opencensus-impl</artifactId>
  <version>${opencensus.version}</version>
</dependency>
<dependency>
  <groupId>io.opencensus</groupId>
  <artifactId>opencensus-exporter-stats-stackdriver</artifactId>
  <version>${opencensus.version}</version>
</dependency>

Node.js

  1. OpenCensus のコアライブラリとエクスポータ ライブラリをインストールする前に、Node.js 開発のための環境を用意しておいてください。
  2. OpenCensus をインストールする最も簡単な方法は、npm を使用する方法です。
    npm install @opencensus/core
    npm install @opencensus/exporter-stackdriver
  3. アプリケーションのメイン スクリプトまたはエントリ ポイントの一番上に、つまり他のどのコードよりも前に、以下に示す require ステートメントを配置します。
const {globalStats, MeasureUnit, AggregationType} = require('@opencensus/core');
const {StackdriverStatsExporter} = require('@opencensus/exporter-stackdriver');

Python

次のコマンドを使用して、OpenCensus コアと Stackdriver エクスポータ ライブラリをインストールします。

pip install -r opencensus/requirements.txt

指標のための OpenCensus の使用

指標のために OpenCensus を使用するようコードを設定するには、通常、以下の 3 つの手順を行います。

  1. OpenCensus 統計情報および OpenCensus Stackdriver エクスポータ パッケージをインポートする。
  2. Stackdriver エクスポータを初期化する。
  3. OpenCensus API を使用してコードを設定する。

基本的な例

以下は、これらの手順を示す最小限のプログラムです。このプログラムはループを実行してレイテンシ測定値を収集し、ループが完了すると、Stackdriver Monitoring に統計情報をエクスポートして終了します。

Go

// metrics_quickstart is an example of exporting a custom metric from
// OpenCensus to Stackdriver.
package main

import (
	"context"
	"fmt"
	"log"
	"time"

	"contrib.go.opencensus.io/exporter/stackdriver"
	"go.opencensus.io/stats"
	"go.opencensus.io/stats/view"
	"golang.org/x/exp/rand"
)

var (
	// The task latency in milliseconds.
	latencyMs = stats.Float64("task_latency", "The task latency in milliseconds", "ms")
)

func main() {
	ctx := context.Background()

	// Register the view. It is imperative that this step exists,
	// otherwise recorded metrics will be dropped and never exported.
	v := &view.View{
		Name:        "task_latency_distribution",
		Measure:     latencyMs,
		Description: "The distribution of the task latencies",

		// Latency in buckets:
		// [>=0ms, >=100ms, >=200ms, >=400ms, >=1s, >=2s, >=4s]
		Aggregation: view.Distribution(0, 100, 200, 400, 1000, 2000, 4000),
	}
	if err := view.Register(v); err != nil {
		log.Fatalf("Failed to register the view: %v", err)
	}

	// Enable OpenCensus exporters to export metrics
	// to Stackdriver Monitoring.
	// Exporters use Application Default Credentials to authenticate.
	// See https://developers.google.com/identity/protocols/application-default-credentials
	// for more details.
	exporter, err := stackdriver.NewExporter(stackdriver.Options{})
	if err != nil {
		log.Fatal(err)
	}
	// Flush must be called before main() exits to ensure metrics are recorded.
	defer exporter.Flush()

	if err := exporter.StartMetricsExporter(); err != nil {
		log.Fatalf("Error starting metric exporter: %v", err)
	}
	defer exporter.StopMetricsExporter()

	// Record 100 fake latency values between 0 and 5 seconds.
	for i := 0; i < 100; i++ {
		ms := float64(5*time.Second/time.Millisecond) * rand.Float64()
		fmt.Printf("Latency %d: %f\n", i, ms)
		stats.Record(ctx, latencyMs.M(ms))
		time.Sleep(1 * time.Second)
	}

	fmt.Println("Done recording metrics")
}

Java

import com.google.common.collect.Lists;

import io.opencensus.exporter.stats.stackdriver.StackdriverStatsExporter;
import io.opencensus.stats.Aggregation;
import io.opencensus.stats.BucketBoundaries;
import io.opencensus.stats.Measure.MeasureLong;
import io.opencensus.stats.Stats;
import io.opencensus.stats.StatsRecorder;
import io.opencensus.stats.View;
import io.opencensus.stats.View.Name;
import io.opencensus.stats.ViewManager;

import java.io.IOException;
import java.util.Collections;
import java.util.Random;
import java.util.concurrent.TimeUnit;

public class Quickstart {
  private static final int EXPORT_INTERVAL = 70;
  private static final MeasureLong LATENCY_MS = MeasureLong.create(
      "task_latency",
      "The task latency in milliseconds",
      "ms");
  // Latency in buckets:
  // [>=0ms, >=100ms, >=200ms, >=400ms, >=1s, >=2s, >=4s]
  private static final BucketBoundaries LATENCY_BOUNDARIES = BucketBoundaries.create(
      Lists.newArrayList(0d, 100d, 200d, 400d, 1000d, 2000d, 4000d));
  private static final StatsRecorder STATS_RECORDER = Stats.getStatsRecorder();

  public static void main(String[] args) throws IOException, InterruptedException {
    // Register the view. It is imperative that this step exists,
    // otherwise recorded metrics will be dropped and never exported.
    View view = View.create(
        Name.create("task_latency_distribution"),
        "The distribution of the task latencies.",
        LATENCY_MS,
        Aggregation.Distribution.create(LATENCY_BOUNDARIES),
        Collections.emptyList());

    ViewManager viewManager = Stats.getViewManager();
    viewManager.registerView(view);

    // Enable OpenCensus exporters to export metrics to Stackdriver Monitoring.
    // Exporters use Application Default Credentials to authenticate.
    // See https://developers.google.com/identity/protocols/application-default-credentials
    // for more details.
    StackdriverStatsExporter.createAndRegister();

    // Record 100 fake latency values between 0 and 5 seconds.
    Random rand = new Random();
    for (int i = 0; i < 100; i++) {
      long ms = (long) (TimeUnit.MILLISECONDS.convert(5, TimeUnit.SECONDS) * rand.nextDouble());
      System.out.println(String.format("Latency %d: %d", i, ms));
      STATS_RECORDER.newMeasureMap().put(LATENCY_MS, ms).record();
    }

    // The default export interval is 60 seconds. The thread with the StackdriverStatsExporter must
    // live for at least the interval past any metrics that must be collected, or some risk being
    // lost if they are recorded after the last export.

    System.out.println(String.format(
        "Sleeping %d seconds before shutdown to ensure all records are flushed.", EXPORT_INTERVAL));
    Thread.sleep(TimeUnit.MILLISECONDS.convert(EXPORT_INTERVAL, TimeUnit.SECONDS));
  }
}

Node.js

'use strict';

const {globalStats, MeasureUnit, AggregationType} = require('@opencensus/core');
const {StackdriverStatsExporter} = require('@opencensus/exporter-stackdriver');

const EXPORT_INTERVAL = 60;
const LATENCY_MS = globalStats.createMeasureInt64(
  'task_latency',
  MeasureUnit.MS,
  'The task latency in milliseconds'
);

// Register the view. It is imperative that this step exists,
// otherwise recorded metrics will be dropped and never exported.
const view = globalStats.createView(
  'task_latency_distribution',
  LATENCY_MS,
  AggregationType.DISTRIBUTION,
  [],
  'The distribution of the task latencies.',
  // Latency in buckets:
  // [>=0ms, >=100ms, >=200ms, >=400ms, >=1s, >=2s, >=4s]
  [0, 100, 200, 400, 1000, 2000, 4000]
);

// Then finally register the views
globalStats.registerView(view);

// Enable OpenCensus exporters to export metrics to Stackdriver Monitoring.
// Exporters use Application Default Credentials (ADCs) to authenticate.
// See https://developers.google.com/identity/protocols/application-default-credentials
// for more details.
// Expects ADCs to be provided through the environment as ${GOOGLE_APPLICATION_CREDENTIALS}
// A Stackdriver workspace is required and provided through the environment as ${GOOGLE_PROJECT_ID}
const projectId = process.env.GOOGLE_PROJECT_ID;

// GOOGLE_APPLICATION_CREDENTIALS are expected by a dependency of this code
// Not this code itself. Checking for existence here but not retaining (as not needed)
if (!projectId || !process.env.GOOGLE_APPLICATION_CREDENTIALS) {
  throw Error('Unable to proceed without a Project ID');
}

// The minimum reporting period for Stackdriver is 1 minute.
const exporter = new StackdriverStatsExporter({
  projectId: projectId,
  period: EXPORT_INTERVAL * 1000,
});

// Pass the created exporter to Stats
globalStats.registerExporter(exporter);

// Record 100 fake latency values between 0 and 5 seconds.
for (let i = 0; i < 100; i++) {
  const ms = Math.floor(Math.random() * 5);
  console.log(`Latency ${i}: ${ms}`);
  globalStats.record([
    {
      measure: LATENCY_MS,
      value: ms,
    },
  ]);
}

/**
 * The default export interval is 60 seconds. The thread with the
 * StackdriverStatsExporter must live for at least the interval past any
 * metrics that must be collected, or some risk being lost if they are recorded
 * after the last export.
 */
setTimeout(() => {
  console.log('Done recording metrics.');
}, EXPORT_INTERVAL * 1000);

Python

from random import random
import time

from opencensus.ext.stackdriver import stats_exporter
from opencensus.stats import aggregation
from opencensus.stats import measure
from opencensus.stats import stats
from opencensus.stats import view

# A measure that represents task latency in ms.
LATENCY_MS = measure.MeasureFloat(
    "task_latency",
    "The task latency in milliseconds",
    "ms")

# A view of the task latency measure that aggregates measurements according to
# a histogram with predefined bucket boundaries. This aggregate is periodically
# exported to Stackdriver Monitoring.
LATENCY_VIEW = view.View(
    "task_latency_distribution",
    "The distribution of the task latencies",
    [],
    LATENCY_MS,
    # Latency in buckets: [>=0ms, >=100ms, >=200ms, >=400ms, >=1s, >=2s, >=4s]
    aggregation.DistributionAggregation(
        [100.0, 200.0, 400.0, 1000.0, 2000.0, 4000.0]))

def main():
    # Register the view. Measurements are only aggregated and exported if
    # they're associated with a registered view.
    stats.stats.view_manager.register_view(LATENCY_VIEW)

    # Create the Stackdriver stats exporter and start exporting metrics in the
    # background, once every 60 seconds by default.
    exporter = stats_exporter.new_stats_exporter()
    print('Exporting stats to project "{}"'
          .format(exporter.options.project_id))

    # Record 100 fake latency values between 0 and 5 seconds.
    for num in range(100):
        ms = random() * 5 * 1000
        print("Latency {}: {}".format(num, ms))

        mmap = stats.stats.stats_recorder.new_measurement_map()
        mmap.measure_float_put(LATENCY_MS, ms)
        mmap.record()

    # Keep the thread alive long enough for the exporter to export at least
    # once.
    time.sleep(65)

if __name__ == '__main__':
    main()
この指標データを Stackdriver にエクスポートすると、他のデータと同じように使用できます。

このプログラムは task_latency_distribution という OpenCensus ビューを作成します。この文字列は、Stackdriver Monitoring にエクスポートされたときの指標の名前の一部になります。OpenCensus ビューが Stackdriver Monitoring の指標記述子としてどのように実現されるかは、指標記述子の取得をご覧ください。

ビュー名は、グラフ化する指標を選択するときに、検索文字列として使用できます。たとえば、Metrics Explorer の [Find resource type and metric] フィールドに入力できます。結果は、次のスクリーンショットのようになります。

Stackdriver Monitoring での OpenCensus からの指標

ヒートマップの各バーは、プログラムの 1 回の実行を表し、各バーの色付きのコンポーネントは、レイテンシ分布のバケットを表します。グラフの背後にあるデータの詳細については、Stackdriver の OpenCensus 指標をご覧ください。

OpenCensus のドキュメント

OpenCensus では、指標 API と Stackdriver エクスポータのための信頼できるリファレンス ドキュメントが提供されています。次の表に、これらのリファレンス ドキュメントへのリンクを示します。

言語 API リファレンス ドキュメント エクスポータ ドキュメント クイックスタート
Go Go API Stats Exporter と Trace Exporter 指標
Java Java API Stats Exporter 指標
NodeJS NodeJS API Stats Exporter 指標
Python Python API Stats Exporter 指標

モデルのマッピング

カスタム指標用にネイティブの Stackdriver Monitoring API がサポートされています。この使用方法については、カスタム指標の使用をご覧ください。実際に、Stackdriver 用の OpenCensus エクスポータでは、この API が使用されています。

Stackdriver Monitoring API の詳細な使用方法を知る必要がない場合でも、この API の構造と用語に精通していることは、Stackdriver Monitoring が指標を表す方法を理解するうえで役立ちます。このセクションでは、その背景の一部について説明します。

指標が Stackdriver に取り込まれると、Stackdriver Monitoring の構造に格納されます。たとえば、カスタム指標の指標記述子(Monitoring API のタイプの 1 つ)を取得できます。詳細については、MetricDescriptor をご覧ください。これらの指標記述子は、たとえばデータのグラフを作成するときに使用します。

用語とコンセプト

OpenCensus API で使用される構造は、Stackdriver Monitoring で使用される構造とは異なり、用語の使用法も一部異なります。Stackdriver Monitoring で「指標」と呼ばれるものが、OpenCensus では「統計情報」と呼ばれることがあります。たとえば、Stackdriver で指標データを送信する OpenCensus のコンポーネントは、「Stackdriver 用の統計情報エクスポータ」と呼ばれます。

指標の OpenCensus モデルの概要については、OpenCensus の指標をご覧ください。

OpenCensus 統計情報と Stackdriver Monitoring 指標のデータモデルは、1 対 1 のマッピングにまとめきれません。コンセプトの多くはそれぞれで同じですが、それらを直接置き換えることができないためです。

  • 通常、OpenCensus のビューは Monitoring API の MetricDescriptor に似ています。ビューは、個々の測定値を収集して集計する方法を記述するものです。記録されたすべての測定値はタグで分類されます。

  • OpenCensus のタグは Key-Value ペアです。これは通常、Monitoring API の LabelDescriptor に対応します。タグを使用すると、指標のフィルタリングとグループ化に使用できるコンテキスト情報を取得できます。

  • OpenCensus の測定は、記録される指標データを記述します。OpenCensus の集計は、集計用のデータに適用される機能です。これらはエクスポート時に、Stackdriver 指標記述子で報告される MetricKindValueType、単位を決定するために使用されます。

  • OpenCensus の測定値は、測定のために収集されるデータポイントです。測定値はビューに集約される必要があります。そうでない場合、個々の測定値は削除されます。この構造は、Monitoring API の Point に似ています。測定値がビューに集約されると、集約されたデータは Monitoring API の TimeSeries に似たビューデータとして保存されます。

Stackdriver の OpenCensus 指標

Stackdriver Monitoring 内で、エクスポートされた指標を調べることができます。基本的な例のスクリーンショットは、Metrics Explorer から取得しました。サンプル プログラムを実行している場合は、Metrics Explorer を使用してデータを見ることができます。

[Metrics Explorer] ページに移動

検索を制限するために指標を指定するとき、OpenCensus ビューの名前を指定できます。詳細については、指標の選択をご覧ください。

指標記述子の検索

Monitoring API を直接使用して指標データを検索できます。指標データを検索するには、OpenCensus 指標がエクスポートされた Stackdriver 名を知っている必要があります。

この情報を取得する 1 つの方法は、エクスポータによって作成された指標記述子を検索し、type フィールドの値を見つけることです。この値には、データのエクスポート元である OpenCensus ビューの名前が取り込まれています。指標記述子の詳細については、MetricDescriptor をご覧ください。

エクスポートされた指標に作成された指標記述子は、metricDescriptors.list メソッドのリファレンス ページにある API Explorer(この API を試す)ウィジェットを使用して確認できます。このツールを使用して OpenCensus 指標についての指標記述子を取得するには:

  1. name フィールドにプロジェクトの名前 projects/[PROJECT_ID] を入力します。このドキュメントでは、ID が a-gcp-project のプロジェクトを使用します。

  2. filter フィールドにフィルタを入力します。OpenCensus ビューの名前は指標名の一部になります。そのため、この名前を使用して、次のようなフィルタを指定することでリストを制限できます。

    metric.type=has_substring("task_latency_distribution")

    どのプロジェクトにも多くの指標記述子があります。OpenCensus ビューの名前を部分文字列でフィルタリングすると、ほとんどの指標記述子が除外されます。

  3. [Execute] ボタンをクリックします。

返された指標記述子を以下に示します。

{
  "metricDescriptors": [
    {
      "name": "projects/a-gcp-project/metricDescriptors/custom.googleapis.com/opencensus/task_latency_distribution",
      "labels": [
        {
          "key": "opencensus_task",
          "description": "Opencensus task identifier"
        }
      ],
      "metricKind": "CUMULATIVE",
      "valueType": "DISTRIBUTION",
      "unit": "ms",
      "description": "The distribution of the task latencies",
      "displayName": "OpenCensus/task_latency_distribution",
      "type": "custom.googleapis.com/opencensus/task_latency_distribution"
    }
  ]
}

指標記述子の次の行は、Stackdriver Monitoring の指標タイプの名前を示します。

"type": "custom.googleapis.com/opencensus/task_latency_distribution"

この情報を使用して、この指標タイプに関連付けられたデータを手動で検索できます。これは、この指標のグラフに表示されるデータでもあります。

指標データの検索

指標タイプから時系列データを手動で取得するには、timeSeries.list メソッドのリファレンス ページにあるこの API を試すツールを使用します。

  1. name フィールドにプロジェクトの名前 projects/[PROJECT_ID] を入力します。
  2. 目的の指標タイプの filter フィールドにフィルタ metric.type="custom.googleapis.com/opencensus/task_latency_distribution" を入力します。
    • キー metric.type は、timeseries に埋め込まれるタイプのフィールドです。詳細については、TimeSeries をご覧ください。
    • 値は、指標記述子から抽出された type 値です。指標記述子の検索をご覧ください。
  3. これらのフィールドの値を指定して、検索の期間を入力します。
    • interval.endTime はタイムスタンプとして指定します。たとえば 2018-10-11T15:48:38-04:00 にします。
    • interval.startTimeinterval.endTime より前である必要があります)
  4. [Execute] ボタンをクリックします。

このような検索の結果を以下に示します。

{
  "timeSeries": [
    {
      "metric": {
        "labels": {
          "opencensus_task": "java-3424@docbuild"
        },
        "type": "custom.googleapis.com/opencensus/task_latency_distribution"
      },
      "resource": {
        "type": "gce_instance",
        "labels": {
          "instance_id": "2455918024984027105",
          "zone": "us-east1-b",
          "project_id": "a-gcp-project"
        }
      },
      "metricKind": "CUMULATIVE",
      "valueType": "DISTRIBUTION",
      "points": [
        {
          "interval": {
            "startTime": "2019-04-04T17:49:34.163Z",
            "endTime": "2019-04-04T17:50:42.917Z"
          },
          "value": {
            "distributionValue": {
              "count": "100",
              "mean": 2610.11,
              "sumOfSquaredDeviation": 206029821.78999996,
              "bucketOptions": {
                "explicitBuckets": {
                  "bounds": [
                    0,
                    100,
                    200,
                    400,
                    1000,
                    2000,
                    4000
                  ]
                }
              },
              "bucketCounts": [
                "0",
                "0",
                "1",
                "6",
                "13",
                "15",
                "44",
                "21"
              ]
            }
          }
        }
      ]
    },
    [ ... data from additional program runs deleted ...]
  ]
}

ここでは次のようなデータが返されます。

  • データが収集されたモニタリング対象リソースに関する情報。OpenCensus はモニタリング対象リソース gce_instancek8s_containeraws_ec2_instance を自動的に検出できます。このデータは、Compute Engine インスタンス上で実行するプログラムから取得されたものです。他のモニタリング対象リソースの使用方法については、エクスポータ用のモニタリング対象リソースの設定をご覧ください。
  • 指標の種類と値のタイプの説明。
  • 要求された時間間隔内に収集された実際のデータポイント。
このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

ご不明な点がありましたら、Google のサポートページをご覧ください。