github.com/newrelic/newrelic-client-go@v1.1.0/pkg/apm/applications_metrics.go (about)

     1  package apm
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"strconv"
     7  	"time"
     8  )
     9  
    10  // MetricNamesParams are the request parameters for the /metrics.json endpoint.
    11  type MetricNamesParams struct {
    12  	Name string `url:"name,omitempty"`
    13  }
    14  
    15  // MetricDataParams are the request parameters for the /metrics/data.json endpoint.
    16  type MetricDataParams struct {
    17  	Names     []string   `url:"names[],omitempty"`
    18  	Values    []string   `url:"values[],omitempty"`
    19  	From      *time.Time `url:"from,omitempty"`
    20  	To        *time.Time `url:"to,omitempty"`
    21  	Period    int        `url:"period,omitempty"`
    22  	Summarize bool       `url:"summarize,omitempty"`
    23  	Raw       bool       `url:"raw,omitempty"`
    24  }
    25  
    26  // MetricName is the name of a metric, and the names of the values that can be retrieved.
    27  type MetricName struct {
    28  	Name   string   `json:"name,omitempty"`
    29  	Values []string `json:"values,omitempty"`
    30  }
    31  
    32  // MetricData is the series of time windows and the data therein, for a given metric name.
    33  type MetricData struct {
    34  	Name       string            `json:"name,omitempty"`
    35  	Timeslices []MetricTimeslice `json:"timeslices,omitempty"`
    36  }
    37  
    38  // MetricTimeslice is a single window of time for a given metric, with the associated metric data.
    39  type MetricTimeslice struct {
    40  	From   *time.Time            `json:"from"`
    41  	To     *time.Time            `json:"to"`
    42  	Values MetricTimesliceValues `json:"values"`
    43  }
    44  
    45  // MetricTimesliceValues is the collection of metric values for a single time slice.
    46  // Note that according to the API documentation, these values are from a `hashmap`.
    47  // The static values have been left in the struct to maintain backwards compatibility.
    48  // Users of this type should prefer the `Values` map over struct fields.
    49  type MetricTimesliceValues struct {
    50  	AsPercentage           float64 `json:"as_percentage,omitempty"`
    51  	AverageTime            float64 `json:"average_time,omitempty"`
    52  	CallsPerMinute         float64 `json:"calls_per_minute,omitempty"`
    53  	MaxValue               float64 `json:"max_value,omitempty"`
    54  	TotalCallTimePerMinute float64 `json:"total_call_time_per_minute,omitempty"`
    55  	Utilization            float64 `json:"utilization,omitempty"`
    56  
    57  	Values map[string]float64 `json:"-"`
    58  }
    59  
    60  // UnmarshalJSON is a custom unmarshaling function that unmarshals the JSON into a `MetricTimesliceValues` and into the `Values` field.
    61  func (m *MetricTimesliceValues) UnmarshalJSON(b []byte) error {
    62  	// Create a type alias for unmarshaling MetricTimesliceValues to avoid an infinite loop,
    63  	// but still take advantage of the standard json.Unmarshal functionality
    64  	type timeSliceValues MetricTimesliceValues
    65  	metricValues := timeSliceValues{
    66  		Values: map[string]float64{},
    67  	}
    68  
    69  	if err := json.Unmarshal(b, &metricValues); err != nil {
    70  		return err
    71  	}
    72  
    73  	// Unmarshal the same JSON into the map
    74  	if err := json.Unmarshal(b, &metricValues.Values); err != nil {
    75  		return err
    76  	}
    77  
    78  	*m = MetricTimesliceValues(metricValues)
    79  	return nil
    80  }
    81  
    82  // GetMetricNames is used to retrieve a list of known metrics and their value names for the given resource.
    83  //
    84  // https://rpm.newrelic.com/api/explore/applications/metric_names
    85  func (a *APM) GetMetricNames(applicationID int, params MetricNamesParams) ([]*MetricName, error) {
    86  	return a.GetMetricNamesWithContext(context.Background(), applicationID, params)
    87  }
    88  
    89  // GetMetricNamesWithContext is used to retrieve a list of known metrics and their value names for the given resource.
    90  //
    91  // https://rpm.newrelic.com/api/explore/applications/metric_names
    92  func (a *APM) GetMetricNamesWithContext(ctx context.Context, applicationID int, params MetricNamesParams) ([]*MetricName, error) {
    93  	nextURL := a.config.Region().RestURL("applications", strconv.Itoa(applicationID), "metrics.json")
    94  	response := metricNamesResponse{}
    95  	metrics := []*MetricName{}
    96  
    97  	for nextURL != "" {
    98  		resp, err := a.client.GetWithContext(ctx, nextURL, &params, &response)
    99  
   100  		if err != nil {
   101  			return nil, err
   102  		}
   103  
   104  		metrics = append(metrics, response.Metrics...)
   105  
   106  		paging := a.pager.Parse(resp)
   107  		nextURL = paging.Next
   108  	}
   109  
   110  	return metrics, nil
   111  }
   112  
   113  // GetMetricData is used to retrieve a list of values for each of the requested metrics.
   114  //
   115  // https://rpm.newrelic.com/api/explore/applications/metric_data
   116  func (a *APM) GetMetricData(applicationID int, params MetricDataParams) ([]*MetricData, error) {
   117  	return a.GetMetricDataWithContext(context.Background(), applicationID, params)
   118  }
   119  
   120  // GetMetricDataWithContext is used to retrieve a list of values for each of the requested metrics.
   121  //
   122  // https://rpm.newrelic.com/api/explore/applications/metric_data
   123  func (a *APM) GetMetricDataWithContext(ctx context.Context, applicationID int, params MetricDataParams) ([]*MetricData, error) {
   124  	nextURL := a.config.Region().RestURL("applications", strconv.Itoa(applicationID), "/metrics/data.json")
   125  
   126  	response := metricDataResponse{}
   127  	data := []*MetricData{}
   128  
   129  	for nextURL != "" {
   130  		resp, err := a.client.GetWithContext(ctx, nextURL, &params, &response)
   131  
   132  		if err != nil {
   133  			return nil, err
   134  		}
   135  
   136  		data = append(data, response.MetricData.Metrics...)
   137  
   138  		paging := a.pager.Parse(resp)
   139  		nextURL = paging.Next
   140  	}
   141  
   142  	return data, nil
   143  }
   144  
   145  type metricNamesResponse struct {
   146  	Metrics []*MetricName
   147  }
   148  
   149  type metricDataResponse struct {
   150  	MetricData struct {
   151  		From            *time.Time    `json:"from"`
   152  		To              *time.Time    `json:"to"`
   153  		MetricsNotFound []string      `json:"metrics_not_found"`
   154  		MetricsFound    []string      `json:"metrics_found"`
   155  		Metrics         []*MetricData `json:"metrics"`
   156  	} `json:"metric_data"`
   157  }