커스텀 측정항목 만들기

커스텀 측정항목은 사용자가 정의한 측정항목입니다. 이 페이지에서는 커스텀 측정항목의 측정항목 설명을 만드는 방법과 커스텀 측정항목 데이터를 작성하는 방법을 설명합니다.

커스텀 측정항목은 기본 제공 Cloud Monitoring 측정항목과 동일한 요소를 사용합니다.

  • 데이터 포인트 집합
  • 데이터 포인트의 의미를 알려주는 측정항목 유형 정보
  • 데이터 포인트의 출처를 알려주는 모니터링 리소스 정보

커스텀 측정항목은 기본 제공 측정항목과 동일한 방식으로 사용할 수 있습니다. 즉, 커스텀 측정항목 데이터에 대한 차트와 알림을 만들 수 있습니다.

시작하기 전에

모든 측정항목 아래에 있는 구조에 익숙하지 않은 경우 측정항목, 시계열, 리소스를 참조하세요.

커스텀 측정항목 시작하기

커스텀 측정항목을 사용하려면 새 측정항목 유형에 대한 측정항목 설명이 있어야 합니다. 측정항목 설명은 데이터 구성 방식을 정의합니다. 커스텀 측정항목 데이터 쓰기를 시작하기 전에 수집하는 데이터를 어떻게 사용할지 결정하고 데이터 조직에서 이러한 목표를 지원하는지 확인하세요.

측정항목 설명 만들기

Cloud Monitoring은 측정항목 설명을 자동으로 만들거나 Monitoring API에서 metricDescriptors.create 메서드를 사용하여 직접 만들 수 있습니다. Monitoring용 Google Cloud Console을 사용하여 측정항목 설명을 조작할 수 없습니다.

Cloud Monitoring에서 측정항목 설명을 만들도록 하려면 측정항목의 시계열 데이터를 작성하면 됩니다. 그러면 Cloud Monitoring은 작성 중인 데이터를 기반으로 설명을 만듭니다. 자세한 내용은 측정항목 설명 자동 생성을 참조하세요. 자동 생성에는 제한이 있으므로 측정항목 정의에 어떤 정보가 포함되는지 알아두면 유용합니다. 사용자 혹은 모니터링이 생성한 새 커스텀 측정항목 설명이 만들어진 후에 측정항목 설명 API 메서드시계열 API 메서드와 함께 측정항목 설명을 사용할 수 있습니다.

측정항목 설명을 명시적으로 만들었는지 또는 Monitoring이 데이터를 기반으로 만들었는지에 관계없이 데이터 구성이 쿼리 방법과 일치하는지 확인해야 합니다.

데이터 조직화

단일 머신에서 실행되는 프로그램이 있고 이 프로그램이 보조 프로그램 AB를 호출한다고 가정해 보겠습니다. AB가 호출되는 빈도를 계산하려고 합니다. 또한 프로그램 A가 분당 10회 이상 호출되고 프로그램 B가 분당 5회 이상 호출되는 경우를 알고 싶습니다.

논의를 간소화하기 위해 단일 Google Cloud 프로젝트가 있고 global 모니터링 리소스를 사용할 계획이라고 가정해 보겠습니다. 이 선택 항목에 대한 자세한 내용은 커스텀 측정항목에 대한 모니터링 리소스를 참조하세요.

다음과 같은 접근 방식을 생각해 봅시다.

  • 두 가지 커스텀 측정항목을 사용합니다. Metric-type-A는 프로그램 A에 대한 호출 수, Metric-type-B는 프로그램 B에 대한 호출 수를 카운트합니다. 이 경우 Metric-type-A에 시계열 1개, Metric-type-B에 시계열이 1개가 있습니다.

    이 데이터 모델을 사용하면 조건이 2개인 단일 알림 정책을 만들거나 조건이 하나인 2개의 알림 정책을 만들 수 있습니다. 알림 정책은 여러 조건을 지원할 수 있지만, 알림 채널에 대한 구성은 한 가지입니다.

    모니터링 중인 활동 간 데이터의 유사성에 관심이 없는 경우 이 모델이 적합할 수 있습니다. 이 예시에서 활동은 프로그램 AB에 대한 호출율입니다.

  • 단일 커스텀 측정항목을 사용하고 라벨을 사용하여 프로그램 식별자를 저장합니다. 예를 들어 라벨에 A 또는 B 값을 저장할 수 있습니다. Monitoring은 고유한 라벨 조합별로 시계열을 생성하므로 이 단일 측정항목 유형에는 두 개의 시계열이 있습니다.

    이전 모델과 마찬가지로 단일 알림 정책 또는 두 개의 알림 정책을 만들 수 있습니다. 하지만 알림 정책의 조건이 더 복잡합니다. 프로그램 A의 호출 비율이 임곗값을 초과하는 경우 이슈를 생성하는 조건을 만들려면 조건에 라벨 값이 A이고 다른 모든 데이터 포인트는 제외하는 데이터 포인트를 포함하는 필터가 포함되어야 합니다.

    이 모델의 장점 가운데 한 가지는 간단하게 비율을 계산할 수 있다는 것입니다. 예를 들어 A 호출로 인한 총량을 확인할 수 있습니다.

  • 단일 커스텀 측정항목을 사용하여 호출 수를 계산하지만 어떤 프로그램을 호출했는지 기록하는 데 라벨을 사용하지 않습니다. 이 모델에는 두 프로그램의 데이터를 결합하는 단일 시계열이 있습니다. 그러나 두 프로그램의 데이터를 분리할 수 없으므로 목표를 충족하는 알림 정책을 만들 수 없습니다.

