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 プロジェクトを選択または作成します。

    [リソースの管理] ページに移動

  3. プロジェクトに対して課金が有効になっていることを確認します。

    課金を有効にする方法について

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

カスタム指標は 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 のサポートページをご覧ください。