Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CES] Reimplement the MetricData v1 API. #384

Merged
merged 14 commits into from
Aug 12, 2022
96 changes: 96 additions & 0 deletions acceptance/openstack/ces/v1/metricdata_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package v1

import (
"strconv"
"testing"
"time"

"github.com/opentelekomcloud/gophertelekomcloud/acceptance/clients"
"github.com/opentelekomcloud/gophertelekomcloud/acceptance/openstack"
"github.com/opentelekomcloud/gophertelekomcloud/openstack/ces/v1/metricdata"
th "github.com/opentelekomcloud/gophertelekomcloud/testhelper"
)

func TestMetricData(t *testing.T) {
client, err := clients.NewCesV1Client()
th.AssertNoErr(t, err)

ecsClient, err := clients.NewComputeV1Client()
th.AssertNoErr(t, err)

ecs := openstack.CreateCloudServer(t, ecsClient, openstack.GetCloudServerCreateOpts(t))
t.Cleanup(func() {
openstack.DeleteCloudServer(t, ecsClient, ecs.ID)
})

old := time.Now().UnixMilli()
newOps := metricdata.MetricDataItem{
Metric: metricdata.MetricInfo{
Namespace: "MINE.APP",
MetricName: "cpu_util",
Dimensions: []metricdata.MetricsDimension{
{
Name: "instance_id",
Value: ecs.ID,
},
},
},
Ttl: 172800,
CollectTime: old,
Value: 0.09,
Unit: "%",
Type: "float",
}

err = metricdata.CreateMetricData(client, []metricdata.MetricDataItem{newOps})
th.AssertNoErr(t, err)

batchOps := metricdata.BatchListMetricDataOpts{
Metrics: []metricdata.Metric{
{
Namespace: "MINE.APP",
MetricName: "cpu_util",
Dimensions: []metricdata.MetricsDimension{
{
Name: "instance_id",
Value: ecs.ID,
},
},
},
},
From: old,
To: time.Now().UnixMilli(),
Period: "1",
Filter: "average",
}

batchData, err := metricdata.BatchListMetricData(client, batchOps)
th.AssertNoErr(t, err)
th.AssertEquals(t, len(batchData), 1)
Aloento marked this conversation as resolved.
Show resolved Hide resolved

metricOps := metricdata.ShowMetricDataOpts{
Namespace: "SYS.ECS",
MetricName: "cpu_util",
Dim0: "instance_id," + ecs.ID,
Filter: "average",
Period: 1,
From: strconv.FormatInt(old, 10),
To: strconv.FormatInt(time.Now().UnixMilli(), 10),
}

metricData, err := metricdata.ShowMetricData(client, metricOps)
th.AssertNoErr(t, err)
th.AssertEquals(t, len(metricData.Datapoints), 0)
outcatcher marked this conversation as resolved.
Show resolved Hide resolved

eventOps := metricdata.ShowEventDataOpts{
Namespace: "SYS.ECS",
Dim0: "instance_id," + ecs.ID,
Type: "instance_host_info",
From: strconv.FormatInt(old, 10),
To: strconv.FormatInt(time.Now().UnixMilli(), 10),
}

event, err := metricdata.ListEventData(client, eventOps)
th.AssertNoErr(t, err)
th.AssertEquals(t, len(event), 0)
}
110 changes: 110 additions & 0 deletions openstack/ces/v1/metricdata/batch_list_metric_data.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package metricdata

import (
golangsdk "github.com/opentelekomcloud/gophertelekomcloud"
"github.com/opentelekomcloud/gophertelekomcloud/internal/extract"
)

type BatchListMetricDataOpts struct {
// Specifies the metric data. The maximum length of the array is 10.
Metrics []Metric `json:"metrics" required:"true"`
// Specifies the start time of the query.
// The value is a UNIX timestamp and the unit is ms.
// Set the value of from to at least one period earlier than the current time.
// Rollup aggregates the raw data generated within a period to the start time of the period.
// Therefore, if values of from and to are within a period,
// the query result will be empty due to the rollup failure.
// You are advised to set from to be at least one period earlier than the current time.
// Take the 5-minute period as an example. If it is 10:35 now,
// the raw data generated between 10:30 and 10:35 will be aggregated to 10:30.
// Therefore, in this example, if the value of period is 5 minutes,
// the value of from should be 10:30 or earlier.
From int64 `json:"from" required:"true"`
// Specifies the end time of the query.
// The value is a UNIX timestamp and the unit is ms.
// The value of parameter from must be earlier than that of parameter to.
To int64 `json:"to" required:"true"`
// Specifies how often Cloud Eye aggregates data.
//
// Possible values are:
// 1: Cloud Eye performs no aggregation and displays raw data.
// 300: Cloud Eye aggregates data every 5 minutes.
// 1200: Cloud Eye aggregates data every 20 minutes.
// 3600: Cloud Eye aggregates data every 1 hour.
// 14400: Cloud Eye aggregates data every 4 hours.
// 86400: Cloud Eye aggregates data every 24 hours.
Period string `json:"period" required:"true"`
// Specifies the data rollup method. The following methods are supported:
//
// average: Cloud Eye calculates the average value of metric data within a rollup period.
// max: Cloud Eye calculates the maximum value of metric data within a rollup period.
// min: Cloud Eye calculates the minimum value of metric data within a rollup period.
// sum: Cloud Eye calculates the sum of metric data within a rollup period.
// variance: Cloud Eye calculates the variance value of metric data within a rollup period.
// The value of filter does not affect the query result of raw data. (The period is 1.)
Filter string `json:"filter" required:"true"`
}

