Criar métricas personalizadas

Para definir uma métrica personalizada, use o método de API metricDescriptors.create para criar um descritor de métrica personalizado. É possível simplesmente gravar dados de série temporal da métrica e deixar o Monitoring criar automaticamente o descritor. No entanto, é necessário saber quais informações usar em uma definição de métrica. Depois de criar um novo descritor, use a métrica com os métodos de API do descritor e os métodos de API da série temporal. Também é possível utilizar a métrica para gráficos e alertas no Monitoring.

Nomes de métricas personalizadas

Quando criar uma métrica personalizada, atribua um nome de tipo exclusivo entre as métricas personalizadas no projeto do GCP. O nome do tipo precisa começar com custom.googleapis.com/, seguido por um nome simples ou um nome de caminho. Com os nomes de caminho, você organiza as métricas personalizadas. No entanto, eles são tratados da mesma maneira que os nomes simples. Consulte Regras de nomenclatura para ver mais detalhes. Veja exemplos de dois nomes de tipos:

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

As métricas personalizadas também têm nomes de recursos, que são exclusivos entre todos os recursos do GCP em todos os projetos. O formato do nome de recurso de uma métrica é:

projects/[PROJECT_ID]/metricDescriptors/[METRIC_TYPE]

Se os exemplos de métrica personalizada anteriores tivessem sido criados no projeto my-project-id, os respectivos nomes de recursos seriam:

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

Nome ou tipo? Na Monitoring API, os campos de nome de tipo de métrica têm geralmente os marcadores type. Já os campos de nome de recurso têm name. No entanto, em conversas e em algumas documentações, o nome do tipo é muitas vezes chamado de "nome da métrica".

Como definir a métrica personalizada

Para criar a métrica personalizada, forneça um objeto MetricDescriptor que especifique várias informações sobre ela. Veja a seguir as informações necessárias:

  • Escolha um nome de tipo para a métrica personalizada, conforme descrito na seção anterior.

  • Escolha um projeto em que a métrica personalizada será definida e grave os dados de série temporal dela. As métricas personalizadas da AWS precisam ser criadas no projeto do conector da AWS referente à conta dessa plataforma. O projeto escolhido também precisa ser membro do espaço de trabalho em que a métrica é monitorada. Se você precisa de métricas iguais em vários projetos, faça as mesmas definições para elas em cada projeto.

  • Escolha um nome de exibição e uma descrição da métrica. O nome de exibição é usado na interface de usuário do Monitoring.

  • Escolha o tipo de métrica e de valor e, opcionalmente, as unidades. Nem todos os tipos de valores e classes de métrica são compatíveis com as métricas personalizadas. Consulte Tipos de métricas.

  • Escolha os rótulos da métrica: nomes, tipos de valor e descrições.

  • Escolha os objetos de recursos monitorados que serão incluídos nos pontos de dados da série temporal da métrica. Pense sobre isso antes de criar o descritor de métrica. O tipo de recurso monitorado que você usa afeta quais rótulos de métrica você precisa. Por exemplo, se um objeto de instância de VM for incluído nos dados, não será necessário um rótulo de métrica para especificar a instância. Para ver mais informações, consulte Como escolher um tipo de recurso monitorado.

Navegar pelas métricas integradas e analisar os dados da série temporal delas ajudará você a fazer essas escolhas.

Como escolher um tipo de recurso monitorado

Cada um dos pontos de dados da métrica precisa incluir um objeto de recurso monitorado. Os pontos de diferentes objetos de recursos monitorados são mantidos em séries temporais distintas.

Você pode usar apenas os seguintes tipos de recursos monitorados nas métricas personalizadas:

É uma prática comum usar os objetos de recursos monitorados que representam os recursos físicos em que o código do aplicativo está sendo executado. Isso tem muitas vantagens:

  • Você consegue melhor desempenho em comparação com o uso de um único tipo de recurso.
  • Você evita dados fora de ordem causados pela gravação de vários processos na mesma série temporal.
  • É possível agrupar os dados da métrica personalizada e de outras dos mesmos recursos.

Recursos global em comparação a genéricos

