using System; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.Linq; | |
using System.Net; | |
using System.Net.Http; | |
using System.Net.Http.Headers; | |
using System.Reactive.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
using Amazon; | |
using Amazon.CloudWatch; | |
using Amazon.CloudWatch.Model; | |
using Amazon.EC2.Model; | |
using Amazon.ElasticTranscoder.Model; | |
using Amazon.RDS; | |
using Newtonsoft.Json; | |
using Newtonsoft.Json.Linq; | |
namespace Grani.NewRelic.RDS | |
{ | |
class Program | |
{ | |
private static int ProcessId; | |
private static string HostName; | |
private static readonly string PluginVersion = "0.0.1"; | |
private static readonly string LicenseKey = "YourLicenceKey"; | |
private static DateTime Last { get; set; } | |
private static HttpClient client; | |
private static IDisposable timer; | |
private static List<RDSMetric> MetricList = new List<RDSMetric>() | |
{ | |
new RDSMetric("BinLogDiskUsage", "Average", StandardUnit.Bytes), | |
new RDSMetric("CPUUtilization", "Average", StandardUnit.Percent), | |
new RDSMetric("DatabaseConnections", "Average", StandardUnit.Count), | |
new RDSMetric("DiskQueueDepth", "Average", StandardUnit.Count), | |
new RDSMetric("FreeableMemory", "Average", StandardUnit.Bytes), | |
new RDSMetric("FreeStorageSpace", "Average", StandardUnit.Bytes), | |
new RDSMetric("ReplicaLag", "Average", StandardUnit.Seconds), | |
new RDSMetric("SwapUsage", "Average", StandardUnit.Bytes), | |
new RDSMetric("ReadIOPS", "Average", StandardUnit.CountSecond), | |
new RDSMetric("WriteIOPS", "Average", StandardUnit.CountSecond), | |
new RDSMetric("ReadLatency", "Average", StandardUnit.Seconds), | |
new RDSMetric("WriteLatency", "Average", StandardUnit.Seconds), | |
new RDSMetric("ReadThroughput", "Average", StandardUnit.BytesSecond), | |
new RDSMetric("WriteThroughput", "Average", StandardUnit.BytesSecond) | |
}; | |
static Program() | |
{ | |
ProcessId = Process.GetCurrentProcess().Id; | |
HostName = Dns.GetHostName(); | |
} | |
static void Main(string[] args) | |
{ | |
Last = DateTime.Now; | |
client = new HttpClient(); | |
client.DefaultRequestHeaders.Add("X-License-Key", LicenseKey); | |
client.DefaultRequestHeaders.Add("Accept", "application/json"); | |
var cloudwatch = new AmazonCloudWatchClient(RegionEndpoint.APNortheast1); | |
var rds = new AmazonRDSClient(RegionEndpoint.APNortheast1); | |
var dBInstanceIdentifiers = rds.DescribeDBInstances().DBInstances.Select(db => db.DBInstanceIdentifier) | |
.Where(id => id.Contains("production")).ToArray(); | |
var tasks = dBInstanceIdentifiers.SelectMany(name => MetricList.Select(metric => new {name, metric})) | |
.Select(pair => | |
new DataPointWrapper() | |
{ | |
Metric = pair.metric, | |
Name = pair.name, | |
Datapoints = (cloudwatch.GetMetricStatistics(new GetMetricStatisticsRequest() | |
{ | |
Namespace = @"AWS/RDS", | |
MetricName = pair.metric.MetricName, | |
Statistics = new List<string>() { pair.metric.Statistic }, | |
Unit = pair.metric.Unit, | |
Dimensions = new List<Dimension>() | |
{ | |
new Dimension() {Name = "DBInstanceIdentifier", Value = pair.name} | |
}, | |
StartTime = DateTime.UtcNow - TimeSpan.FromMinutes(2), | |
EndTime = DateTime.UtcNow - TimeSpan.FromMinutes(1), | |
Period = 60 | |
})).Datapoints | |
}); | |
var timer = Observable.Interval(TimeSpan.FromSeconds(60)) | |
.Select(_ => tasks.ToArray()) | |
.Subscribe(Send); | |
Console.ReadKey(); | |
} | |
private static void Send(DataPointWrapper[] results) | |
{ | |
var now = DateTime.Now; | |
var duration = (int)(now - Last).TotalSeconds; | |
Last = now; | |
var components = new List<Object>(){ new | |
{ | |
duration, | |
guid = "jp.tanaka733.newrelic.rds", | |
name = "production", | |
metrics = results.Aggregate(new JObject(), (o, wrapper) => | |
{ | |
o[string.Format("Component/RDS/{0}/{1}[{2}]", wrapper.Name, wrapper.Metric.MetricName, wrapper.Metric.Unit.Value)] = wrapper.Datapoints.Any() | |
? wrapper.Datapoints.First().Average | |
: 0; | |
return o; | |
}) | |
}}; | |
var payload = new | |
{ | |
agent = new | |
{ | |
host = HostName, | |
pid = ProcessId, | |
version = PluginVersion | |
}, | |
components | |
}; | |
var text = JsonConvert.SerializeObject(payload); | |
Console.WriteLine(text); | |
var content = new StringContent(text); | |
content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); | |
var result = client.PostAsync("https://platform-api.newrelic.com/platform/v1/metrics", content).Result; | |
if (!result.IsSuccessStatusCode) | |
{ | |
Console.WriteLine(result.Content.ReadAsStringAsync().Result); | |
} | |
} | |
} | |
public class DataPointWrapper | |
{ | |
public RDSMetric Metric { get; set; } | |
public string Name { get; set; } | |
public List<Datapoint> Datapoints { get; set; } | |
} | |
public class RDSMetric | |
{ | |
public string MetricName { get; set; } | |
public string Statistic { get; set; } | |
public StandardUnit Unit { get; set; } | |
public RDSMetric(string metricName, string statistic, StandardUnit unit) | |
{ | |
MetricName = metricName; | |
Statistic = statistic; | |
Unit = unit; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment