Creating custom metrics

Custom metrics are metrics defined by users. Custom metrics use the same elements that the built-in Stackdriver Monitoring metrics use:

  • A set of data points.
  • Metric-type information, which tells you what the data points represent.
  • Monitored-resource information, which tells you where the data points originated.

For an introduction to the structures that underlie both the built-in and custom metrics, see Metrics, time series, and resources. To browse the built-in metrics, see Metrics list. To browse the available monitored resources, see Resource list.

To use a custom metric, you must have a metric descriptor for your new metric type. Stackdriver Monitoring can create the metric descriptor for you automatically, or you can use the metricDescriptors.create API method to create it yourself.

To have Stackdriver Monitoring create the metric descriptor for you, you simply write time series data for your metric, and Stackdriver Monitoring creates a descriptor based on the data you are writing. There are limits to auto-creation, so it's helpful to know what information goes into a metric definition.

After you have a new custom metric descriptor, whether you or Monitoring created it, you can use the metric descriptor with the metric descriptor API methods and the time series API methods.

You can also create charts and alerts for your custom metric data.

Custom metric names

When you create a custom metric, you create a string identifier that represents the metric type. This string must be unique among the custom metrics in your GCP project. The string must begin with a prefix that marks it as a user-defined metric. For Monitoring, the most common prefix is custom.googleapis.com/, though external.googleapis.com/ is also used. This is followed by either a simple name or a path name that generally describes what you are collecting. Path names can help you organize your custom metrics, but they are handled just like simple names. See Naming rules for more details. Here are examples of the two kinds of identifiers for metric types:

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

Your custom metrics also have resource names that are unique among all GCP resources in all projects. The format of a resource name for a metric is:

projects/[PROJECT_ID]/metricDescriptors/[METRIC_TYPE]

If the previous custom metric examples were created in project my-project-id, then their resource names would be the following:

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

Name or type? In the Monitoring API, metric type name fields are usually labeled type and resource name fields are usually labeled name. However, in conversation and some documentation, the type name is often called the "metric name."

Defining your custom metric descriptor

To collect custom metric data, you must provide a MetricDescriptor object that specifies various information about the metric. Stackdriver Monitoring can create this for you automatically; see Auto-creation of metric descriptors for more information.

If you want to create the metric descriptor explicitly, here is the information you'll need:

  • Choose an identifier for the custom metric type, as described in the previous section.

  • Choose a project in which to define your custom metric and write its time series data.

    The project you choose must also be a member of the Workspace where you monitor the metric. If you need the same metric in several projects, then make identical definitions of the metric in each project.

    Custom metrics for AWS should be created in the AWS connector project for your AWS account.

  • Choose a display name and description of the metric. The display name is used in the Monitoring console.

  • Choose the metric's kind, value type, and (optionally) units. Not all value types and metric kinds are supported for custom metrics. See Kinds of metrics.

  • Choose the metric's labels—their names, value types, and descriptions.

For more help in making these choices, you can browse the built-in metrics and look at their time series data.

Creating metric descriptors manually includes code samples for manually creating a metric descriptor.

Choosing a monitored-resource type

When you write your data to a time series, you must indicate where the data came from. To do this, you choose a monitored-resource type that represents where your data comes from, and then use that to describe the specific origin. The monitored resource is not part of the metric type; instead, the time series to which you write data includes a reference to the metric type, which describes the data, and a reference to the monitored resource, which indicates where the data originated.

Consider the monitored resource before creating your metric descriptor. The monitored-resource type you use affects which labels you need to include in the metric descriptor. For example, if you use a VM instance monitored resource with your data, then you won't need a metric label to specify the instance. For more information, see Choosing a monitored-resource type.

Each of your metric's data points must be associated with a monitored resource object. Points from different monitored resource objects are held in different time series.

Monitored resources for custom metrics

You can use only the following monitored-resource types in your custom metrics.

A common practice is to use the monitored resource objects that represent the physical resources where your application code is running. This has several advantages:

  • You get better performance compared with using a single resource type.
  • You avoid out-of-order data caused by multiple processes writing to the same time series.
  • Your custom metric data can be grouped with other metric data from the same resources.

global versus generic resources

The generic_task and generic_node resource types are useful in situations where none of the more specific resource types are appropriate. The generic_task type is useful for defining task-like resources such as applications. The generic_node type is useful for defining node-like resources such as virtual machines. Both generic_* types have several common labels you can use to define unique resource objects, making it easy to use them in metric filters for aggregations and reductions.

In contrast, the global resource type has only project_id and location labels. If you have many sources of metrics within a project, using the same global resource object can cause collisions and over-writes of your metric data.

Creating metric descriptors

The data you collect for a custom metric must be associated with a descriptor for a custom metric type. You can create the metric descriptor yourself, or Monitoring can create it for you.

You can change an existing descriptor in limited ways; see Modifying metric descriptors for more information.

Auto-creation of metric descriptors

If you write metric data to a custom metric type that does not yet exist, then a new custom metric descriptor is created for you automatically. However, this new metric descriptor might not be exactly what you want; auto-creation of metric descriptors involves some assumptions and defaults.