Os tipos de recursos generic_task e generic_node são úteis em situações em que não seja adequado o uso de nenhum dos recursos mais específicos. O tipo generic_task é útil para definir recursos semelhantes a tarefas, como aplicativos. O tipo generic_node é útil para definir recursos semelhantes a nós, como máquinas virtuais. Os dois tipos generic_* têm vários rótulos comuns que podem ser usados para definir objetos de recursos exclusivos, facilitando o uso em filtros de métrica para agregações e reduções.

Por outro lado, o tipo de recurso global tem apenas os rótulos project_id e location. Se um projeto tiver muitas fontes de métricas, o uso do mesmo objeto de recurso global poderá causar colisões e sobregravações dos dados das métricas.

Chamar o método create

Depois de fazer as escolhas, transmita um objeto MetricDescriptor para chamar o método metricDescriptors.create. Como alternativa, consulte Criação automática de descritores de métrica. A alteração de um descritor atual é limitada. Consulte Como modificar descritores de métrica para ver mais informações.

Geralmente, é um erro chamar metricDescriptors.create usando o mesmo nome de tipo de um descritor de métrica personalizada atual. No entanto, se todos os campos do novo objeto MetricDescriptor corresponderem aos do descritor atual, isso não será um erro, mas não terá efeito.

Como criar descritores de métrica

No exemplo a seguir, você cria uma métrica personalizada de medidor: custom.googleapis.com/stores/daily_sales. A métrica tem um marcador de dimensão única: store_id.

Protocolo

Para criar um descritor de métrica, use o método metricDescriptors.create. É possível executá-lo por meio do widget da API Explorer na página de referência do método. Consulte a API Explorer para ver mais informações.

Veja a seguir amostras de parâmetros de metricDescriptors.create:

  • nome (URL): projects/[PROJECT_ID]
  • Corpo da solicitação: forneça um objeto MetricDescriptor como o seguinte:

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

Forneça estes valores nos campos do widget usando o código do projeto no lugar de [PROJECT_ID]:

Como criar um descritor de métrica

Clique em Executar para executar o método.

Faça o teste!

Quando uma nova métrica personalizada é criada, o campo name no MetricDescriptor é ignorado e pode ser omitido. O método create retorna o novo descritor de métrica com o campo name preenchido. Neste exemplo, ele é:

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

Use esse nome se quiser receber o descritor de uma métrica, por exemplo.

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

Consulte Como solucionar problemas de chamadas da API se tiver dificuldade.

Próxima etapa: veja Como gravar dados de métrica.

Como excluir métricas

Para excluir uma métrica personalizada, chame o método metricDescriptors.delete.

Protocolo

Para excluir um descritor de métrica, use o método metricDescriptors.delete. É possível executá-lo por meio do widget da API Explorer na página de referência do método. Consulte a API Explorer para ver mais informações.

É possível excluir somente os tipos de métricas personalizadas.

Para excluir a métrica personalizada stores/daily_sales criada em Como criar descritores de métrica:

  1. Acesse a página de referência de metricDescriptors.delete:
  2. Forneça o nome do descritor de métrica ao widget da API Explorer:

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

  3. Clique em Executar.

Faça o teste!

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

Consulte Como solucionar problemas de chamadas da API se tiver dificuldade.

Não é possível excluir os dados de série temporal da métrica personalizada. No entanto, eles expiram e são excluídos de acordo com a política de retenção de dados.

Como gravar dados de métricas

É possível gravar dados apenas para tipos de métricas personalizadas. Use o método timeSeries.create para gravar os pontos de dados. O método anexa um novo ponto de dados a uma série temporal existente, criando-a se necessário.

Para gravar pontos de dados, transmita uma lista de objetos TimeSeries para timeSeries.create. O tamanho máximo da lista é de 200, e cada objeto nela precisa especificar uma série temporal diferente:

  • Cada série temporal é identificada pelos campos de metric e resource do objeto TimeSeries.
  • Omita os campos metricKind e valueType. Eles são ignorados ao gravar pontos de dados.
  • Cada objeto TimeSeries precisa conter apenas um único objeto Point:

    • O valor do ponto e o intervalo de tempo precisam ser consistentes com a definição do tipo de métrica. Para saber mais sobre intervalos de tempo de tipos diferentes de métricas, consulte Tipos de métricas.
    • O intervalo de tempo do ponto precisa ser posterior a qualquer ponto atual na série temporal.
    • O tempo de término do intervalo não pode ser superior a 24 horas no passado nem maior que cinco minutos no futuro.
  • Se você quiser gravar mais de um ponto na mesma série temporal, use uma chamada separada para o método timeSeries.create de cada ponto. Não faça as chamadas mais rápido do que uma vez por minuto. Se você estiver adicionando pontos de dados a séries temporais diferentes, não haverá limitação de taxa.

