package newrelic import ( "fmt" "net/url" "time" "github.com/influxdata/telegraf/plugins/inputs" "github.com/rmanocha/go_newrelic_api" ) // Metric struct type Metric struct { Values []string } // NewRelic Plugin Struct type NewRelic struct { Name string APIKey string APPID int Metrics map[string]Metric PollServerAverages bool PollApplicationAverages bool } // Description of Plugin func (nr *NewRelic) Description() string { return "Newrelic Metrics Query Plugin" } var sampleConfig = ` # Name Name = "" #APIKey APIKey = "" #Application ID APPID = # Poll for Averages PollServerAverages=false PollApplicationAverages=false # Poll for individual metrics [inputs.newrelic.Metrics] [inputs.newrelic.Metrics.Apdex] Values = ["f", "count", "value", "threshold", "threshold_min", "score", "s"] [inputs.newrelic.Metrics."Errors/all"] Values = ["errors_per_minute", "error_count"] [inputs.newrelic.Metrics."EndUser"] Values = ["average_response_time", "calls_per_minute", "call_count"] [inputs.newrelic.Metrics."HttpDispatcher"] Values = ["average_response_time", "calls_per_minute", "call_count"] ` // SampleConfig of Plugin func (nr *NewRelic) SampleConfig() string { return sampleConfig } func (nr *NewRelic) GatherServerAverages(acc inputs.Accumulator, nrapi *go_newrelic_api.Newrelic) error { dataserver := nrapi.GetServers() for v := range dataserver.Servers { tags := map[string]string{ "ServerName": fmt.Sprintf("%s", dataserver.Servers[v].Name), } fieldsServers := map[string]interface{}{ "CPU": dataserver.Servers[v].ServerSummary.CPU, "CPUStolen": dataserver.Servers[v].ServerSummary.CPUStolen, "DiskIOPercent": dataserver.Servers[v].ServerSummary.DiskIO, "MemoryPercent": dataserver.Servers[v].ServerSummary.Memory, "MemoryUsed": dataserver.Servers[v].ServerSummary.MemoryUsed, "MemoryTotal": dataserver.Servers[v].ServerSummary.MemoryTotal, "FullestDisk": dataserver.Servers[v].ServerSummary.FullestDisk, "FullestDiskFree": dataserver.Servers[v].ServerSummary.FullestDiskFree, } acc.AddFields("Servers", fieldsServers, tags) } return nil } func (nr *NewRelic) GatherApplicationAverages(acc inputs.Accumulator, nrapi *go_newrelic_api.Newrelic) error { dataapplication := nrapi.GetApplication(nr.APPID) fieldsApplication := map[string]interface{}{ "ResponceTime": dataapplication.Application.ApplicationSummary.ResponseTime, "Throughput": dataapplication.Application.ApplicationSummary.Throughput, "ErrorRate": dataapplication.Application.ApplicationSummary.ErrorRate, "ApdexTarget": dataapplication.Application.ApplicationSummary.ApdexTarget, "ApdexScore": dataapplication.Application.ApplicationSummary.ApdexScore, } fieldsEndUser := map[string]interface{}{ "ResponceTime": dataapplication.Application.EndUserSummary.ResponseTime, "Throughput": dataapplication.Application.EndUserSummary.Throughput, "ApdexTarget": dataapplication.Application.EndUserSummary.ApdexTarget, "ApdexScore": dataapplication.Application.EndUserSummary.ApdexScore, } acc.AddFields("Application", fieldsApplication, nil) acc.AddFields("EndUser", fieldsEndUser, nil) return nil } func (nr *NewRelic) GatherMetrics(acc inputs.Accumulator, nrapi *go_newrelic_api.Newrelic) error { return nil } // Gather requested metrics func (nr *NewRelic) Gather(acc inputs.Accumulator) error { conn := go_newrelic_api.NewNewrelic(nr.APIKey) if nr.PollServerAverages { nr.GatherServerAverages(acc, conn) } if nr.PollApplicationAverages { nr.GatherApplicationAverages(acc, conn) } if len(nr.Metrics) > 0 { tNow := time.Now() tFrom := tNow.Add(-1 * time.Minute) tFromStr := fmt.Sprintf("%d-%02d-%02dT%02d:%02d:%02d-00:00\n", tFrom.Year(), tFrom.Month(), tFrom.Day(), tFrom.Hour(), tFrom.Minute(), 00) tToStr := fmt.Sprintf("%d-%02d-%02dT%02d:%02d:%02d-00:00\n", tNow.Year(), tNow.Month(), tNow.Day(), tNow.Hour(), tNow.Minute(), 00) vals := url.Values{} vals.Add("from", tFromStr) vals.Add("to", tToStr) for k := range nr.Metrics { vals.Add("names[]", k) } result := conn.GetMetricData(nr.APPID, vals) var fieldsMetrics map[string]interface{} fieldsMetrics = make(map[string]interface{}) for metricRequest := range nr.Metrics { for metricResult := range result.MetricData.Metrics { if metricRequest == result.MetricData.Metrics[metricResult].Name { // If new relic returned a metric we are after for valueRequest := range nr.Metrics[metricRequest].Values { for valueResult := range result.MetricData.Metrics[metricResult].Timeslices[0].Values { if valueResult == nr.Metrics[metricRequest].Values[valueRequest] { // If we matched a returned metric value that was requested fieldsMetrics[metricRequest+"_"+valueResult] = result.MetricData.Metrics[metricResult].Timeslices[0].Values[valueResult] } } } } } } acc.AddFields("Metrics", fieldsMetrics, nil) } return nil } func init() { inputs.Add("newrelic", func() inputs.Input { return &NewRelic{} }) }