创建自定义指标

要定义自定义指标,请使用 metricDescriptors.create API 方法创建自定义指标描述符。虽然您可以只为指标编写时间序列数据,让 Monitoring 自动创建指标描述符,但您应该了解指标定义包含哪些信息。创建新的自定义指标描述符后,您可以将指标用于指标描述符 API 方法时间序列 API 方法。您还可以使用指标在 Monitoring 中绘制图表和创建提醒。

自定义指标名称

创建自定义指标时,您需要为其分配自定义指标类型名称,该名称在 GCP 项目的自定义指标中是唯一的。该类型名称必须以 custom.googleapis.com/ 开头,后跟简单的名称或路径名称。路径名称可以帮助您整理自定义指标,但其处理方式与简单的名称没有差别。如需了解详情,请参阅命名规则。以下是两种类型名称的示例:

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

您的自定义指标还具备资源名称,这些资源名称在所有项目的所有 GCP 资源中都是唯一的。指标资源名称的格式为:

projects/[PROJECT_ID]/metricDescriptors/[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

名称还是类型? 在 Monitoring API 中,指标类型名称字段通常带有 type(类型)标签,资源名称字段通常带有 name(名称)标签。但是,在会话和一些文档中,类型名称通常被称为“指标名称”。

定义您的自定义指标

要创建您的自定义指标,您必须提供 MetricDescriptor 对象,以指定与指标相关的各种信息。需要的信息如下:

  • 为自定义指标选择类型名称(如上一部分所述)。

  • 选择一个项目,在其中定义您的自定义指标并编写其时间序列数据。AWS 的自定义指标应该在您 AWS 帐号的 AWS 连接器项目中创建。此外,您选择的项目还必须包含在您用于监控指标的工作区中。如果您需要在多个项目中使用相同的指标,请在每个项目中为指标提供相同的定义。

  • 选择指标的显示名和说明。显示名会在 Monitoring 的界面中使用。

  • 选择指标的种类、值类型和(可选)单位。并非所有值类型和指标种类都支持自定义指标。请参阅指标种类

  • 选择指标的标签 - 其名称、值类型和说明。

  • 选择您要将哪些受监控的资源对象添加到指标的时间序列数据点。您应该先考虑这一点,然后再创建指标描述符。您使用的受监控的资源类型会影响您需要的指标标签。例如,如果您将一个虚拟机实例对象添加到您的数据中,那么您不需要使用指标标签来指定该实例。如需了解详情,请参阅选择受监控的资源类型

如需有关如何进行上述选择的更多帮助,您可以浏览内置指标以及查看时间序列数据

选择受监控的资源类型

指标的每个数据点都必须包含一个受监控的资源对象。不同受监控资源对象的数据点保存在不同的时间序列中。

您只能在自定义指标中使用以下受监控的资源类型。

常见做法是使用表示运行应用代码的物理资源的受监控资源对象。这样做有多个好处:

  • 与使用单一资源类型相比,您可以体验更好的性能。
  • 避免因多个进程向同一时间序列写入数据导致的数据无序。
  • 您的自定义指标数据可与来自同一资源的其他指标数据分为一组。

global 资源与通用资源

在某些情况下,如果没有更具体的资源类型适合使用,则 generic_taskgeneric_node 资源类型十分实用。generic_task 类型适用于定义类似任务的资源(如应用)。generic_node 类型适用于定义类似节点的资源(如虚拟机)。这两种 generic_* 类型都有多个可用于定义唯一资源对象的通用标签,让您可以轻松地在指标过滤器中使用这些标签进行聚合和缩减。

相比之下,global 资源类型只有 project_idlocation 标签。如果一个项目中有多个指标来源,则使用相同的 global 资源对象可能会导致您的指标数据发生冲突和被覆盖。

调用 create 方法

选好资源类型后,调用 metricDescriptors.create 方法,并传入 MetricDescriptor 对象。或者,您也可以参阅自动创建指标描述符。您只能通过几种有限方法更改现有描述符。如需详细了解,请参阅修改指标描述符

使用与现有自定义指标描述符相同的类型名称调用 metricDescriptors.create 通常会导致错误。不过,如果新 MetricDescriptor 对象的所有字段与现有描述符的字段完全匹配,则该调用不会导致错误,但也不会有任何效果。

创建指标描述符

在以下示例中,您将创建一个 gauge 自定义指标 custom.googleapis.com/stores/daily_sales。该指标具有单个维度标签 store_id

协议

要创建指标描述符,请使用 metricDescriptors.create 方法。您可以使用方法参考页面上的 API Explorer 微件来执行此方法。如需详细了解,请参阅 API Explorer

以下是 metricDescriptors.create 的示例参数:

  • name(网址):projects/[PROJECT_ID]
  • Request body:提供一个 MetricDescriptor 对象,如下所示:

    {
      "name": "",
      "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."
        },
      ],
    }
    

将这些值提供给微件中的字段,使用您的项目 ID 代替 [PROJECT_ID]:

创建指标描述符

点击执行按钮以运行该方法。

试试看!

创建新的自定义指标时,注意 MetricDescriptor 中的 name 字段将被忽略,可以省略。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
}

Java

// 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)
    .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 = client.project_path(project_id)
descriptor = monitoring_v3.types.MetricDescriptor()
descriptor.type = 'custom.googleapis.com/my_metric' + RANDOM_SUFFIX
descriptor.metric_kind = (
    monitoring_v3.enums.MetricDescriptor.MetricKind.GAUGE)
descriptor.value_type = (
    monitoring_v3.enums.MetricDescriptor.ValueType.DOUBLE)
descriptor.description = 'This is a simple example of a custom metric.'
descriptor = client.create_metric_descriptor(project_name, descriptor)
print('Created {}.'.format(descriptor.name))

Ruby

client = Google::Cloud::Monitoring::Metric.new
project_name = Google::Cloud::Monitoring::V3::MetricServiceClient.project_path project_id

descriptor = Google::Api::MetricDescriptor.new(
  type:        "custom.googleapis.com/my_metric#{random_suffix}",
  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 project_name, descriptor
p "Created #{result.name}"
p result

如果遇到困难,请参阅 API 调用问题排查

下一步:请参阅写入指标数据

删除指标

要删除自定义指标,请调用 metricDescriptors.delete 方法。

协议

要删除指标描述符,请使用 metricDescriptors.delete 方法。您可以使用方法参考页面上的 API Explorer 微件来执行此方法。如需详细了解,请参阅 API Explorer

您只能删除自定义指标类型。

要删除在创建指标描述符中创建的 stores/daily_sales 自定义指标,请执行以下操作:

  1. 转到 metricDescriptors.delete 的参考页面
  2. 将指标描述符的名称提供给 API Explorer 微件。

    nameprojects/[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
}

Java

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.metricDescriptorPath(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(descriptor_name)
print('Deleted metric descriptor {}.'.format(descriptor_name))

Ruby

client = Google::Cloud::Monitoring::Metric.new
client.delete_metric_descriptor descriptor_name
p "Deleted metric descriptor #{descriptor_name}."

如果遇到困难,请参阅 API 调用问题排查

您无法删除自定义指标中的时间序列数据,但数据会到期,届时系统将依据数据保留政策将其删除。

写入指标数据

您只能将数据写入自定义指标类型。使用 timeSeries.create 方法写入数据点。该方法会将新的数据点附加到现有时间序列,并在需要时创建时间序列。

您可以通过将 TimeSeries 对象列表传递到 timeSeries.create 来写入数据点。列表大小上限为 200,列表中的每个对象都必须指定不同的时间序列:

  • 每个时间序列由 TimeSeries 对象的 metricresource 字段标识。
  • 省略字段 metricKindvalueType;写入数据点时,系统会忽略这两个字段。
  • 每个 TimeSeries 对象只能包含一个 Point 对象:

    • 该点的值和时段必须与指标类型的定义一致。如需了解不同指标种类的时段,请参阅指标种类
    • 该点的时段必须晚于时间序列中已有的点。
    • 时段的结束时间不得早于 24 小时之前,也不得晚于 5 分钟后。
  • 如果您想要将多个点写入相同的时间序列,请为每个点单独调用 timeSeries.create 方法。添加速度不要超过每分钟一个。如果您要将数据点添加到不同的时间序列,则没有速率限制。

协议

要写入指标数据,请使用 timeSeries.create 方法。您可以使用方法参考页面上的 API Explorer 微件来执行此方法。如需详细了解,请参阅 API Explorer

要将数据点写入在创建指标描述符中创建的 stores/daily_sales 自定义指标,请执行以下操作:

  1. 转到 timeSeries.create 参考页面
  2. 将以下参数提供给 API Explorer 微件。
  3. 点击执行按钮。

使用以下示例参数:

  • nameprojects/[PROJECT_ID]
  • request body:包含 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
}

Java

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);
    $filter = 'metric.type="compute.googleapis.com/instance/cpu/utilization"';

    $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 = client.project_path(project_id)