커스텀 측정항목 이름 지정

커스텀 측정항목을 만들 때 측정항목 유형을 나타내는 문자열 식별자를 정의합니다. 이 문자열은 Google Cloud 프로젝트의 커스텀 측정항목에서 고유해야 하며 측정항목을 사용자 정의 측정항목으로 표시하는 프리픽스를 사용해야 합니다. Monitoring의 경우 허용 가능한 프리픽스는 custom.googleapis.com/external.googleapis.com/prometheus입니다. 프리픽스 다음에 수집하는 항목을 설명하는 이름이 표시됩니다. 커스텀 측정항목의 이름을 지정하는 데 권장되는 방법은 이름 지정 규칙을 참조하세요. 다음은 측정항목 유형에 대한 두 가지 종류의 식별자 예시입니다.

custom.googleapis.com/cpu_utilization
custom.googleapis.com/instance/cpu/utilization

모든 측정항목 유형에는 리소스 이름이라는 서비스 전체에서 고유한 식별자가 있습니다. 측정항목 유형의 리소스 이름 형식은 다음과 같습니다.

projects/[PROJECT_ID]/metricDescriptors/[METRIC_TYPE]

여기서 METRIC_TYPE는 측정항목 유형의 문자열 식별자입니다. 앞서 다룬 커스텀 측정항목 예시를 프로젝트 my-project-id에서 만들었다면 측정항목에 다음과 같은 리소스 이름을 지정합니다.

projects/my-project-id/metricDescriptors/custom.googleapis.com/cpu_utilization
projects/my-project-id/metricDescriptors/custom.googleapis.com/instance/cpu/utilization

이름 또는 유형 측정항목 설명에서 name 필드는 측정항목 유형의 리소스 이름을 저장하고 type 필드는 METRIC_TYPE 문자열을 저장합니다.

모니터링 리소스 유형 선택

시계열에 데이터를 쓸 때는 데이터의 출처를 명시해야 합니다. 이렇게 하려면 데이터의 출처를 나타내는 모니터링 리소스 유형을 선택한 다음 이를 사용하여 특정 출처를 설명합니다. 모니터링 리소스는 측정항목 유형의 일부가 아닙니다. 대신 데이터를 작성하는 시계열에는 데이터를 설명하는 측정항목 유형에 대한 참조와 데이터의 출처를 나타내는 모니터링 리소스에 대한 참조가 포함됩니다.

측정항목 설명을 만들기 전에 모니터링 리소스를 고려하세요. 사용 중인 모니터링 리소스 유형은 측정항목 설명에 포함해야 하는 라벨에 영향을 줍니다. 예를 들어 VM 인스턴스 모니터링 리소스를 데이터와 함께 사용하는 경우 인스턴스를 지정하기 위해 측정항목 라벨이 필요하지 않습니다. 자세한 내용은 커스텀 측정항목 모니터링 리소스를 참조하세요.

각 측정항목의 데이터 포인트는 모니터링 리소스 객체와 연결되어야 합니다. 다른 모니터링 리소스 객체의 요소는 다른 시계열에 유지됩니다.

커스텀 측정항목에 대한 모니터링 리소스

커스텀 측정항목에서는 다음과 같은 모니터링 리소스 유형만 사용할 수 있습니다.

애플리케이션 코드가 실행되는 물리적 리소스를 나타내는 모니터링 리소스 객체를 사용하는 것이 일반적입니다. 이 방식의 장점은 다음과 같습니다.

  • 단일 리소스 유형을 사용할 때보다 성능이 향상됩니다.
  • 동일한 시계열에 작성된 여러 프로세스로 인해 데이터의 순서가 잘못되는 현상을 방지합니다.
  • 커스텀 측정항목 데이터를 동일한 리소스의 다른 측정항목 데이터와 그룹화할 수 있습니다.

global 리소스와 일반 리소스 비교

generic_taskgeneric_node 리소스 유형은 좀 더 적합한 특정 리소스 유형이 없는 상황에서 유용합니다. generic_task 유형은 애플리케이션 등의 작업과 같은 리소스를 정의할 때 유용합니다. generic_node 유형은 가상 머신 등 노드와 같은 리소스를 정의할 때 유용합니다. 두 generic_* 유형에는 고유한 리소스 객체를 정의할 때 사용할 수 있는 공통 라벨이 여러 개 있으므로, 집계 및 축소를 위한 측정항목 필터에서 이들을 간편하게 사용할 수 있습니다.

반대로 global 리소스 유형에는 project_idlocation 라벨만 있습니다. 프로젝트에 측정항목 소스가 여러 개 있는 경우, 동일한 global 리소스 객체를 사용하면 측정항목 데이터의 충돌 및 덮어쓰기가 발생할 수 있습니다.

측정항목 설명 만들기

커스텀 측정항목에 대해 수집하는 데이터는 측정항목에 대한 다양한 정보를 지정하는 MetricDescriptor 객체와 연결되어야 합니다.

측정항목 설명을 직접 만들거나 Monitoring에서 자동으로 만들 수 있습니다.

제한된 방법으로 기존 설명을 변경할 수 있습니다. 자세한 내용은 측정항목 설명 수정을 참조하세요.

측정항목 설명 자동 생성

커스텀 측정항목의 측정항목 설명이 아직 존재하지 않는 경우 측정항목 데이터를 작성하면 측정항목 설명이 자동으로 생성됩니다. 하지만 이 새 측정항목 설명은 정확히 원하는 설명이 아닐 수도 있습니다. 측정항목 설명은 몇 가지 가정과 기본값에 따라 자동으로 생성됩니다.