type Metric struct {
// Specifies the metric namespace. Its value must be in the service.item format and can contain 3 to 32 characters.
// service and item each must be a string that starts with a letter and contains only letters, digits, and underscores (_).
Namespace string `json:"namespace" required:"true"`

// Specifies the metric name. Start with a letter.
// Enter 1 to 64 characters. Only letters, digits, and underscores (_) are allowed.
MetricName string `json:"metric_name" required:"true"`

// Specifies the list of the metric dimensions.
Dimensions []MetricsDimension `json:"dimensions" required:"true"`
}

func BatchListMetricData(client *golangsdk.ServiceClient, opts BatchListMetricDataOpts) ([]BatchMetricData, error) {
b, err := golangsdk.BuildRequestBody(opts, "")
if err != nil {
return nil, err
}

// POST /V1.0/{project_id}/batch-query-metric-data
raw, err := client.Post(client.ServiceURL("batch-query-metric-data"), b, nil, &golangsdk.RequestOpts{
OkCodes: []int{200},
})
if err != nil {
return nil, err
}

var res []BatchMetricData
err = extract.IntoSlicePtr(raw.Body, &res, "metrics")

return res, err
}

type BatchMetricData struct {
// Specifies the metric namespace.
// The value must be in the service.item format and can contain 3 to 32 characters.
Namespace string `json:"namespace"`
// Specifies the metric name. Start with a letter. Enter 1 to 64 characters.
MetricName string `json:"metric_name"`
// Specifies the list of metric dimensions.
Dimensions []MetricsDimension `json:"dimensions"`
// Specifies the metric data list.
// Since Cloud Eye rounds up the value of from based on the level of granularity for data query,
// datapoints may contain more data points than expected.
Datapoints []DatapointForBatchMetric `json:"datapoints"`
// Specifies the metric unit.
Unit string `json:"unit"`
}

type DatapointForBatchMetric struct {
// Specifies the maximum value of metric data within a rollup period.
Max float64 `json:"max"`
// Specifies the minimum value of metric data within a rollup period.
Min float64 `json:"min"`
// Specifies the average value of metric data within a rollup period.
Average float64 `json:"average"`
// Specifies the sum of metric data within a rollup period.
Sum float64 `json:"sum"`
// Specifies the variance of metric data within a rollup period.
Variance float64 `json:"variance"`
// Specifies when the metric is collected. It is a UNIX timestamp in milliseconds.
Timestamp int64 `json:"timestamp"`
}
62 changes: 62 additions & 0 deletions openstack/ces/v1/metricdata/create_metric_data.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package metricdata

import golangsdk "github.com/opentelekomcloud/gophertelekomcloud"

type MetricDataItem struct {
// Specifies the metric data.
Metric MetricInfo `json:"metric" required:"true"`
// Specifies the data validity period.
// The unit is second. The value range is 0–604,800 seconds.
// If the validity period expires, the data will be automatically deleted.
Ttl int `json:"ttl" required:"true"`
// Specifies when the data was collected.
// The time is UNIX timestamp (ms) format.
CollectTime int64 `json:"collect_time" required:"true"`
// Specifies the monitoring metric data to be added.
// The value can be an integer or a floating point number.
Value float64 `json:"value" required:"true"`
// Specifies the data unit.
// Enter a maximum of 32 characters.
Unit string `json:"unit,omitempty"`
// Specifies the enumerated type.
// Possible values:
// int
// float
Type string `json:"type,omitempty"`
}

type MetricInfo struct {
// Specifies the metric dimension. A maximum of three dimensions are supported.
Dimensions []MetricsDimension `json:"dimensions" required:"true"`
// Specifies the metric ID. For example, if the monitoring metric of an ECS is CPU usage, metric_name is cpu_util.
MetricName string `json:"metric_name" required:"true"`
// Query the namespace of a service.
Namespace string `json:"namespace" required:"true"`
}

type MetricsDimension struct {
// Specifies the dimension. For example, the ECS dimension is instance_id.
// For details about the dimension of each service, see the key column in Services Interconnected with Cloud Eye.
// Start with a letter. Enter 1 to 32 characters.
// Only letters, digits, underscores (_), and hyphens (-) are allowed.
Name string `json:"name,omitempty"`
// Specifies the dimension value, for example, an ECS ID.
// Start with a letter or a digit. Enter 1 to 256 characters. Only letters, digits, underscores (_), and hyphens (-) are allowed.
Value string `json:"value,omitempty"`
}