series = monitoring_v3.types.TimeSeries()
series.metric.type = 'custom.googleapis.com/my_metric' + RANDOM_SUFFIX
series.resource.type = 'gce_instance'
series.resource.labels['instance_id'] = '1234567890123456789'
series.resource.labels['zone'] = 'us-central1-f'
point = series.points.add()
point.value.double_value = 3.14
now = time.time()
point.interval.end_time.seconds = int(now)
point.interval.end_time.nanos = int(
    (now - point.interval.end_time.seconds) * 10**9)
client.create_time_series(project_name, [series])

Ruby

client = Google::Cloud::Monitoring::Metric.new
project_name = Google::Cloud::Monitoring::V3::MetricServiceClient.project_path project_id

# Random suffix for metric type to avoid collisions with other runs
random_suffix = rand(36**10).to_s(36)

series = Google::Monitoring::V3::TimeSeries.new
metric = Google::Api::Metric.new type: "custom.googleapis.com/my_metric#{random_suffix}"
series.metric = metric

resource = Google::Api::MonitoredResource.new type: "gce_instance"
resource.labels["instance_id"] = "1234567890123456789"
resource.labels["zone"] = "us-central1-f"
series.resource = resource

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

client.create_time_series project_name, [series]
p "Time series created : #{metric.type}"

如果遇到困难,请参阅 API 调用问题排查

自动创建指标描述符

如果您将指标数据写入尚不存在的自定义指标类型,则系统将自动为您创建新的自定义指标类型。但是,这个新的指标描述符可能不是您想要的;系统在自动创建指标描述符时会做出一些假设,并使用默认值。

具体而言,在调用 timeSeries.create 时,如果 TimeSeries 对象包含指定了不存在的指标类型名称Metric 对象,则 Stackdriver Monitoring 会创建一个具备以下字段的新 MetricDescriptor

  • type:类型是从 Metric 对象的 type 字段复制的。
  • name:名称是依据方法调用中的项目 ID 和 Metric 对象中的 type 值创建的。
  • labelsMetric 对象中的标签。新指标描述符中的每个标签描述符都具备以下字段:
    • keyMetric 对象中的标签键。
    • valueTypeSTRING
    • description:未设置
  • metricKind:默认的指标种类是 GAUGE,但如果您指定 TimeSeries 对象的 metricKind 参数,则新指标将具备该参数指定的种类。您只能指定 GAUGECUMULATIVE 种类。
  • valueType:值类型取自写入的 Point 的值类型,必须为 BOOLINT64DOUBLEDISTRIBUTION。如果您在 TimeSeriesvalueType 字段中指定值类型,则该类型必须与 Point 的类型相匹配。
  • unit:未设置
  • description"Auto created custom metric."
  • displayName:未设置

单次 timeSeries.create 调用可以包含多个引用同一个不存在的自定义指标类型的 TimeSeries 对象。在这种情况下,系统会以相同的方式设置新类型的字段,只是新的指标描述符中的标签包含对 create 的本次调用中所有时间序列中的 Metric 指标的标签的集合。

修改指标描述符

您还可以使用 timeSeries.create 调用向自定义指标添加新标签。您可以通过将标签包含在时间序列数据中来为自定义指标描述符添加标签。

如果您尝试编写的标签有效,并且不会导致指标描述符中的标签数超过标签限制(10 个),系统即会添加标签。然后写入时间序列数据,就好像标签从一开始就存在一样。

如果您要执行添加新标签以外的操作,必须删除并重新创建指标描述符。在这种情况下,您将丢失先前为旧指标描述符收集的所有时间序列数据。如需详细了解,请参阅删除指标

您无法重命名指标。

此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

此网页
Stackdriver Monitoring
需要帮助?请访问我们的支持页面