특히 timeSeries.create 호출 중에 TimeSeries 객체에 존재하지 않는 측정항목 유형 이름을 지정하는 Metric 객체가 포함되어 있으면 Cloud Monitoring은 다음 필드가 포함된 새 MetricDescriptor를 만듭니다.

  • type: 유형은 Metric 객체의 type 필드에서 복사됩니다.
  • name: 메서드 호출의 프로젝트 ID 및 Metric 객체의 type 값으로 만든 이름입니다.
  • labels: Metric 객체에 표시되는 라벨입니다. 새 측정항목 설명의 각 라벨 설명에는 다음과 같은 필드가 포함됩니다.
    • key: Metric 객체의 라벨 키
    • valueType: STRING
    • description: 설정되지 않음
  • metricKind: 기본 측정항목 종류는 GAUGE이지만 TimeSeries 객체의 metricKind 매개변수를 지정하면 해당 종류가 새 측정항목 종류에 적용됩니다. GAUGECUMULATIVE 종류만 지정할 수 있습니다.
  • valueType: 값 유형은 BOOL, INT64, DOUBLE 또는 DISTRIBUTION 중 하나로 작성된 Point의 유형 값에서 가져옵니다. TimeSeriesvalueType 필드에 값 유형을 지정하면 해당 유형은 Point의 유형과 일치해야 합니다.
  • unit: 설정되지 않음
  • description: "Auto created custom metric.".
  • displayName: 설정되지 않음

하나의 timeSeries.create 호출에 존재하지 않는 동일한 측정항목 유형을 참조하는 여러 TimeSeries 객체를 포함시킬 수 있습니다. 이 경우 새 유형의 필드가 동일하게 설정됩니다. 단, 새 측정항목 설명의 라벨은 create에 대한 이 호출에서 모든 시계열의 Metric 객체에 있는 모든 라벨이 통합되어 구성됩니다.

다음 단계: 측정항목 데이터 작성을 참조하세요.

수동으로 측정항목 설명 만들기

이 섹션에서는 커스텀 측정항목의 측정항목 설명을 만드는 방법을 설명합니다.

시작하기 전에

다음 단계를 완료합니다.

  • 커스텀 측정항목의 측정항목 이름 또는 식별자를 선택합니다.

  • 측정항목의 표시 이름과 설명을 선택합니다. 표시 이름은 Google Cloud Console에서 사용됩니다.

  • 커스텀 측정항목을 정의하고 시계열 데이터를 작성할 프로젝트를 선택합니다. 여러 프로젝트에 동일한 측정항목이 필요하다면 프로젝트마다 측정항목을 똑같이 정의합니다.

    AWS 계정에서 관리하는 리소스에서 커스텀 측정항목을 작성하려면 해당 계정의 AWS 커넥터 프로젝트에서 측정항목 설명을 만듭니다.

  • 측정항목의 종류, 값 유형, 단위(선택사항)를 결정합니다. 커스텀 측정항목에서 지원되지 않는 값 유형 및 측정항목 종류도 일부 있습니다. 이러한 필드에 대한 자세한 내용은 값 유형 및 측정항목 종류를 참조하세요.

  • 측정항목 라벨(이름, 값 유형, 설명)을 선택합니다.

기본 제공 측정항목을 찾아보고 시계열 데이터를 살펴보면 옵션을 선택하는 데 도움이 됩니다.

측정항목 설명 만들기

커스텀 측정항목의 설명을 만들려면 metricDescriptors.create 메서드를 호출하고 MetricDescriptor 객체를 전달합니다.

일반적으로 기존 커스텀 측정항목 설명과 동일한 유형 이름을 사용하여 metricDescriptors.create를 호출하면 오류가 발생합니다. 하지만 새 MetricDescriptor 객체의 모든 필드가 기존 설명의 필드와 정확히 일치할 경우에는 오류에 해당하지 않으며 아무런 영향도 미치지 않습니다.

다음 예시에서는 게이지 커스텀 측정항목을 만듭니다.

프로토콜

측정항목 설명을 만들려면 metricDescriptors.create 메서드를 사용합니다. 메서드의 참조 페이지에서 API 탐색기 위젯을 사용하여 이 메서드를 실행할 수 있습니다. 자세한 내용은 API 탐색기를 참조하세요.

다음은 metricDescriptors.create의 샘플 매개변수입니다.

  • name (URL): projects/[PROJECT_ID]
  • 요청 본문: 다음과 같은 MetricDescriptor 객체를 제공합니다.

    {
      "name": "",
      "description": "Daily sales records from all branch stores.",
      "displayName": "Sales",
      "type": "custom.googleapis.com/stores/sales",
      "metricKind": "CUMULATIVE",
      "valueType": "DOUBLE",
      "unit": "{USD}",
      "labels": [
        {
          "key": "store_id",
          "valueType": "STRING",
          "description": "The ID of the store."
        },
      ],
    }
    

[PROJECT_ID] 대신 프로젝트 ID를 사용하여 위젯의 필드에 이 값을 입력합니다.

요청 본문으로 채워진 이 API 대화상자에서 측정항목 설명을 만들어보세요.

메서드를 실행하려면 실행 버튼을 클릭합니다.

사용해 보기

새 커스텀 측정항목을 만들 때 MetricDescriptorname 필드는 무시되고 생략될 수 있습니다. create 메서드는 name 필드가 채워진 새 측정항목 설명을 반환합니다. 이 예시에서는 다음과 같습니다.

"name": "projects/[PROJECT_ID]/metricDescriptors/custom.googleapis.com/stores/daily_sales"

예를 들어 측정항목 설명을 가져오려면 이 이름을 사용합니다.

C#

        public static object CreateMetric(string projectId,
            string metricType = "custom.googleapis.com/stores/daily_sales")
        {
            // Create client.
            MetricServiceClient metricServiceClient = MetricServiceClient.Create();

            // Prepare custom metric descriptor.
            MetricDescriptor metricDescriptor = new MetricDescriptor();
            metricDescriptor.DisplayName = "Daily Sales";
            metricDescriptor.Description = "Daily sales records from all branch stores.";
            metricDescriptor.MetricKind = MetricKind.Gauge;
            metricDescriptor.ValueType = MetricDescriptor.Types.ValueType.Double;
            metricDescriptor.Type = metricType;
            metricDescriptor.Unit = "{USD}";
            LabelDescriptor labels = new LabelDescriptor();
            labels.Key = "store_id";
            labels.ValueType = LabelDescriptor.Types.ValueType.String;
            labels.Description = "The ID of the store.";
            metricDescriptor.Labels.Add(labels);
            CreateMetricDescriptorRequest request = new CreateMetricDescriptorRequest
            {
                ProjectName = new ProjectName(projectId),
            };
            request.MetricDescriptor = metricDescriptor;
            // Make the request.
            MetricDescriptor response = metricServiceClient.CreateMetricDescriptor(request);
            Console.WriteLine("Done creating metric descriptor:");
            Console.WriteLine(JObject.Parse($"{response}").ToString());
            return 0;
        }

Go


import (
	"context"
	"fmt"
	"io"

	monitoring "cloud.google.com/go/monitoring/apiv3"
	"google.golang.org/genproto/googleapis/api/label"
	"google.golang.org/genproto/googleapis/api/metric"
	metricpb "google.golang.org/genproto/googleapis/api/metric"
	monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3"
)

// createCustomMetric creates a custom metric specified by the metric type.
func createCustomMetric(w io.Writer, projectID, metricType string) (*metricpb.MetricDescriptor, error) {
	ctx := context.Background()
	c, err := monitoring.NewMetricClient(ctx)
	if err != nil {
		return nil, err
	}
	md := &metric.MetricDescriptor{
		Name: "Custom Metric",
		Type: metricType,
		Labels: []*label.LabelDescriptor{{
			Key:         "environment",
			ValueType:   label.LabelDescriptor_STRING,
			Description: "An arbitrary measurement",
		}},
		MetricKind:  metric.MetricDescriptor_GAUGE,
		ValueType:   metric.MetricDescriptor_INT64,
		Unit:        "s",
		Description: "An arbitrary measurement",
		DisplayName: "Custom Metric",
	}
	req := &monitoringpb.CreateMetricDescriptorRequest{
		Name:             "projects/" + projectID,
		MetricDescriptor: md,
	}
	m, err := c.CreateMetricDescriptor(ctx, req)
	if err != nil {
		return nil, fmt.Errorf("could not create custom metric: %v", err)
	}

	fmt.Fprintf(w, "Created %s\n", m.GetName())
	return m, nil
}

자바

// Your Google Cloud Platform project ID
String projectId = System.getProperty("projectId");
String metricType = CUSTOM_METRIC_DOMAIN + "/" + type;

final MetricServiceClient client = MetricServiceClient.create();
ProjectName name = ProjectName.of(projectId);

MetricDescriptor descriptor =
    MetricDescriptor.newBuilder()
        .setType(metricType)
        .addLabels(
            LabelDescriptor.newBuilder()
                .setKey("store_id")
                .setValueType(LabelDescriptor.ValueType.STRING))
        .setDescription("This is a simple example of a custom metric.")
        .setMetricKind(MetricDescriptor.MetricKind.GAUGE)
        .setValueType(MetricDescriptor.ValueType.DOUBLE)
        .build();

CreateMetricDescriptorRequest request =
    CreateMetricDescriptorRequest.newBuilder()
        .setName(name.toString())
        .setMetricDescriptor(descriptor)
        .build();

client.createMetricDescriptor(request);

Node.js

// Imports the Google Cloud client library
const monitoring = require('@google-cloud/monitoring');

// Creates a client
const client = new monitoring.MetricServiceClient();

/**
 * TODO(developer): Uncomment and edit the following lines of code.
 */
// const projectId = 'YOUR_PROJECT_ID';

const request = {
  name: client.projectPath(projectId),
  metricDescriptor: {
    description: 'Daily sales records from all branch stores.',
    displayName: 'Daily Sales',
    type: 'custom.googleapis.com/stores/daily_sales',
    metricKind: 'GAUGE',
    valueType: 'DOUBLE',
    unit: '{USD}',
    labels: [
      {
        key: 'store_id',
        valueType: 'STRING',
        description: 'The ID of the store.',
      },
    ],
  },
};

// Creates a custom metric descriptor
const [descriptor] = await client.createMetricDescriptor(request);
console.log('Created custom Metric:\n');
console.log(`Name: ${descriptor.displayName}`);
console.log(`Description: ${descriptor.description}`);
console.log(`Type: ${descriptor.type}`);
console.log(`Kind: ${descriptor.metricKind}`);
console.log(`Value Type: ${descriptor.valueType}`);
console.log(`Unit: ${descriptor.unit}`);
console.log('Labels:');
descriptor.labels.forEach(label => {
  console.log(`  ${label.key} (${label.valueType}) - ${label.description}`);
});