Protocolo

Para gravar dados de métrica, use o método timeSeries.create. É possível executá-lo por meio do widget da API Explorer na página de referência do método. Consulte a API Explorer para ver mais informações.

Para gravar um ponto na métrica personalizada stores/daily_sales criada em Como criar descritores de métrica, siga as seguintes instruções:

  1. Acesse a página de referência de timeSeries.create.
  2. Forneça os parâmetros abaixo ao widget da API Explorer.
  3. Clique em Executar.

Use os seguintes parâmetros de amostra:

  • nome: projects/[PROJECT_ID]
  • corpo da solicitação: inclua uma lista de objetos TimeSeries. A amostra a seguir tem apenas uma série temporal na lista.

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

Faça o teste!

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

Consulte Como solucionar problemas de chamadas da API se tiver dificuldade.

Criação automática de descritores de métrica

Se você gravar dados de métrica em um tipo de métrica personalizada que ainda não existe, um novo tipo de descritor de métrica personalizada será criado automaticamente para você. No entanto, talvez ele não seja exatamente o que você quer. A criação automática de descritores de métrica inclui algumas suposições e padrões.

Especificamente, durante uma chamada para timeSeries.create, se um objeto TimeSeries incluir um objeto Metric que determine um nome do tipo de métrica inexistente, o Stackdriver Monitoring criará um novo MetricDescriptor com os seguintes campos:

  • type: o tipo é copiado do campo type do objeto Metric.
  • name: o nome é criado a partir do código do projeto na chamada do método e do valor de type no objeto Metric;
  • labels: os rótulos são os que aparecem no objeto Metric. Cada descritor de rótulo no novo descritor de métrica tem os seguintes campos:
    • key: a chave do rótulo no objeto Metric
    • valueType: STRING
    • description: não definido
  • metricKind: o tipo de métrica padrão é GAUGE. No entanto, se o parâmetro metricKind do objeto TimeSeries for especificado, a nova métrica terá esse tipo. É possível especificar somente os tipos GAUGE e CUMULATIVE;
  • valueType: o tipo de valor é extraído do valor inserido de Point que está sendo gravado e precisa ser BOOL, INT64, DOUBLE ou DISTRIBUTION. Se você especificar um tipo de valor no campo valueType do TimeSeries, ele precisará corresponder ao tipo em Point.
  • unit: não definido;
  • description: "Auto created custom metric.".
  • displayName: não definido.

Em uma única chamada de timeSeries.create, é possível incluir vários objetos TimeSeries que se refiram ao mesmo tipo de métrica personalizada inexistente. Nesse caso, os campos do novo tipo são definidos da mesma maneira. No entanto, os rótulos no novo descritor de métrica consistem na união de todos os rótulos nos objetos Metric de todas as séries temporais dessa chamada para create.

Como modificar descritores de métrica

Também é possível usar a chamada de timeSeries.create para adicionar novos rótulos a métricas personalizadas. Para adicioná-los ao descritor de métrica personalizada, inclua os rótulos com os dados da série temporal.

O rótulo é adicionado se ele for válido e não ultrapassar o limite máximo de 10 rótulos no descritor de métrica. Depois, os dados da série temporal são gravados como se o rótulo estivesse lá desde o início.

Se você quer fazer mais do que adicionar novos rótulos, exclua e recrie o descritor de métrica. Nesse caso, você perde todos os dados da série temporal coletados anteriormente para o descritor de métrica antigo. Consulte Como excluir métricas para ver mais informações.

Não é possível renomear uma métrica.

Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…

Stackdriver Monitoring
Precisa de ajuda? Acesse nossa página de suporte.