Specifically, during a call to timeSeries.create, if a TimeSeries object includes a Metric object that specifies a nonexistent metric-type name, then Stackdriver Monitoring creates a new MetricDescriptor with the following fields:

  • type: The type is copied from the Metric object's type field.
  • name: The name is created from the project ID in the method call and the value of the type in the Metric object.
  • labels: The labels are those that appear in the Metric object. Each label descriptor in the new metric descriptor has the following fields:
    • key: the label key in the Metric object.
    • valueType: STRING
    • description: not set
  • metricKind: The default metric kind is GAUGE, but if you specify the metricKind parameter of the TimeSeries object, then the new metric has that kind. You can specify only GAUGE and CUMULATIVE kinds.
  • valueType: The value type is taken from the typed value of the Point being written. which must be BOOL, INT64, DOUBLE, or DISTRIBUTION. If you specify a value type in the valueType field of the TimeSeries, then that type must match the type of the Point.
  • unit: not set
  • description: "Auto created custom metric.".
  • displayName: not set

In a single timeSeries.create call, you can include multiple TimeSeries objects that refer to the same nonexistent custom metric type. In that case, the new type's fields are set in the same way, except that the labels in the new metric descriptor consist of the union of all the labels in the Metric objects in all the time series in this call to create.

Next step: See Writing metric data.

Creating metric descriptors manually

After you have collected the information you need for creating your custom metric type, call the metricDescriptors.create method, passing in a MetricDescriptor object. See Modifying metric descriptors for more information.

It is usually an error to call metricDescriptors.create using the same type name as an existing custom metric descriptor. However, if all the fields of the new MetricDescriptor object match the fields of the existing descriptor exactly, then it is not an error but it has no effect.

In the following example, you create a gauge custom metric, custom.googleapis.com/stores/daily_sales. The metric has a single dimension label, store_id.

Protocol

To create a metric descriptor, use the metricDescriptors.create method. You can execute this method by using the API Explorer widget on the method's reference page. See API Explorer for more information.

The following are the sample parameters to metricDescriptors.create:

  • name (URL): projects/[PROJECT_ID]
  • Request body: supply a MetricDescriptor object such as the following:

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

Supply these values to the fields in the widget, using your project's ID in place of [PROJECT_ID]:

Creating a metric descriptor

Click the Execute button to run the method.

Try It!

When creating a new custom metric, note that the name field in the MetricDescriptor is ignored and can be omitted. The create method returns the new metric descriptor with the name field filled in, which in this example would be the following:

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

You use this name, for example, if you want to get a metric's descriptor.

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)
    .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 = 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

See Troubleshooting API calls if you have difficulty.

Next step: See Writing metric data.

Deleting metrics

To delete a custom metric, delete its metric descriptor. You cannot delete the time series data from your custom metric, but deleting the metric descriptor renders the data inaccessible. The data expires and is deleted according to the data retention policy.

To delete your custom metric descriptor, call the metricDescriptors.delete method.

Protocol

To delete a metric descriptor, use the metricDescriptors.delete method. You can execute this method by using the API Explorer widget on the method's reference page. See API Explorer for more information.

You can only delete custom metric types.

To delete the stores/daily_sales custom metric created in Creating metric descriptors manually:

  1. Go to the reference page for metricDescriptors.delete:
  2. Supply the name of the metric descriptor to the API Explorer widget:

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

  3. Click the Execute button.

Try It!

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}."

See Troubleshooting API calls if you have difficulty.

Writing metric data

You can write data only to custom metric types. To write your data, use the timeSeries.create method. If the time series already exists, this method appends a new data point to the existing time series. If the time series does not exist, this method creates it and appends the data.

You write data points by passing a list of TimeSeries objects to timeSeries.create. The maximum list size is 200 and each object in the list must specify a different time series:

  • Each time series is identified by the metric and resource fields of the TimeSeries object. These fields represent the metric type of the data and the monitored resource from which the the data was collected.
  • Omit the fields metricKind and valueType; they are ignored when writing data points.
  • Each TimeSeries object must contain only a single Point object:

    • The point's value and time interval must be consistent with the metric type's definition. For information on time intervals for different metric kinds, see Metric kinds.
    • The point's time interval must be later than any point already in the time series.
    • The end time of the interval must not be more than 24 hours in the past or more than five minutes in the future.
  • If you want to write more than one point to the same time series, then use a separate call to the timeSeries.create method for each point. Don't make the calls faster than one time per minute. If you are adding data points to different time series, then there is no rate limitation.

Protocol

To write metric data, use the timeSeries.create method. You can execute this method by using the API Explorer widget on the method's reference page. See API Explorer for more information.

To write a point to the stores/daily_sales custom metric created in the Creating metric descriptors manually:

  1. Go to the reference page for timeSeries.create.
  2. Supply the parameters below to the API Explorer widget.
  3. Click the Execute button.

Use the following sample parameters:

  • name: projects/[PROJECT_ID]
  • request body: include a list of TimeSeries objects. The following sample has only one time series in the list.

    {
     "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
         }
        }
       ]
      }
     ]
    }
    

Try It!

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);

    $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}"

See Troubleshooting API calls if you have difficulty.

Modifying metric descriptors

You can also use the timeSeries.create call to add new labels to custom metrics. You can add labels to your custom metric descriptor by including them with the time series data.

If the label you attempt to write is valid and does not cause the number of labels in the metric descriptor to exceed the label limit of 10, the label is added. The time series data is then written as though the label had been there from the beginning.

If you want to do more than add new labels, you must delete and recreate the metric descriptor. In this case, you lose all the time series data previously collected for the old metric descriptor. See Deleting metrics for more information.

You cannot rename a metric.

Hai trovato utile questa pagina? Facci sapere cosa ne pensi:

Invia feedback per...

Stackdriver Monitoring
Hai bisogno di assistenza? Visita la nostra pagina di assistenza.