PHP

use Google\Cloud\Monitoring\V3\MetricServiceClient;
use Google\Api\LabelDescriptor;
use Google\Api\LabelDescriptor_ValueType;
use Google\Api\MetricDescriptor;
use Google\Api\MetricDescriptor_MetricKind;
use Google\Api\MetricDescriptor_ValueType;

/**
 * Create a new metric in Stackdriver Monitoring.
 * Example:
 * ```
 * create_metric($projectId);
 * ```
 *
 * @param string $projectId Your project ID
 */
function create_metric($projectId)
{
    $metrics = new MetricServiceClient([
        'projectId' => $projectId,
    ]);

    $projectName = $metrics->projectName($projectId);

    $descriptor = new MetricDescriptor();
    $descriptor->setDescription('Daily sales records from all branch stores.');
    $descriptor->setDisplayName('Daily Sales');
    $descriptor->setType('custom.googleapis.com/stores/daily_sales');
    $descriptor->setMetricKind(MetricDescriptor_MetricKind::GAUGE);
    $descriptor->setValueType(MetricDescriptor_ValueType::DOUBLE);
    $descriptor->setUnit('{USD}');
    $label = new LabelDescriptor();
    $label->setKey('store_id');
    $label->setValueType(LabelDescriptor_ValueType::STRING);
    $label->setDescription('The ID of the store.');
    $labels = [$label];
    $descriptor->setLabels($labels);

    $descriptor = $metrics->createMetricDescriptor($projectName, $descriptor);
    printf('Created a metric: ' . $descriptor->getName() . PHP_EOL);
}

Python

client = monitoring_v3.MetricServiceClient()
project_name = f"projects/{project_id}"
descriptor = ga_metric.MetricDescriptor()
descriptor.type = "custom.googleapis.com/my_metric" + str(uuid.uuid4())
descriptor.metric_kind = ga_metric.MetricDescriptor.MetricKind.GAUGE
descriptor.value_type = ga_metric.MetricDescriptor.ValueType.DOUBLE
descriptor.description = "This is a simple example of a custom metric."

labels = ga_label.LabelDescriptor()
labels.key = "TestLabel"
labels.value_type = ga_label.LabelDescriptor.ValueType.STRING
labels.description = "This is a test label"
descriptor.labels.append(labels)

descriptor = client.create_metric_descriptor(
    name=project_name, metric_descriptor=descriptor
)
print("Created {}.".format(descriptor.name))

Ruby

# Your Google Cloud Platform project ID
# project_id = "YOUR_PROJECT_ID"

# Example metric type
# metric_type = "custom.googleapis.com/my_metric"

client = Google::Cloud::Monitoring.metric_service
project_name = client.project_path project: project_id

descriptor = Google::Api::MetricDescriptor.new(
  type:        metric_type,
  metric_kind: Google::Api::MetricDescriptor::MetricKind::GAUGE,
  value_type:  Google::Api::MetricDescriptor::ValueType::DOUBLE,
  description: "This is a simple example of a custom metric."
)

result = client.create_metric_descriptor name:              project_name,
                                         metric_descriptor: descriptor
p "Created #{result.name}"
p result

문제가 발생할 경우 API 호출 문제 해결을 참조하세요.

다음 단계: 측정항목 데이터 작성을 참조하세요.

측정항목 삭제

커스텀 측정항목을 삭제하려면 측정항목 설명을 삭제합니다. Google Cloud 프로젝트에 저장된 시계열 데이터는 삭제할 수 없습니다. 하지만 측정항목 설명을 삭제하면 데이터에 액세스할 수 없게 됩니다. 데이터는 데이터 보관 정책에 따라 만료 및 삭제됩니다.

기본 제공 측정항목의 측정항목 설명은 삭제할 수 없습니다.

커스텀 측정항목 설명을 삭제하려면 metricDescriptors.delete 메서드를 호출합니다.

프로토콜

측정항목 설명을 삭제하려면 metricDescriptors.delete 메서드를 호출합니다. 메서드의 참조 페이지에서 API 탐색기 위젯을 사용하여 이 메서드를 실행할 수 있습니다. 자세한 내용은 API 탐색기를 참조하세요.

수동으로 측정항목 설명 만들기에서 만든 stores/daily_sales 커스텀 측정항목을 삭제하려면 다음 안내를 따르세요.

  1. metricDescriptors.delete의 참조 페이지로 이동합니다.
  2. API 탐색기 위젯에 측정항목 설명 이름을 제공합니다.

    이름: projects/[PROJECT_ID]/metricDescriptors/custom.googleapis.com/stores/daily_sales

  3. 실행 버튼을 클릭합니다.

사용해 보기

C#

public static object DeleteMetric(string projectId, string metricType)
{
    // Create client.
    MetricServiceClient metricServiceClient = MetricServiceClient.Create();
    // Initialize request argument(s).
    MetricDescriptorName name = new MetricDescriptorName(projectId, metricType);
    // Make the request.
    metricServiceClient.DeleteMetricDescriptor(name);
    Console.WriteLine($"Done deleting metric descriptor: {name}");
    return 0;
}

Go


import (
	"context"
	"fmt"
	"io"

	monitoring "cloud.google.com/go/monitoring/apiv3"
	monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3"
)

// deleteMetric deletes the given metric. name should be of the form
// "projects/PROJECT_ID/metricDescriptors/METRIC_TYPE".
func deleteMetric(w io.Writer, name string) error {
	ctx := context.Background()
	c, err := monitoring.NewMetricClient(ctx)
	if err != nil {
		return err
	}
	req := &monitoringpb.DeleteMetricDescriptorRequest{
		Name: name,
	}

	if err := c.DeleteMetricDescriptor(ctx, req); err != nil {
		return fmt.Errorf("could not delete metric: %v", err)
	}
	fmt.Fprintf(w, "Deleted metric: %q\n", name)
	return nil
}

자바

String projectId = System.getProperty("projectId");
final MetricServiceClient client = MetricServiceClient.create();
MetricDescriptorName metricName = MetricDescriptorName.of(projectId, name);
client.deleteMetricDescriptor(metricName);
System.out.println("Deleted descriptor " + name);

Node.js

// Imports the Google Cloud client library
const monitoring = require('@google-cloud/monitoring');

// Creates a client
const client = new monitoring.MetricServiceClient();

/**
 * TODO(developer): Uncomment and edit the following lines of code.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const metricId = 'custom.googleapis.com/stores/daily_sales';

const request = {
  name: client.projectMetricDescriptorPath(projectId, metricId),
};

// Deletes a metric descriptor
const [result] = await client.deleteMetricDescriptor(request);
console.log(`Deleted ${metricId}`, result);

PHP

use Google\Cloud\Monitoring\V3\MetricServiceClient;

/**
 * Example:
 * ```
 * delete_metric($projectId, $databaseId);
 * ```
 *
 * @param string $projectId Your project ID
 * @param string $metricId  The ID of the Metric Descriptor to delete
 */
function delete_metric($projectId, $metricId)
{
    $metrics = new MetricServiceClient([
        'projectId' => $projectId,
    ]);

    $metricPath = $metrics->metricDescriptorName($projectId, $metricId);
    $ret = $metrics->deleteMetricDescriptor($metricPath);

    printf('Deleted a metric: ' . $metricPath . PHP_EOL);
}

Python

client = monitoring_v3.MetricServiceClient()
client.delete_metric_descriptor(name=descriptor_name)
print("Deleted metric descriptor {}.".format(descriptor_name))

Ruby

# Your Google Cloud Platform project ID
# project_id = "YOUR_PROJECT_ID"

# Example metric type
# metric_type = "custom.googleapis.com/my_metric"

client = Google::Cloud::Monitoring.metric_service
metric_name = client.metric_descriptor_path project:           project_id,
                                            metric_descriptor: metric_type

client.delete_metric_descriptor name: metric_name
p "Deleted metric descriptor #{metric_name}."

문제가 발생할 경우 API 호출 문제 해결을 참조하세요.

측정항목 데이터 작성

커스텀 측정항목의 측정항목 유형에만 데이터를 작성할 수 있습니다. 데이터를 작성하려면 timeSeries.create 메서드를 사용하세요. 시계열이 이미 있으면 이 메서드는 기존 시계열에 새 데이터 포인트를 추가합니다. 시계열이 없는 경우 이 메서드는 시계열을 만들고 데이터를 추가합니다.

TimeSeries 객체 목록을 timeSeries.create에 전달하여 데이터 포인트를 작성합니다. 최대 목록 크기는 200이고 목록의 객체마다 다른 시계열을 지정해야 합니다.

  • 각 시계열은 TimeSeries 객체의 metricresource 필드로 식별됩니다. 이 필드는 데이터의 측정항목 유형과 데이터가 수집된 모니터링 리소스를 나타냅니다.
  • metricKindvalueType 필드는 생략합니다. 이 두 필드는 데이터 포인트를 쓸 때 무시됩니다.
  • TimeSeries 객체에는 단일 Point 객체만 포함되어야 합니다.

    • 포인트의 값 및 시간 간격이 측정항목 유형의 정의와 일치해야 합니다. 다양한 측정항목 종류의 시간 간격에 대한 자세한 내용은 TimeInterval을 참조하세요.
    • 포인트의 시간 간격이 시계열에 이미 존재하는 포인트보다 늦은 시점에 존재해야 합니다.
    • 간격의 종료 시간이 25시간보다 이전이거나 5분보다 늦은 시점이어서는 안 됩니다.
  • 동일한 시계열에 한 개를 초과하는 포인트를 작성하려면 포인트마다 timeSeries.create 메서드를 따로 호출합니다. 10초당 포인트 1개보다 빠른 속도로 단일 시계열에 데이터를 쓰지 마세요. 여러 데이터 포인트를 각기 다른 시계열에 추가할 경우에는 속도 한도가 적용되지 않습니다.

프로토콜

측정항목 데이터를 작성하려면 timeSeries.create 메서드를 사용하세요. 메서드의 참조 페이지에서 API 탐색기 위젯을 사용하여 이 메서드를 실행할 수 있습니다. 자세한 내용은 API 탐색기를 참조하세요.

수동으로 측정항목 설명 만들기에서 만든 stores/daily_sales 커스텀 측정항목에 대한 포인트를 작성하려면 다음 안내를 따르세요.

  1. timeSeries.create의 참조 페이지로 이동합니다.
  2. API 탐색기 위젯에 아래의 매개변수를 제공합니다.
  3. 실행 버튼을 클릭합니다.