func CreateMetricData(client *golangsdk.ServiceClient, items []MetricDataItem) error {
b := make([]map[string]interface{}, len(items))

for i, opt := range items {
opt, err := golangsdk.BuildRequestBody(opt, "")
if err != nil {
return err
}
b[i] = opt
}

// POST /V1.0/{project_id}/metric-data
_, err := client.Post(client.ServiceURL("metric-data"), &b, nil, nil)
return err
}
99 changes: 99 additions & 0 deletions openstack/ces/v1/metricdata/list_metric_data.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package metricdata

import (
golangsdk "github.com/opentelekomcloud/gophertelekomcloud"
"github.com/opentelekomcloud/gophertelekomcloud/internal/extract"
)

type ShowMetricDataOpts struct {
// Specifies the namespace of a service.
Namespace string `q:"namespace"`
// Specifies the metric name.
MetricName string `q:"metric_name"`
// Currently, a maximum of three metric dimensions are supported,
// and the dimensions are numbered from 0 in the dim.{i}=key,value format.
// The key cannot exceed 32 characters and the value cannot exceed 256 characters.
// The following dimensions are only examples.
// For details about whether multiple dimensions are supported,
// see the dimension description in the monitoring indicator description of each service.
// Single dimension: dim.0=instance_id,i-12345
// Multiple dimensions: dim.0=instance_id,i-12345&dim.1=instance_name,i-1234
Dim0 string `q:"dim.0"`
Dim1 string `q:"dim.1"`
Dim2 string `q:"dim.2"`
// Specifies the data rollup method. The following methods are supported:
//
// average: Cloud Eye calculates the average value of metric data within a rollup period.
// max: Cloud Eye calculates the maximum value of metric data within a rollup period.
// min: Cloud Eye calculates the minimum value of metric data within a rollup period.
// sum: Cloud Eye calculates the sum of metric data within a rollup period.
// variance: Cloud Eye calculates the variance value of metric data within a rollup period.
Filter string `q:"filter"`
// Specifies how often Cloud Eye aggregates data.
//
// Possible values are:
// 1: Cloud Eye performs no aggregation and displays raw data.
// 300: Cloud Eye aggregates data every 5 minutes.
// 1200: Cloud Eye aggregates data every 20 minutes.
// 3600: Cloud Eye aggregates data every 1 hour.
// 14400: Cloud Eye aggregates data every 4 hours.
// 86400: Cloud Eye aggregates data every 24 hours.
Period int `q:"period"`
// Specifies the start time of the query.
// The value is a UNIX timestamp and the unit is ms.
// Set the value of from to at least one period earlier than the current time.
// Rollup aggregates the raw data generated within a period to the start time of the period.
// Therefore, if values of from and to are within a period,
// the query result will be empty due to the rollup failure.
// Take the 5-minute period as an example. If it is 10:35 now,
// the raw data generated between 10:30 and 10:35 will be aggregated to 10:30.
// Therefore, in this example, if the value of period is 5 minutes,
// the value of from should be 10:30 or earlier.
From string `q:"from"`
// Specifies the end time of the query.
To string `q:"to"`
}

func ShowMetricData(client *golangsdk.ServiceClient, opts ShowMetricDataOpts) (*MetricData, error) {
q, err := golangsdk.BuildQueryString(&opts)
if err != nil {
return nil, err
}

// GET /V1.0/{project_id}/metric-data
raw, err := client.Get(client.ServiceURL("metric-data")+q.String(), nil, nil)
if err != nil {
return nil, err
}

var res MetricData
err = extract.Into(raw.Body, &res)

return &res, err
}

type MetricData struct {
// Specifies the metric data list. For details, see Table 4.
// Since Cloud Eye rounds up the value of from based on the level of granularity for data query,
// datapoints may contain more data points than expected.
Datapoints []Datapoint `json:"datapoints"`
// Specifies the metric ID. For example, if the monitoring metric of an ECS is CPU usage, metric_name is cpu_util.
MetricName string `json:"metric_name"`
}

type Datapoint struct {
// Specifies the maximum value of metric data within a rollup period.
Max float64 `json:"max,omitempty"`
// Specifies the minimum value of metric data within a rollup period.
Min float64 `json:"min,omitempty"`
// Specifies the average value of metric data within a rollup period.
Average float64 `json:"average,omitempty"`
// Specifies the sum of metric data within a rollup period.
Sum float64 `json:"sum,omitempty"`
// Specifies the variance of metric data within a rollup period.
Variance float64 `json:"variance,omitempty"`
// Specifies when the metric is collected. It is a UNIX timestamp in milliseconds.
Timestamp int64 `json:"timestamp"`
// Specifies the metric unit.
Unit string `json:"unit,omitempty"`
}
Loading