다음 샘플 매개변수를 사용합니다.

  • 이름: projects/[PROJECT_ID]
  • 요청 본문: TimeSeries 객체 목록을 포함합니다. 다음 샘플에는 목록의 시계열이 하나만 있습니다.

    {
     "timeSeries": [
      {
       "metric": {
        "type": "custom.googleapis.com/my_metric",
        "labels": {
         "my_label": "my_value"
        }
       },
       "resource": {
        "type": "gce_instance",
        "labels": {
         "project_id": "[PROJECT_ID]",
         "instance_id": "1234567890123456789",
         "zone": "us-central1-f"
        }
       },
       "points": [
        {
         "interval": {
          "endTime": "2018-06-01T10:00:00-04:00"
         },
         "value": {
          "doubleValue": 123.45
         }
        }
       ]
      }
     ]
    }
    

사용해 보기

C#

        public static object WriteTimeSeriesData(string projectId)
        {
            // Create client.
            MetricServiceClient metricServiceClient = MetricServiceClient.Create();
            // Initialize request argument(s).
            ProjectName name = new ProjectName(projectId);
            // Prepare a data point.
            Point dataPoint = new Point();
            TypedValue salesTotal = new TypedValue();
            salesTotal.DoubleValue = 123.45;
            dataPoint.Value = salesTotal;
            Timestamp timeStamp = new Timestamp();
            timeStamp.Seconds = (long)(DateTime.UtcNow - s_unixEpoch).TotalSeconds;
            TimeInterval interval = new TimeInterval();
            interval.EndTime = timeStamp;
            dataPoint.Interval = interval;

            // Prepare custom metric.
            Metric metric = new Metric();
            metric.Type = "custom.googleapis.com/stores/daily_sales";
            metric.Labels.Add("store_id", "Pittsburgh");

            // Prepare monitored resource.
            MonitoredResource resource = new MonitoredResource();
            resource.Type = "global";
            resource.Labels.Add("project_id", projectId);

            // Create a new time series using inputs.
            TimeSeries timeSeriesData = new TimeSeries();
            timeSeriesData.Metric = metric;
            timeSeriesData.Resource = resource;
            timeSeriesData.Points.Add(dataPoint);

            // Add newly created time series to list of time series to be written.
            IEnumerable<TimeSeries> timeSeries = new List<TimeSeries> { timeSeriesData };
            // Write time series data.
            metricServiceClient.CreateTimeSeries(name, timeSeries);
            Console.WriteLine("Done writing time series data:");
            Console.WriteLine(JObject.Parse($"{timeSeriesData}").ToString());
            return 0;
        }

Go


// writeTimeSeriesValue writes a value for the custom metric created
func writeTimeSeriesValue(projectID, metricType string) error {
	ctx := context.Background()
	c, err := monitoring.NewMetricClient(ctx)
	if err != nil {
		return err
	}
	now := &timestamp.Timestamp{
		Seconds: time.Now().Unix(),
	}
	req := &monitoringpb.CreateTimeSeriesRequest{
		Name: "projects/" + projectID,
		TimeSeries: []*monitoringpb.TimeSeries{{
			Metric: &metricpb.Metric{
				Type: metricType,
				Labels: map[string]string{
					"environment": "STAGING",
				},
			},
			Resource: &monitoredres.MonitoredResource{
				Type: "gce_instance",
				Labels: map[string]string{
					"instance_id": "test-instance",
					"zone":        "us-central1-f",
				},
			},
			Points: []*monitoringpb.Point{{
				Interval: &monitoringpb.TimeInterval{
					StartTime: now,
					EndTime:   now,
				},
				Value: &monitoringpb.TypedValue{
					Value: &monitoringpb.TypedValue_Int64Value{
						Int64Value: rand.Int63n(10),
					},
				},
			}},
		}},
	}
	log.Printf("writeTimeseriesRequest: %+v\n", req)

	err = c.CreateTimeSeries(ctx, req)
	if err != nil {
		return fmt.Errorf("could not write time series value, %v ", err)
	}
	return nil
}

자바

String projectId = System.getProperty("projectId");
// Instantiates a client
MetricServiceClient metricServiceClient = MetricServiceClient.create();

// Prepares an individual data point
TimeInterval interval =
    TimeInterval.newBuilder()
        .setEndTime(Timestamps.fromMillis(System.currentTimeMillis()))
        .build();
TypedValue value = TypedValue.newBuilder().setDoubleValue(123.45).build();
Point point = Point.newBuilder().setInterval(interval).setValue(value).build();

List<Point> pointList = new ArrayList<>();
pointList.add(point);

ProjectName name = ProjectName.of(projectId);

// Prepares the metric descriptor
Map<String, String> metricLabels = new HashMap<>();
Metric metric =
    Metric.newBuilder()
        .setType("custom.googleapis.com/my_metric")
        .putAllLabels(metricLabels)
        .build();

// Prepares the monitored resource descriptor
Map<String, String> resourceLabels = new HashMap<>();
resourceLabels.put("instance_id", "1234567890123456789");
resourceLabels.put("zone", "us-central1-f");

MonitoredResource resource =
    MonitoredResource.newBuilder().setType("gce_instance").putAllLabels(resourceLabels).build();

// Prepares the time series request
TimeSeries timeSeries =
    TimeSeries.newBuilder()
        .setMetric(metric)
        .setResource(resource)
        .addAllPoints(pointList)
        .build();

List<TimeSeries> timeSeriesList = new ArrayList<>();
timeSeriesList.add(timeSeries);

CreateTimeSeriesRequest request =
    CreateTimeSeriesRequest.newBuilder()
        .setName(name.toString())
        .addAllTimeSeries(timeSeriesList)
        .build();

// Writes time series data
metricServiceClient.createTimeSeries(request);
System.out.println("Done writing time series value.");

Node.js

// Imports the Google Cloud client library
const monitoring = require('@google-cloud/monitoring');

// Creates a client
const client = new monitoring.MetricServiceClient();

/**
 * TODO(developer): Uncomment and edit the following lines of code.
 */
// const projectId = 'YOUR_PROJECT_ID';

const dataPoint = {
  interval: {
    endTime: {
      seconds: Date.now() / 1000,
    },
  },
  value: {
    doubleValue: 123.45,
  },
};

const timeSeriesData = {
  metric: {
    type: 'custom.googleapis.com/stores/daily_sales',
    labels: {
      store_id: 'Pittsburgh',
    },
  },
  resource: {
    type: 'global',
    labels: {
      project_id: projectId,
    },
  },
  points: [dataPoint],
};

const request = {
  name: client.projectPath(projectId),
  timeSeries: [timeSeriesData],
};

// Writes time series data
const result = await client.createTimeSeries(request);
console.log('Done writing time series data.', result);

PHP

use Google\Api\Metric;
use Google\Api\MonitoredResource;
use Google\Cloud\Monitoring\V3\MetricServiceClient;
use Google\Cloud\Monitoring\V3\Point;
use Google\Cloud\Monitoring\V3\TimeInterval;
use Google\Cloud\Monitoring\V3\TimeSeries;
use Google\Cloud\Monitoring\V3\TypedValue;
use Google\Protobuf\Timestamp;

/**
 * Example:
 * ```
 * write_timeseries($projectId);
 * ```
 *
 * @param string $projectId Your project ID
 */
function write_timeseries($projectId)
{
    $metrics = new MetricServiceClient([
        'projectId' => $projectId,
    ]);

    $projectName = $metrics->projectName($projectId);

    $endTime = new Timestamp();
    $endTime->setSeconds(time());
    $interval = new TimeInterval();
    $interval->setEndTime($endTime);

    $value = new TypedValue();
    $value->setDoubleValue(123.45);

    $point = new Point();
    $point->setValue($value);
    $point->setInterval($interval);
    $points = [$point];

    $metric = new Metric();
    $metric->setType('custom.googleapis.com/stores/daily_sales');
    $labels = ['store_id' => 'Pittsburg'];
    $metric->setLabels($labels);

    $resource = new MonitoredResource();
    $resource->setType('global');
    $labels = ['project_id' => $projectId];
    $resource->setLabels($labels);

    $timeSeries = new TimeSeries();
    $timeSeries->setMetric($metric);
    $timeSeries->setResource($resource);
    $timeSeries->setPoints($points);

    $result = $metrics->createTimeSeries(
        $projectName,
        [$timeSeries]);

    printf('Done writing time series data.' . PHP_EOL);
}

Python

client = monitoring_v3.MetricServiceClient()
project_name = f"projects/{project_id}"

series = monitoring_v3.TimeSeries()
series.metric.type = "custom.googleapis.com/my_metric" + str(uuid.uuid4())
series.resource.type = "gce_instance"
series.resource.labels["instance_id"] = "1234567890123456789"
series.resource.labels["zone"] = "us-central1-f"
now = time.time()
seconds = int(now)
nanos = int((now - seconds) * 10 ** 9)
interval = monitoring_v3.TimeInterval(
    {"end_time": {"seconds": seconds, "nanos": nanos}}
)
point = monitoring_v3.Point({"interval": interval, "value": {"double_value": 3.14}})
series.points = [point]
client.create_time_series(name=project_name, time_series=[series])

Ruby

# Your Google Cloud Platform project ID
# project_id = "YOUR_PROJECT_ID"

# Example metric type
# metric_type = "custom.googleapis.com/my_metric"

client = Google::Cloud::Monitoring.metric_service
project_name = client.project_path project: project_id

series = Google::Cloud::Monitoring::V3::TimeSeries.new
series.metric = Google::Api::Metric.new type: metric_type

resource = Google::Api::MonitoredResource.new type: "global"
resource.labels["project_id"] = project_id
series.resource = resource

point = Google::Cloud::Monitoring::V3::Point.new
point.value = Google::Cloud::Monitoring::V3::TypedValue.new double_value: 3.14
now = Time.now
end_time = Google::Protobuf::Timestamp.new seconds: now.to_i, nanos: now.nsec
point.interval = Google::Cloud::Monitoring::V3::TimeInterval.new end_time: end_time
series.points << point

client.create_time_series name: project_name, time_series: [series]
p "Time series created."

문제가 발생할 경우 API 호출 문제 해결을 참조하세요.

측정항목 설명 수정

기존 커스텀 측정항목에 라벨을 추가하려면 timeSeries.create 메서드를 사용하고 시계열 데이터에 새 라벨을 포함합니다. 작성할 라벨이 유효하고 측정항목 설명의 라벨 수가 라벨 한도인 10을 초과하지 않으면 라벨이 추가됩니다. 그러면 처음부터 측정항목에 라벨이 있었던 것처럼 시계열 데이터가 작성됩니다.

새 라벨을 추가하는 것보다 더 많은 작업을 하려면 측정항목 설명자를 삭제하고 다시 만들어야 합니다. 이 경우 오래된 측정항목 설명자에 대해 이전에 수집된 시계열 데이터가 모두 손실됩니다. 자세한 내용은 측정항목 삭제를 참조하세요.

측정항목 이름은 변경할 수 없습니다.

다음 단계

  • 기본 제공 측정항목을 탐색하려면 측정항목 목록을 참조하세요.
  • 사용 가능한 모니터링 리소스를 찾아보려면 리소스 목록을 참조하세요.