CloudWatch ejemplos que utilizan AWS SDK for .NET - AWS Ejemplos de código de SDK

Hay más ejemplos de AWS SDK disponibles en el GitHub repositorio de ejemplos de AWS Doc SDK.

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

CloudWatch ejemplos que utilizan AWS SDK for .NET

Los siguientes ejemplos de código muestran cómo realizar acciones e implementar escenarios comunes mediante el uso del AWS SDK for .NET with CloudWatch.

Las acciones son extractos de código de programas más grandes y deben ejecutarse en contexto. Mientras las acciones muestran cómo llamar a las funciones de servicio individuales, es posible ver las acciones en contexto en los escenarios relacionados y en los ejemplos entre servicios.

Los escenarios son ejemplos de código que muestran cómo llevar a cabo una tarea específica llamando a varias funciones dentro del mismo servicio.

Cada ejemplo incluye un enlace a GitHub, donde puede encontrar instrucciones sobre cómo configurar y ejecutar el código en su contexto.

Introducción

Los siguientes ejemplos de código muestran cómo empezar a usarlo CloudWatch.

AWS SDK for .NET
nota

Hay más información al respecto GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el Repositorio de ejemplos de código de AWS.

using Amazon.CloudWatch; using Amazon.CloudWatch.Model; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace CloudWatchActions; public static class HelloCloudWatch { static async Task Main(string[] args) { // Use the AWS .NET Core Setup package to set up dependency injection for the Amazon CloudWatch service. // Use your AWS profile name, or leave it blank to use the default profile. using var host = Host.CreateDefaultBuilder(args) .ConfigureServices((_, services) => services.AddAWSService<IAmazonCloudWatch>() ).Build(); // Now the client is available for injection. var cloudWatchClient = host.Services.GetRequiredService<IAmazonCloudWatch>(); // You can use await and any of the async methods to get a response. var metricNamespace = "AWS/Billing"; var response = await cloudWatchClient.ListMetricsAsync(new ListMetricsRequest { Namespace = metricNamespace }); Console.WriteLine($"Hello Amazon CloudWatch! Following are some metrics available in the {metricNamespace} namespace:"); Console.WriteLine(); foreach (var metric in response.Metrics.Take(5)) { Console.WriteLine($"\tMetric: {metric.MetricName}"); Console.WriteLine($"\tNamespace: {metric.Namespace}"); Console.WriteLine($"\tDimensions: {string.Join(", ", metric.Dimensions.Select(m => $"{m.Name}:{m.Value}"))}"); Console.WriteLine(); } } }
  • Para obtener más información sobre la API, consulta ListMetricsla Referencia AWS SDK for .NET de la API.

Acciones

En el siguiente ejemplo de código, se muestra cómo usar DeleteAlarms.

AWS SDK for .NET
nota

Hay más información al respecto GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el Repositorio de ejemplos de código de AWS.

/// <summary> /// Delete a list of alarms from CloudWatch. /// </summary> /// <param name="alarmNames">A list of names of alarms to delete.</param> /// <returns>True if successful.</returns> public async Task<bool> DeleteAlarms(List<string> alarmNames) { var deleteAlarmsResult = await _amazonCloudWatch.DeleteAlarmsAsync( new DeleteAlarmsRequest() { AlarmNames = alarmNames }); return deleteAlarmsResult.HttpStatusCode == HttpStatusCode.OK; }
  • Para obtener más información sobre la API, consulta DeleteAlarmsla Referencia AWS SDK for .NET de la API.

En el siguiente ejemplo de código, se muestra cómo usar DeleteAnomalyDetector.

AWS SDK for .NET
nota

Hay más información al respecto GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el Repositorio de ejemplos de código de AWS.

/// <summary> /// Delete a single metric anomaly detector. /// </summary> /// <param name="anomalyDetector">The anomaly detector to delete.</param> /// <returns>True if successful.</returns> public async Task<bool> DeleteAnomalyDetector(SingleMetricAnomalyDetector anomalyDetector) { var deleteAnomalyDetectorResponse = await _amazonCloudWatch.DeleteAnomalyDetectorAsync( new DeleteAnomalyDetectorRequest() { SingleMetricAnomalyDetector = anomalyDetector }); return deleteAnomalyDetectorResponse.HttpStatusCode == HttpStatusCode.OK; }
  • Para obtener más información sobre la API, consulta DeleteAnomalyDetectorla Referencia AWS SDK for .NET de la API.

En el siguiente ejemplo de código, se muestra cómo usar DeleteDashboards.

AWS SDK for .NET
nota

Hay más información al respecto GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el Repositorio de ejemplos de código de AWS.

/// <summary> /// Delete a list of CloudWatch dashboards. /// </summary> /// <param name="dashboardNames">List of dashboard names to delete.</param> /// <returns>True if successful.</returns> public async Task<bool> DeleteDashboards(List<string> dashboardNames) { var deleteDashboardsResponse = await _amazonCloudWatch.DeleteDashboardsAsync( new DeleteDashboardsRequest() { DashboardNames = dashboardNames }); return deleteDashboardsResponse.HttpStatusCode == HttpStatusCode.OK; }
  • Para obtener más información sobre la API, consulta DeleteDashboardsla Referencia AWS SDK for .NET de la API.

En el siguiente ejemplo de código, se muestra cómo usar DescribeAlarmHistory.

AWS SDK for .NET
nota

Hay más información al respecto GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el Repositorio de ejemplos de código de AWS.

/// <summary> /// Describe the history of an alarm for a number of days in the past. /// </summary> /// <param name="alarmName">The name of the alarm.</param> /// <param name="historyDays">The number of days in the past.</param> /// <returns>The list of alarm history data.</returns> public async Task<List<AlarmHistoryItem>> DescribeAlarmHistory(string alarmName, int historyDays) { List<AlarmHistoryItem> alarmHistory = new List<AlarmHistoryItem>(); var paginatedAlarmHistory = _amazonCloudWatch.Paginators.DescribeAlarmHistory( new DescribeAlarmHistoryRequest() { AlarmName = alarmName, EndDateUtc = DateTime.UtcNow, HistoryItemType = HistoryItemType.StateUpdate, StartDateUtc = DateTime.UtcNow.AddDays(-historyDays) }); await foreach (var data in paginatedAlarmHistory.AlarmHistoryItems) { alarmHistory.Add(data); } return alarmHistory; }
  • Para obtener más información sobre la API, consulta DescribeAlarmHistoryla Referencia AWS SDK for .NET de la API.

En el siguiente ejemplo de código, se muestra cómo usar DescribeAlarms.

AWS SDK for .NET
nota

Hay más información al respecto GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el Repositorio de ejemplos de código de AWS.

/// <summary> /// Describe the current alarms, optionally filtered by state. /// </summary> /// <param name="stateValue">Optional filter for alarm state.</param> /// <returns>The list of alarm data.</returns> public async Task<List<MetricAlarm>> DescribeAlarms(StateValue? stateValue = null) { List<MetricAlarm> alarms = new List<MetricAlarm>(); var paginatedDescribeAlarms = _amazonCloudWatch.Paginators.DescribeAlarms( new DescribeAlarmsRequest() { StateValue = stateValue }); await foreach (var data in paginatedDescribeAlarms.MetricAlarms) { alarms.Add(data); } return alarms; }
  • Para obtener más información sobre la API, consulta DescribeAlarmsla Referencia AWS SDK for .NET de la API.

En el siguiente ejemplo de código, se muestra cómo usar DescribeAlarmsForMetric.

AWS SDK for .NET
nota

Hay más información al respecto GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el Repositorio de ejemplos de código de AWS.

/// <summary> /// Describe the current alarms for a specific metric. /// </summary> /// <param name="metricNamespace">The namespace of the metric.</param> /// <param name="metricName">The name of the metric.</param> /// <returns>The list of alarm data.</returns> public async Task<List<MetricAlarm>> DescribeAlarmsForMetric(string metricNamespace, string metricName) { var alarmsResult = await _amazonCloudWatch.DescribeAlarmsForMetricAsync( new DescribeAlarmsForMetricRequest() { Namespace = metricNamespace, MetricName = metricName }); return alarmsResult.MetricAlarms; }
  • Para obtener más información sobre la API, consulta DescribeAlarmsForMetricla Referencia AWS SDK for .NET de la API.

En el siguiente ejemplo de código, se muestra cómo usar DescribeAnomalyDetectors.

AWS SDK for .NET
nota

Hay más información al respecto GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el Repositorio de ejemplos de código de AWS.

/// <summary> /// Describe anomaly detectors for a metric and namespace. /// </summary> /// <param name="metricNamespace">The namespace of the metric.</param> /// <param name="metricName">The metric of the anomaly detectors.</param> /// <returns>The list of detectors.</returns> public async Task<List<AnomalyDetector>> DescribeAnomalyDetectors(string metricNamespace, string metricName) { List<AnomalyDetector> detectors = new List<AnomalyDetector>(); var paginatedDescribeAnomalyDetectors = _amazonCloudWatch.Paginators.DescribeAnomalyDetectors( new DescribeAnomalyDetectorsRequest() { MetricName = metricName, Namespace = metricNamespace }); await foreach (var data in paginatedDescribeAnomalyDetectors.AnomalyDetectors) { detectors.Add(data); } return detectors; }
  • Para obtener más información sobre la API, consulta DescribeAnomalyDetectorsla Referencia AWS SDK for .NET de la API.

En el siguiente ejemplo de código, se muestra cómo usar DisableAlarmActions.

AWS SDK for .NET
nota

Hay más información al respecto GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el Repositorio de ejemplos de código de AWS.

/// <summary> /// Disable the actions for a list of alarms from CloudWatch. /// </summary> /// <param name="alarmNames">A list of names of alarms.</param> /// <returns>True if successful.</returns> public async Task<bool> DisableAlarmActions(List<string> alarmNames) { var disableAlarmActionsResult = await _amazonCloudWatch.DisableAlarmActionsAsync( new DisableAlarmActionsRequest() { AlarmNames = alarmNames }); return disableAlarmActionsResult.HttpStatusCode == HttpStatusCode.OK; }
  • Para obtener más información sobre la API, consulta DisableAlarmActionsla Referencia AWS SDK for .NET de la API.

En el siguiente ejemplo de código, se muestra cómo usar EnableAlarmActions.

AWS SDK for .NET
nota

Hay más información al respecto GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el Repositorio de ejemplos de código de AWS.

/// <summary> /// Enable the actions for a list of alarms from CloudWatch. /// </summary> /// <param name="alarmNames">A list of names of alarms.</param> /// <returns>True if successful.</returns> public async Task<bool> EnableAlarmActions(List<string> alarmNames) { var enableAlarmActionsResult = await _amazonCloudWatch.EnableAlarmActionsAsync( new EnableAlarmActionsRequest() { AlarmNames = alarmNames }); return enableAlarmActionsResult.HttpStatusCode == HttpStatusCode.OK; }
  • Para obtener más información sobre la API, consulta EnableAlarmActionsla Referencia AWS SDK for .NET de la API.

En el siguiente ejemplo de código, se muestra cómo usar GetDashboard.

AWS SDK for .NET
nota

Hay más información al respecto GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el Repositorio de ejemplos de código de AWS.

/// <summary> /// Get information on a dashboard. /// </summary> /// <param name="dashboardName">The name of the dashboard.</param> /// <returns>A JSON object with dashboard information.</returns> public async Task<string> GetDashboard(string dashboardName) { var dashboardResponse = await _amazonCloudWatch.GetDashboardAsync( new GetDashboardRequest() { DashboardName = dashboardName }); return dashboardResponse.DashboardBody; }
  • Para obtener más información sobre la API, consulta GetDashboardla Referencia AWS SDK for .NET de la API.

En el siguiente ejemplo de código, se muestra cómo usar GetMetricData.

AWS SDK for .NET
nota

Hay más información al respecto GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el Repositorio de ejemplos de código de AWS.

/// <summary> /// Get data for CloudWatch metrics. /// </summary> /// <param name="minutesOfData">The number of minutes of data to include.</param> /// <param name="useDescendingTime">True to return the data descending by time.</param> /// <param name="endDateUtc">The end date for the data, in UTC.</param> /// <param name="maxDataPoints">The maximum data points to include.</param> /// <param name="dataQueries">Optional data queries to include.</param> /// <returns>A list of the requested metric data.</returns> public async Task<List<MetricDataResult>> GetMetricData(int minutesOfData, bool useDescendingTime, DateTime? endDateUtc = null, int maxDataPoints = 0, List<MetricDataQuery>? dataQueries = null) { var metricData = new List<MetricDataResult>(); // If no end time is provided, use the current time for the end time. endDateUtc ??= DateTime.UtcNow; var timeZoneOffset = TimeZoneInfo.Local.GetUtcOffset(endDateUtc.Value.ToLocalTime()); var startTimeUtc = endDateUtc.Value.AddMinutes(-minutesOfData); // The timezone string should be in the format +0000, so use the timezone offset to format it correctly. var timeZoneString = $"{timeZoneOffset.Hours:D2}{timeZoneOffset.Minutes:D2}"; var paginatedMetricData = _amazonCloudWatch.Paginators.GetMetricData( new GetMetricDataRequest() { StartTimeUtc = startTimeUtc, EndTimeUtc = endDateUtc.Value, LabelOptions = new LabelOptions { Timezone = timeZoneString }, ScanBy = useDescendingTime ? ScanBy.TimestampDescending : ScanBy.TimestampAscending, MaxDatapoints = maxDataPoints, MetricDataQueries = dataQueries, }); await foreach (var data in paginatedMetricData.MetricDataResults) { metricData.Add(data); } return metricData; }
  • Para obtener más información sobre la API, consulta GetMetricDatala Referencia AWS SDK for .NET de la API.

En el siguiente ejemplo de código, se muestra cómo usar GetMetricStatistics.

AWS SDK for .NET
nota

Hay más información al respecto GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el Repositorio de ejemplos de código de AWS.

/// <summary> /// Get billing statistics using a call to a wrapper class. /// </summary> /// <returns>A collection of billing statistics.</returns> private static async Task<List<Datapoint>> SetupBillingStatistics() { // Make a request for EstimatedCharges with a period of one day for the past seven days. var billingStatistics = await _cloudWatchWrapper.GetMetricStatistics( "AWS/Billing", "EstimatedCharges", new List<string>() { "Maximum" }, new List<Dimension>() { new Dimension { Name = "Currency", Value = "USD" } }, 7, 86400); billingStatistics = billingStatistics.OrderBy(n => n.Timestamp).ToList(); return billingStatistics; } /// <summary> /// Wrapper to get statistics for a specific CloudWatch metric. /// </summary> /// <param name="metricNamespace">The namespace of the metric.</param> /// <param name="metricName">The name of the metric.</param> /// <param name="statistics">The list of statistics to include.</param> /// <param name="dimensions">The list of dimensions to include.</param> /// <param name="days">The number of days in the past to include.</param> /// <param name="period">The period for the data.</param> /// <returns>A list of DataPoint objects for the statistics.</returns> public async Task<List<Datapoint>> GetMetricStatistics(string metricNamespace, string metricName, List<string> statistics, List<Dimension> dimensions, int days, int period) { var metricStatistics = await _amazonCloudWatch.GetMetricStatisticsAsync( new GetMetricStatisticsRequest() { Namespace = metricNamespace, MetricName = metricName, Dimensions = dimensions, Statistics = statistics, StartTimeUtc = DateTime.UtcNow.AddDays(-days), EndTimeUtc = DateTime.UtcNow, Period = period }); return metricStatistics.Datapoints; }
  • Para obtener más información sobre la API, consulta GetMetricStatisticsla Referencia AWS SDK for .NET de la API.

En el siguiente ejemplo de código, se muestra cómo usar GetMetricWidgetImage.

AWS SDK for .NET
nota

Hay más información al respecto GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el Repositorio de ejemplos de código de AWS.

/// <summary> /// Get an image for a metric graphed over time. /// </summary> /// <param name="metricNamespace">The namespace of the metric.</param> /// <param name="metric">The name of the metric.</param> /// <param name="stat">The name of the stat to chart.</param> /// <param name="period">The period to use for the chart.</param> /// <returns>A memory stream for the chart image.</returns> public async Task<MemoryStream> GetTimeSeriesMetricImage(string metricNamespace, string metric, string stat, int period) { var metricImageWidget = new { title = "Example Metric Graph", view = "timeSeries", stacked = false, period = period, width = 1400, height = 600, metrics = new List<List<object>> { new() { metricNamespace, metric, new { stat } } } }; var metricImageWidgetString = JsonSerializer.Serialize(metricImageWidget); var imageResponse = await _amazonCloudWatch.GetMetricWidgetImageAsync( new GetMetricWidgetImageRequest() { MetricWidget = metricImageWidgetString }); return imageResponse.MetricWidgetImage; } /// <summary> /// Save a metric image to a file. /// </summary> /// <param name="memoryStream">The MemoryStream for the metric image.</param> /// <param name="metricName">The name of the metric.</param> /// <returns>The path to the file.</returns> public string SaveMetricImage(MemoryStream memoryStream, string metricName) { var metricFileName = $"{metricName}_{DateTime.Now.Ticks}.png"; using var sr = new StreamReader(memoryStream); // Writes the memory stream to a file. File.WriteAllBytes(metricFileName, memoryStream.ToArray()); var filePath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, metricFileName); return filePath; }
  • Para obtener más información sobre la API, consulta GetMetricWidgetImagela Referencia AWS SDK for .NET de la API.

En el siguiente ejemplo de código, se muestra cómo usar ListDashboards.

AWS SDK for .NET
nota

Hay más información al respecto GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el Repositorio de ejemplos de código de AWS.

/// <summary> /// Get a list of dashboards. /// </summary> /// <returns>A list of DashboardEntry objects.</returns> public async Task<List<DashboardEntry>> ListDashboards() { var results = new List<DashboardEntry>(); var paginateDashboards = _amazonCloudWatch.Paginators.ListDashboards( new ListDashboardsRequest()); // Get the entire list using the paginator. await foreach (var data in paginateDashboards.DashboardEntries) { results.Add(data); } return results; }
  • Para obtener más información sobre la API, consulta ListDashboardsla Referencia AWS SDK for .NET de la API.

En el siguiente ejemplo de código, se muestra cómo usar ListMetrics.

AWS SDK for .NET
nota

Hay más información al respecto GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el Repositorio de ejemplos de código de AWS.

/// <summary> /// List metrics available, optionally within a namespace. /// </summary> /// <param name="metricNamespace">Optional CloudWatch namespace to use when listing metrics.</param> /// <param name="filter">Optional dimension filter.</param> /// <param name="metricName">Optional metric name filter.</param> /// <returns>The list of metrics.</returns> public async Task<List<Metric>> ListMetrics(string? metricNamespace = null, DimensionFilter? filter = null, string? metricName = null) { var results = new List<Metric>(); var paginateMetrics = _amazonCloudWatch.Paginators.ListMetrics( new ListMetricsRequest { Namespace = metricNamespace, Dimensions = filter != null ? new List<DimensionFilter> { filter } : null, MetricName = metricName }); // Get the entire list using the paginator. await foreach (var metric in paginateMetrics.Metrics) { results.Add(metric); } return results; }
  • Para obtener más información sobre la API, consulta ListMetricsla Referencia AWS SDK for .NET de la API.

En el siguiente ejemplo de código, se muestra cómo usar PutAnomalyDetector.

AWS SDK for .NET
nota

Hay más información al respecto GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el Repositorio de ejemplos de código de AWS.

/// <summary> /// Add an anomaly detector for a single metric. /// </summary> /// <param name="anomalyDetector">A single metric anomaly detector.</param> /// <returns>True if successful.</returns> public async Task<bool> PutAnomalyDetector(SingleMetricAnomalyDetector anomalyDetector) { var putAlarmDetectorResult = await _amazonCloudWatch.PutAnomalyDetectorAsync( new PutAnomalyDetectorRequest() { SingleMetricAnomalyDetector = anomalyDetector }); return putAlarmDetectorResult.HttpStatusCode == HttpStatusCode.OK; }
  • Para obtener más información sobre la API, consulta PutAnomalyDetectorla Referencia AWS SDK for .NET de la API.

En el siguiente ejemplo de código, se muestra cómo usar PutDashboard.

AWS SDK for .NET
nota

Hay más información al respecto GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el Repositorio de ejemplos de código de AWS.

/// <summary> /// Set up a dashboard using a call to the wrapper class. /// </summary> /// <param name="customMetricNamespace">The metric namespace.</param> /// <param name="customMetricName">The metric name.</param> /// <param name="dashboardName">The name of the dashboard.</param> /// <returns>A list of validation messages.</returns> private static async Task<List<DashboardValidationMessage>> SetupDashboard( string customMetricNamespace, string customMetricName, string dashboardName) { // Get the dashboard model from configuration. var newDashboard = new DashboardModel(); _configuration.GetSection("dashboardExampleBody").Bind(newDashboard); // Add a new metric to the dashboard. newDashboard.Widgets.Add(new Widget { Height = 8, Width = 8, Y = 8, X = 0, Type = "metric", Properties = new Properties { Metrics = new List<List<object>> { new() { customMetricNamespace, customMetricName } }, View = "timeSeries", Region = "us-east-1", Stat = "Sum", Period = 86400, YAxis = new YAxis { Left = new Left { Min = 0, Max = 100 } }, Title = "Custom Metric Widget", LiveData = true, Sparkline = true, Trend = true, Stacked = false, SetPeriodToTimeRange = false } }); var newDashboardString = JsonSerializer.Serialize(newDashboard, new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }); var validationMessages = await _cloudWatchWrapper.PutDashboard(dashboardName, newDashboardString); return validationMessages; } /// <summary> /// Wrapper to create or add to a dashboard with metrics. /// </summary> /// <param name="dashboardName">The name for the dashboard.</param> /// <param name="dashboardBody">The metric data in JSON for the dashboard.</param> /// <returns>A list of validation messages for the dashboard.</returns> public async Task<List<DashboardValidationMessage>> PutDashboard(string dashboardName, string dashboardBody) { // Updating a dashboard replaces all contents. // Best practice is to include a text widget indicating this dashboard was created programmatically. var dashboardResponse = await _amazonCloudWatch.PutDashboardAsync( new PutDashboardRequest() { DashboardName = dashboardName, DashboardBody = dashboardBody }); return dashboardResponse.DashboardValidationMessages; }
  • Para obtener más información sobre la API, consulta PutDashboardla Referencia AWS SDK for .NET de la API.

En el siguiente ejemplo de código, se muestra cómo usar PutMetricAlarm.

AWS SDK for .NET
nota

Hay más información al respecto GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el Repositorio de ejemplos de código de AWS.

/// <summary> /// Add a metric alarm to send an email when the metric passes a threshold. /// </summary> /// <param name="alarmDescription">A description of the alarm.</param> /// <param name="alarmName">The name for the alarm.</param> /// <param name="comparison">The type of comparison to use.</param> /// <param name="metricName">The name of the metric for the alarm.</param> /// <param name="metricNamespace">The namespace of the metric.</param> /// <param name="threshold">The threshold value for the alarm.</param> /// <param name="alarmActions">Optional actions to execute when in an alarm state.</param> /// <returns>True if successful.</returns> public async Task<bool> PutMetricEmailAlarm(string alarmDescription, string alarmName, ComparisonOperator comparison, string metricName, string metricNamespace, double threshold, List<string> alarmActions = null!) { try { var putEmailAlarmResponse = await _amazonCloudWatch.PutMetricAlarmAsync( new PutMetricAlarmRequest() { AlarmActions = alarmActions, AlarmDescription = alarmDescription, AlarmName = alarmName, ComparisonOperator = comparison, Threshold = threshold, Namespace = metricNamespace, MetricName = metricName, EvaluationPeriods = 1, Period = 10, Statistic = new Statistic("Maximum"), DatapointsToAlarm = 1, TreatMissingData = "ignore" }); return putEmailAlarmResponse.HttpStatusCode == HttpStatusCode.OK; } catch (LimitExceededException lex) { _logger.LogError(lex, $"Unable to add alarm {alarmName}. Alarm quota has already been reached."); } return false; } /// <summary> /// Add specific email actions to a list of action strings for a CloudWatch alarm. /// </summary> /// <param name="accountId">The AccountId for the alarm.</param> /// <param name="region">The region for the alarm.</param> /// <param name="emailTopicName">An Amazon Simple Notification Service (SNS) topic for the alarm email.</param> /// <param name="alarmActions">Optional list of existing alarm actions to append to.</param> /// <returns>A list of string actions for an alarm.</returns> public List<string> AddEmailAlarmAction(string accountId, string region, string emailTopicName, List<string>? alarmActions = null) { alarmActions ??= new List<string>(); var snsAlarmAction = $"arn:aws:sns:{region}:{accountId}:{emailTopicName}"; alarmActions.Add(snsAlarmAction); return alarmActions; }
  • Para obtener más información sobre la API, consulta PutMetricAlarmla Referencia AWS SDK for .NET de la API.

En el siguiente ejemplo de código, se muestra cómo usar PutMetricData.

AWS SDK for .NET
nota

Hay más información al respecto GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el Repositorio de ejemplos de código de AWS.

/// <summary> /// Add some metric data using a call to a wrapper class. /// </summary> /// <param name="customMetricName">The metric name.</param> /// <param name="customMetricNamespace">The metric namespace.</param> /// <returns></returns> private static async Task<List<MetricDatum>> PutRandomMetricData(string customMetricName, string customMetricNamespace) { List<MetricDatum> customData = new List<MetricDatum>(); Random rnd = new Random(); // Add 10 random values up to 100, starting with a timestamp 15 minutes in the past. var utcNowMinus15 = DateTime.UtcNow.AddMinutes(-15); for (int i = 0; i < 10; i++) { var metricValue = rnd.Next(0, 100); customData.Add( new MetricDatum { MetricName = customMetricName, Value = metricValue, TimestampUtc = utcNowMinus15.AddMinutes(i) } ); } await _cloudWatchWrapper.PutMetricData(customMetricNamespace, customData); return customData; } /// <summary> /// Wrapper to add metric data to a CloudWatch metric. /// </summary> /// <param name="metricNamespace">The namespace of the metric.</param> /// <param name="metricData">A data object for the metric data.</param> /// <returns>True if successful.</returns> public async Task<bool> PutMetricData(string metricNamespace, List<MetricDatum> metricData) { var putDataResponse = await _amazonCloudWatch.PutMetricDataAsync( new PutMetricDataRequest() { MetricData = metricData, Namespace = metricNamespace, }); return putDataResponse.HttpStatusCode == HttpStatusCode.OK; }
  • Para obtener más información sobre la API, consulta PutMetricDatala Referencia AWS SDK for .NET de la API.

Escenarios

En el siguiente ejemplo de código, se muestra cómo:

  • Enumera los espacios de CloudWatch nombres y las métricas.

  • Obtener estadísticas para una métrica y para la facturación estimada.

  • Crear y actualizar un panel.

  • Crear y agregar datos a una métrica.

  • Crear y activar una alarma y, a continuación, consultar el historial de alarmas.

  • Crear un detector de anomalías.

  • Realice una imagen métrica y, luego, limpie los recursos.

AWS SDK for .NET
nota

Hay más en marcha. GitHub Busque el ejemplo completo y aprenda a configurar y ejecutar en el Repositorio de ejemplos de código de AWS.

Ejecutar un escenario interactivo en un símbolo del sistema.

public class CloudWatchScenario { /* Before running this .NET code example, set up your development environment, including your credentials. To enable billing metrics and statistics for this example, make sure billing alerts are enabled for your account: https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/monitor_estimated_charges_with_cloudwatch.html#turning_on_billing_metrics This .NET example performs the following tasks: 1. List and select a CloudWatch namespace. 2. List and select a CloudWatch metric. 3. Get statistics for a CloudWatch metric. 4. Get estimated billing statistics for the last week. 5. Create a new CloudWatch dashboard with two metrics. 6. List current CloudWatch dashboards. 7. Create a CloudWatch custom metric and add metric data. 8. Add the custom metric to the dashboard. 9. Create a CloudWatch alarm for the custom metric. 10. Describe current CloudWatch alarms. 11. Get recent data for the custom metric. 12. Add data to the custom metric to trigger the alarm. 13. Wait for an alarm state. 14. Get history for the CloudWatch alarm. 15. Add an anomaly detector. 16. Describe current anomaly detectors. 17. Get and display a metric image. 18. Clean up resources. */ private static ILogger logger = null!; private static CloudWatchWrapper _cloudWatchWrapper = null!; private static IConfiguration _configuration = null!; private static readonly List<string> _statTypes = new List<string> { "SampleCount", "Average", "Sum", "Minimum", "Maximum" }; private static SingleMetricAnomalyDetector? anomalyDetector = null!; static async Task Main(string[] args) { // Set up dependency injection for the Amazon service. using var host = Host.CreateDefaultBuilder(args) .ConfigureLogging(logging => logging.AddFilter("System", LogLevel.Debug) .AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information) .AddFilter<ConsoleLoggerProvider>("Microsoft", LogLevel.Trace)) .ConfigureServices((_, services) => services.AddAWSService<IAmazonCloudWatch>() .AddTransient<CloudWatchWrapper>() ) .Build(); _configuration = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("settings.json") // Load settings from .json file. .AddJsonFile("settings.local.json", true) // Optionally, load local settings. .Build(); logger = LoggerFactory.Create(builder => { builder.AddConsole(); }) .CreateLogger<CloudWatchScenario>(); _cloudWatchWrapper = host.Services.GetRequiredService<CloudWatchWrapper>(); Console.WriteLine(new string('-', 80)); Console.WriteLine("Welcome to the Amazon CloudWatch example scenario."); Console.WriteLine(new string('-', 80)); try { var selectedNamespace = await SelectNamespace(); var selectedMetric = await SelectMetric(selectedNamespace); await GetAndDisplayMetricStatistics(selectedNamespace, selectedMetric); await GetAndDisplayEstimatedBilling(); await CreateDashboardWithMetrics(); await ListDashboards(); await CreateNewCustomMetric(); await AddMetricToDashboard(); await CreateMetricAlarm(); await DescribeAlarms(); await GetCustomMetricData(); await AddMetricDataForAlarm(); await CheckForMetricAlarm(); await GetAlarmHistory(); anomalyDetector = await AddAnomalyDetector(); await DescribeAnomalyDetectors(); await GetAndOpenMetricImage(); await CleanupResources(); } catch (Exception ex) { logger.LogError(ex, "There was a problem executing the scenario."); await CleanupResources(); } } /// <summary> /// Select a namespace. /// </summary> /// <returns>The selected namespace.</returns> private static async Task<string> SelectNamespace() { Console.WriteLine(new string('-', 80)); Console.WriteLine($"1. Select a CloudWatch Namespace from a list of Namespaces."); var metrics = await _cloudWatchWrapper.ListMetrics(); // Get a distinct list of namespaces. var namespaces = metrics.Select(m => m.Namespace).Distinct().ToList(); for (int i = 0; i < namespaces.Count; i++) { Console.WriteLine($"\t{i + 1}. {namespaces[i]}"); } var namespaceChoiceNumber = 0; while (namespaceChoiceNumber < 1 || namespaceChoiceNumber > namespaces.Count) { Console.WriteLine( "Select a namespace by entering a number from the preceding list:"); var choice = Console.ReadLine(); Int32.TryParse(choice, out namespaceChoiceNumber); } var selectedNamespace = namespaces[namespaceChoiceNumber - 1]; Console.WriteLine(new string('-', 80)); return selectedNamespace; } /// <summary> /// Select a metric from a namespace. /// </summary> /// <param name="metricNamespace">The namespace for metrics.</param> /// <returns>The metric name.</returns> private static async Task<Metric> SelectMetric(string metricNamespace) { Console.WriteLine(new string('-', 80)); Console.WriteLine($"2. Select a CloudWatch metric from a namespace."); var namespaceMetrics = await _cloudWatchWrapper.ListMetrics(metricNamespace); for (int i = 0; i < namespaceMetrics.Count && i < 15; i++) { var dimensionsWithValues = namespaceMetrics[i].Dimensions .Where(d => !string.Equals("None", d.Value)); Console.WriteLine($"\t{i + 1}. {namespaceMetrics[i].MetricName} " + $"{string.Join(", :", dimensionsWithValues.Select(d => d.Value))}"); } var metricChoiceNumber = 0; while (metricChoiceNumber < 1 || metricChoiceNumber > namespaceMetrics.Count) { Console.WriteLine( "Select a metric by entering a number from the preceding list:"); var choice = Console.ReadLine(); Int32.TryParse(choice, out metricChoiceNumber); } var selectedMetric = namespaceMetrics[metricChoiceNumber - 1]; Console.WriteLine(new string('-', 80)); return selectedMetric; } /// <summary> /// Get and display metric statistics for a specific metric. /// </summary> /// <param name="metricNamespace">The namespace for metrics.</param> /// <param name="metric">The CloudWatch metric.</param> /// <returns>Async task.</returns> private static async Task GetAndDisplayMetricStatistics(string metricNamespace, Metric metric) { Console.WriteLine(new string('-', 80)); Console.WriteLine($"3. Get CloudWatch metric statistics for the last day."); for (int i = 0; i < _statTypes.Count; i++) { Console.WriteLine($"\t{i + 1}. {_statTypes[i]}"); } var statisticChoiceNumber = 0; while (statisticChoiceNumber < 1 || statisticChoiceNumber > _statTypes.Count) { Console.WriteLine( "Select a metric statistic by entering a number from the preceding list:"); var choice = Console.ReadLine(); Int32.TryParse(choice, out statisticChoiceNumber); } var selectedStatistic = _statTypes[statisticChoiceNumber - 1]; var statisticsList = new List<string> { selectedStatistic }; var metricStatistics = await _cloudWatchWrapper.GetMetricStatistics(metricNamespace, metric.MetricName, statisticsList, metric.Dimensions, 1, 60); if (!metricStatistics.Any()) { Console.WriteLine($"No {selectedStatistic} statistics found for {metric} in namespace {metricNamespace}."); } metricStatistics = metricStatistics.OrderBy(s => s.Timestamp).ToList(); for (int i = 0; i < metricStatistics.Count && i < 10; i++) { var metricStat = metricStatistics[i]; var statValue = metricStat.GetType().GetProperty(selectedStatistic)!.GetValue(metricStat, null); Console.WriteLine($"\t{i + 1}. Timestamp {metricStatistics[i].Timestamp:G} {selectedStatistic}: {statValue}"); } Console.WriteLine(new string('-', 80)); } /// <summary> /// Get and display estimated billing statistics. /// </summary> /// <param name="metricNamespace">The namespace for metrics.</param> /// <param name="metric">The CloudWatch metric.</param> /// <returns>Async task.</returns> private static async Task GetAndDisplayEstimatedBilling() { Console.WriteLine(new string('-', 80)); Console.WriteLine($"4. Get CloudWatch estimated billing for the last week."); var billingStatistics = await SetupBillingStatistics(); for (int i = 0; i < billingStatistics.Count; i++) { Console.WriteLine($"\t{i + 1}. Timestamp {billingStatistics[i].Timestamp:G} : {billingStatistics[i].Maximum}"); } Console.WriteLine(new string('-', 80)); } /// <summary> /// Get billing statistics using a call to a wrapper class. /// </summary> /// <returns>A collection of billing statistics.</returns> private static async Task<List<Datapoint>> SetupBillingStatistics() { // Make a request for EstimatedCharges with a period of one day for the past seven days. var billingStatistics = await _cloudWatchWrapper.GetMetricStatistics( "AWS/Billing", "EstimatedCharges", new List<string>() { "Maximum" }, new List<Dimension>() { new Dimension { Name = "Currency", Value = "USD" } }, 7, 86400); billingStatistics = billingStatistics.OrderBy(n => n.Timestamp).ToList(); return billingStatistics; } /// <summary> /// Create a dashboard with metrics. /// </summary> /// <param name="metricNamespace">The namespace for metrics.</param> /// <param name="metric">The CloudWatch metric.</param> /// <returns>Async task.</returns> private static async Task CreateDashboardWithMetrics() { Console.WriteLine(new string('-', 80)); Console.WriteLine($"5. Create a new CloudWatch dashboard with metrics."); var dashboardName = _configuration["dashboardName"]; var newDashboard = new DashboardModel(); _configuration.GetSection("dashboardExampleBody").Bind(newDashboard); var newDashboardString = JsonSerializer.Serialize( newDashboard, new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }); var validationMessages = await _cloudWatchWrapper.PutDashboard(dashboardName, newDashboardString); Console.WriteLine(validationMessages.Any() ? $"\tValidation messages:" : null); for (int i = 0; i < validationMessages.Count; i++) { Console.WriteLine($"\t{i + 1}. {validationMessages[i].Message}"); } Console.WriteLine($"\tDashboard {dashboardName} was created."); Console.WriteLine(new string('-', 80)); } /// <summary> /// List dashboards. /// </summary> /// <returns>Async task.</returns> private static async Task ListDashboards() { Console.WriteLine(new string('-', 80)); Console.WriteLine($"6. List the CloudWatch dashboards in the current account."); var dashboards = await _cloudWatchWrapper.ListDashboards(); for (int i = 0; i < dashboards.Count; i++) { Console.WriteLine($"\t{i + 1}. {dashboards[i].DashboardName}"); } Console.WriteLine(new string('-', 80)); } /// <summary> /// Create and add data for a new custom metric. /// </summary> /// <returns>Async task.</returns> private static async Task CreateNewCustomMetric() { Console.WriteLine(new string('-', 80)); Console.WriteLine($"7. Create and add data for a new custom metric."); var customMetricNamespace = _configuration["customMetricNamespace"]; var customMetricName = _configuration["customMetricName"]; var customData = await PutRandomMetricData(customMetricName, customMetricNamespace); var valuesString = string.Join(',', customData.Select(d => d.Value)); Console.WriteLine($"\tAdded metric values for for metric {customMetricName}: \n\t{valuesString}"); Console.WriteLine(new string('-', 80)); } /// <summary> /// Add some metric data using a call to a wrapper class. /// </summary> /// <param name="customMetricName">The metric name.</param> /// <param name="customMetricNamespace">The metric namespace.</param> /// <returns></returns> private static async Task<List<MetricDatum>> PutRandomMetricData(string customMetricName, string customMetricNamespace) { List<MetricDatum> customData = new List<MetricDatum>(); Random rnd = new Random(); // Add 10 random values up to 100, starting with a timestamp 15 minutes in the past. var utcNowMinus15 = DateTime.UtcNow.AddMinutes(-15); for (int i = 0; i < 10; i++) { var metricValue = rnd.Next(0, 100); customData.Add( new MetricDatum { MetricName = customMetricName, Value = metricValue, TimestampUtc = utcNowMinus15.AddMinutes(i) } ); } await _cloudWatchWrapper.PutMetricData(customMetricNamespace, customData); return customData; } /// <summary> /// Add the custom metric to the dashboard. /// </summary> /// <returns>Async task.</returns> private static async Task AddMetricToDashboard() { Console.WriteLine(new string('-', 80)); Console.WriteLine($"8. Add the new custom metric to the dashboard."); var dashboardName = _configuration["dashboardName"]; var customMetricNamespace = _configuration["customMetricNamespace"]; var customMetricName = _configuration["customMetricName"]; var validationMessages = await SetupDashboard(customMetricNamespace, customMetricName, dashboardName); Console.WriteLine(validationMessages.Any() ? $"\tValidation messages:" : null); for (int i = 0; i < validationMessages.Count; i++) { Console.WriteLine($"\t{i + 1}. {validationMessages[i].Message}"); } Console.WriteLine($"\tDashboard {dashboardName} updated with metric {customMetricName}."); Console.WriteLine(new string('-', 80)); } /// <summary> /// Set up a dashboard using a call to the wrapper class. /// </summary> /// <param name="customMetricNamespace">The metric namespace.</param> /// <param name="customMetricName">The metric name.</param> /// <param name="dashboardName">The name of the dashboard.</param> /// <returns>A list of validation messages.</returns> private static async Task<List<DashboardValidationMessage>> SetupDashboard( string customMetricNamespace, string customMetricName, string dashboardName) { // Get the dashboard model from configuration. var newDashboard = new DashboardModel(); _configuration.GetSection("dashboardExampleBody").Bind(newDashboard); // Add a new metric to the dashboard. newDashboard.Widgets.Add(new Widget { Height = 8, Width = 8, Y = 8, X = 0, Type = "metric", Properties = new Properties { Metrics = new List<List<object>> { new() { customMetricNamespace, customMetricName } }, View = "timeSeries", Region = "us-east-1", Stat = "Sum", Period = 86400, YAxis = new YAxis { Left = new Left { Min = 0, Max = 100 } }, Title = "Custom Metric Widget", LiveData = true, Sparkline = true, Trend = true, Stacked = false, SetPeriodToTimeRange = false } }); var newDashboardString = JsonSerializer.Serialize(newDashboard, new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }); var validationMessages = await _cloudWatchWrapper.PutDashboard(dashboardName, newDashboardString); return validationMessages; } /// <summary> /// Create a CloudWatch alarm for the new metric. /// </summary> /// <returns>Async task.</returns> private static async Task CreateMetricAlarm() { Console.WriteLine(new string('-', 80)); Console.WriteLine($"9. Create a CloudWatch alarm for the new metric."); var customMetricNamespace = _configuration["customMetricNamespace"]; var customMetricName = _configuration["customMetricName"]; var alarmName = _configuration["exampleAlarmName"]; var accountId = _configuration["accountId"]; var region = _configuration["region"]; var emailTopic = _configuration["emailTopic"]; var alarmActions = new List<string>(); if (GetYesNoResponse( $"\tAdd an email action for topic {emailTopic} to alarm {alarmName}? (y/n)")) { _cloudWatchWrapper.AddEmailAlarmAction(accountId, region, emailTopic, alarmActions); } await _cloudWatchWrapper.PutMetricEmailAlarm( "Example metric alarm", alarmName, ComparisonOperator.GreaterThanOrEqualToThreshold, customMetricName, customMetricNamespace, 100, alarmActions); Console.WriteLine($"\tAlarm {alarmName} added for metric {customMetricName}."); Console.WriteLine(new string('-', 80)); } /// <summary> /// Describe Alarms. /// </summary> /// <returns>Async task.</returns> private static async Task DescribeAlarms() { Console.WriteLine(new string('-', 80)); Console.WriteLine($"10. Describe CloudWatch alarms in the current account."); var alarms = await _cloudWatchWrapper.DescribeAlarms(); alarms = alarms.OrderByDescending(a => a.StateUpdatedTimestamp).ToList(); for (int i = 0; i < alarms.Count && i < 10; i++) { var alarm = alarms[i]; Console.WriteLine($"\t{i + 1}. {alarm.AlarmName}"); Console.WriteLine($"\tState: {alarm.StateValue} for {alarm.MetricName} {alarm.ComparisonOperator} {alarm.Threshold}"); } Console.WriteLine(new string('-', 80)); } /// <summary> /// Get the recent data for the metric. /// </summary> /// <returns>Async task.</returns> private static async Task GetCustomMetricData() { Console.WriteLine(new string('-', 80)); Console.WriteLine($"11. Get current data for new custom metric."); var customMetricNamespace = _configuration["customMetricNamespace"]; var customMetricName = _configuration["customMetricName"]; var accountId = _configuration["accountId"]; var query = new List<MetricDataQuery> { new MetricDataQuery { AccountId = accountId, Id = "m1", Label = "Custom Metric Data", MetricStat = new MetricStat { Metric = new Metric { MetricName = customMetricName, Namespace = customMetricNamespace, }, Period = 1, Stat = "Maximum" } } }; var metricData = await _cloudWatchWrapper.GetMetricData( 20, true, DateTime.UtcNow.AddMinutes(1), 20, query); for (int i = 0; i < metricData.Count; i++) { for (int j = 0; j < metricData[i].Values.Count; j++) { Console.WriteLine( $"\tTimestamp {metricData[i].Timestamps[j]:G} Value: {metricData[i].Values[j]}"); } } Console.WriteLine(new string('-', 80)); } /// <summary> /// Add metric data to trigger an alarm. /// </summary> /// <returns>Async task.</returns> private static async Task AddMetricDataForAlarm() { Console.WriteLine(new string('-', 80)); Console.WriteLine($"12. Add metric data to the custom metric to trigger an alarm."); var customMetricNamespace = _configuration["customMetricNamespace"]; var customMetricName = _configuration["customMetricName"]; var nowUtc = DateTime.UtcNow; List<MetricDatum> customData = new List<MetricDatum> { new MetricDatum { MetricName = customMetricName, Value = 101, TimestampUtc = nowUtc.AddMinutes(-2) }, new MetricDatum { MetricName = customMetricName, Value = 101, TimestampUtc = nowUtc.AddMinutes(-1) }, new MetricDatum { MetricName = customMetricName, Value = 101, TimestampUtc = nowUtc } }; var valuesString = string.Join(',', customData.Select(d => d.Value)); Console.WriteLine($"\tAdded metric values for for metric {customMetricName}: \n\t{valuesString}"); await _cloudWatchWrapper.PutMetricData(customMetricNamespace, customData); Console.WriteLine(new string('-', 80)); } /// <summary> /// Check for a metric alarm using the DescribeAlarmsForMetric action. /// </summary> /// <returns>Async task.</returns> private static async Task CheckForMetricAlarm() { Console.WriteLine(new string('-', 80)); Console.WriteLine($"13. Checking for an alarm state."); var customMetricNamespace = _configuration["customMetricNamespace"]; var customMetricName = _configuration["customMetricName"]; var hasAlarm = false; var retries = 10; while (!hasAlarm && retries > 0) { var alarms = await _cloudWatchWrapper.DescribeAlarmsForMetric(customMetricNamespace, customMetricName); hasAlarm = alarms.Any(a => a.StateValue == StateValue.ALARM); retries--; Thread.Sleep(20000); } Console.WriteLine(hasAlarm ? $"\tAlarm state found for {customMetricName}." : $"\tNo Alarm state found for {customMetricName} after 10 retries."); Console.WriteLine(new string('-', 80)); } /// <summary> /// Get history for an alarm. /// </summary> /// <returns>Async task.</returns> private static async Task GetAlarmHistory() { Console.WriteLine(new string('-', 80)); Console.WriteLine($"14. Get alarm history."); var exampleAlarmName = _configuration["exampleAlarmName"]; var alarmHistory = await _cloudWatchWrapper.DescribeAlarmHistory(exampleAlarmName, 2); for (int i = 0; i < alarmHistory.Count; i++) { var history = alarmHistory[i]; Console.WriteLine($"\t{i + 1}. {history.HistorySummary}, time {history.Timestamp:g}"); } if (!alarmHistory.Any()) { Console.WriteLine($"\tNo alarm history data found for {exampleAlarmName}."); } Console.WriteLine(new string('-', 80)); } /// <summary> /// Add an anomaly detector. /// </summary> /// <returns>Async task.</returns> private static async Task<SingleMetricAnomalyDetector> AddAnomalyDetector() { Console.WriteLine(new string('-', 80)); Console.WriteLine($"15. Add an anomaly detector."); var customMetricNamespace = _configuration["customMetricNamespace"]; var customMetricName = _configuration["customMetricName"]; var detector = new SingleMetricAnomalyDetector { MetricName = customMetricName, Namespace = customMetricNamespace, Stat = "Maximum" }; await _cloudWatchWrapper.PutAnomalyDetector(detector); Console.WriteLine($"\tAdded anomaly detector for metric {customMetricName}."); Console.WriteLine(new string('-', 80)); return detector; } /// <summary> /// Describe anomaly detectors. /// </summary> /// <returns>Async task.</returns> private static async Task DescribeAnomalyDetectors() { Console.WriteLine(new string('-', 80)); Console.WriteLine($"16. Describe anomaly detectors in the current account."); var customMetricNamespace = _configuration["customMetricNamespace"]; var customMetricName = _configuration["customMetricName"]; var detectors = await _cloudWatchWrapper.DescribeAnomalyDetectors(customMetricNamespace, customMetricName); for (int i = 0; i < detectors.Count; i++) { var detector = detectors[i]; Console.WriteLine($"\t{i + 1}. {detector.SingleMetricAnomalyDetector.MetricName}, state {detector.StateValue}"); } Console.WriteLine(new string('-', 80)); } /// <summary> /// Fetch and open a metrics image for a CloudWatch metric and namespace. /// </summary> /// <returns>Async task.</returns> private static async Task GetAndOpenMetricImage() { Console.WriteLine(new string('-', 80)); Console.WriteLine("17. Get a metric image from CloudWatch."); Console.WriteLine($"\tGetting Image data for custom metric."); var customMetricNamespace = _configuration["customMetricNamespace"]; var customMetricName = _configuration["customMetricName"]; var memoryStream = await _cloudWatchWrapper.GetTimeSeriesMetricImage(customMetricNamespace, customMetricName, "Maximum", 10); var file = _cloudWatchWrapper.SaveMetricImage(memoryStream, "MetricImages"); ProcessStartInfo info = new ProcessStartInfo(); Console.WriteLine($"\tFile saved as {Path.GetFileName(file)}."); Console.WriteLine($"\tPress enter to open the image."); Console.ReadLine(); info.FileName = Path.Combine("ms-photos://", file); info.UseShellExecute = true; info.CreateNoWindow = true; info.Verb = string.Empty; Process.Start(info); Console.WriteLine(new string('-', 80)); } /// <summary> /// Clean up created resources. /// </summary> /// <param name="metricNamespace">The namespace for metrics.</param> /// <param name="metric">The CloudWatch metric.</param> /// <returns>Async task.</returns> private static async Task CleanupResources() { Console.WriteLine(new string('-', 80)); Console.WriteLine($"18. Clean up resources."); var dashboardName = _configuration["dashboardName"]; if (GetYesNoResponse($"\tDelete dashboard {dashboardName}? (y/n)")) { Console.WriteLine($"\tDeleting dashboard."); var dashboardList = new List<string> { dashboardName }; await _cloudWatchWrapper.DeleteDashboards(dashboardList); } var alarmName = _configuration["exampleAlarmName"]; if (GetYesNoResponse($"\tDelete alarm {alarmName}? (y/n)")) { Console.WriteLine($"\tCleaning up alarms."); var alarms = new List<string> { alarmName }; await _cloudWatchWrapper.DeleteAlarms(alarms); } if (GetYesNoResponse($"\tDelete anomaly detector? (y/n)") && anomalyDetector != null) { Console.WriteLine($"\tCleaning up anomaly detector."); await _cloudWatchWrapper.DeleteAnomalyDetector( anomalyDetector); } Console.WriteLine(new string('-', 80)); } /// <summary> /// Get a yes or no response from the user. /// </summary> /// <param name="question">The question string to print on the console.</param> /// <returns>True if the user responds with a yes.</returns> private static bool GetYesNoResponse(string question) { Console.WriteLine(question); var ynResponse = Console.ReadLine(); var response = ynResponse != null && ynResponse.Equals("y", StringComparison.InvariantCultureIgnoreCase); return response; } }

Métodos envoltorios utilizados por el escenario para CloudWatch las acciones.

/// <summary> /// Wrapper class for Amazon CloudWatch methods. /// </summary> public class CloudWatchWrapper { private readonly IAmazonCloudWatch _amazonCloudWatch; private readonly ILogger<CloudWatchWrapper> _logger; /// <summary> /// Constructor for the CloudWatch wrapper. /// </summary> /// <param name="amazonCloudWatch">The injected CloudWatch client.</param> /// <param name="logger">The injected logger for the wrapper.</param> public CloudWatchWrapper(IAmazonCloudWatch amazonCloudWatch, ILogger<CloudWatchWrapper> logger) { _logger = logger; _amazonCloudWatch = amazonCloudWatch; } /// <summary> /// List metrics available, optionally within a namespace. /// </summary> /// <param name="metricNamespace">Optional CloudWatch namespace to use when listing metrics.</param> /// <param name="filter">Optional dimension filter.</param> /// <param name="metricName">Optional metric name filter.</param> /// <returns>The list of metrics.</returns> public async Task<List<Metric>> ListMetrics(string? metricNamespace = null, DimensionFilter? filter = null, string? metricName = null) { var results = new List<Metric>(); var paginateMetrics = _amazonCloudWatch.Paginators.ListMetrics( new ListMetricsRequest { Namespace = metricNamespace, Dimensions = filter != null ? new List<DimensionFilter> { filter } : null, MetricName = metricName }); // Get the entire list using the paginator. await foreach (var metric in paginateMetrics.Metrics) { results.Add(metric); } return results; } /// <summary> /// Wrapper to get statistics for a specific CloudWatch metric. /// </summary> /// <param name="metricNamespace">The namespace of the metric.</param> /// <param name="metricName">The name of the metric.</param> /// <param name="statistics">The list of statistics to include.</param> /// <param name="dimensions">The list of dimensions to include.</param> /// <param name="days">The number of days in the past to include.</param> /// <param name="period">The period for the data.</param> /// <returns>A list of DataPoint objects for the statistics.</returns> public async Task<List<Datapoint>> GetMetricStatistics(string metricNamespace, string metricName, List<string> statistics, List<Dimension> dimensions, int days, int period) { var metricStatistics = await _amazonCloudWatch.GetMetricStatisticsAsync( new GetMetricStatisticsRequest() { Namespace = metricNamespace, MetricName = metricName, Dimensions = dimensions, Statistics = statistics, StartTimeUtc = DateTime.UtcNow.AddDays(-days), EndTimeUtc = DateTime.UtcNow, Period = period }); return metricStatistics.Datapoints; } /// <summary> /// Wrapper to create or add to a dashboard with metrics. /// </summary> /// <param name="dashboardName">The name for the dashboard.</param> /// <param name="dashboardBody">The metric data in JSON for the dashboard.</param> /// <returns>A list of validation messages for the dashboard.</returns> public async Task<List<DashboardValidationMessage>> PutDashboard(string dashboardName, string dashboardBody) { // Updating a dashboard replaces all contents. // Best practice is to include a text widget indicating this dashboard was created programmatically. var dashboardResponse = await _amazonCloudWatch.PutDashboardAsync( new PutDashboardRequest() { DashboardName = dashboardName, DashboardBody = dashboardBody }); return dashboardResponse.DashboardValidationMessages; } /// <summary> /// Get information on a dashboard. /// </summary> /// <param name="dashboardName">The name of the dashboard.</param> /// <returns>A JSON object with dashboard information.</returns> public async Task<string> GetDashboard(string dashboardName) { var dashboardResponse = await _amazonCloudWatch.GetDashboardAsync( new GetDashboardRequest() { DashboardName = dashboardName }); return dashboardResponse.DashboardBody; } /// <summary> /// Get a list of dashboards. /// </summary> /// <returns>A list of DashboardEntry objects.</returns> public async Task<List<DashboardEntry>> ListDashboards() { var results = new List<DashboardEntry>(); var paginateDashboards = _amazonCloudWatch.Paginators.ListDashboards( new ListDashboardsRequest()); // Get the entire list using the paginator. await foreach (var data in paginateDashboards.DashboardEntries) { results.Add(data); } return results; } /// <summary> /// Wrapper to add metric data to a CloudWatch metric. /// </summary> /// <param name="metricNamespace">The namespace of the metric.</param> /// <param name="metricData">A data object for the metric data.</param> /// <returns>True if successful.</returns> public async Task<bool> PutMetricData(string metricNamespace, List<MetricDatum> metricData) { var putDataResponse = await _amazonCloudWatch.PutMetricDataAsync( new PutMetricDataRequest() { MetricData = metricData, Namespace = metricNamespace, }); return putDataResponse.HttpStatusCode == HttpStatusCode.OK; } /// <summary> /// Get an image for a metric graphed over time. /// </summary> /// <param name="metricNamespace">The namespace of the metric.</param> /// <param name="metric">The name of the metric.</param> /// <param name="stat">The name of the stat to chart.</param> /// <param name="period">The period to use for the chart.</param> /// <returns>A memory stream for the chart image.</returns> public async Task<MemoryStream> GetTimeSeriesMetricImage(string metricNamespace, string metric, string stat, int period) { var metricImageWidget = new { title = "Example Metric Graph", view = "timeSeries", stacked = false, period = period, width = 1400, height = 600, metrics = new List<List<object>> { new() { metricNamespace, metric, new { stat } } } }; var metricImageWidgetString = JsonSerializer.Serialize(metricImageWidget); var imageResponse = await _amazonCloudWatch.GetMetricWidgetImageAsync( new GetMetricWidgetImageRequest() { MetricWidget = metricImageWidgetString }); return imageResponse.MetricWidgetImage; } /// <summary> /// Save a metric image to a file. /// </summary> /// <param name="memoryStream">The MemoryStream for the metric image.</param> /// <param name="metricName">The name of the metric.</param> /// <returns>The path to the file.</returns> public string SaveMetricImage(MemoryStream memoryStream, string metricName) { var metricFileName = $"{metricName}_{DateTime.Now.Ticks}.png"; using var sr = new StreamReader(memoryStream); // Writes the memory stream to a file. File.WriteAllBytes(metricFileName, memoryStream.ToArray()); var filePath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, metricFileName); return filePath; } /// <summary> /// Get data for CloudWatch metrics. /// </summary> /// <param name="minutesOfData">The number of minutes of data to include.</param> /// <param name="useDescendingTime">True to return the data descending by time.</param> /// <param name="endDateUtc">The end date for the data, in UTC.</param> /// <param name="maxDataPoints">The maximum data points to include.</param> /// <param name="dataQueries">Optional data queries to include.</param> /// <returns>A list of the requested metric data.</returns> public async Task<List<MetricDataResult>> GetMetricData(int minutesOfData, bool useDescendingTime, DateTime? endDateUtc = null, int maxDataPoints = 0, List<MetricDataQuery>? dataQueries = null) { var metricData = new List<MetricDataResult>(); // If no end time is provided, use the current time for the end time. endDateUtc ??= DateTime.UtcNow; var timeZoneOffset = TimeZoneInfo.Local.GetUtcOffset(endDateUtc.Value.ToLocalTime()); var startTimeUtc = endDateUtc.Value.AddMinutes(-minutesOfData); // The timezone string should be in the format +0000, so use the timezone offset to format it correctly. var timeZoneString = $"{timeZoneOffset.Hours:D2}{timeZoneOffset.Minutes:D2}"; var paginatedMetricData = _amazonCloudWatch.Paginators.GetMetricData( new GetMetricDataRequest() { StartTimeUtc = startTimeUtc, EndTimeUtc = endDateUtc.Value, LabelOptions = new LabelOptions { Timezone = timeZoneString }, ScanBy = useDescendingTime ? ScanBy.TimestampDescending : ScanBy.TimestampAscending, MaxDatapoints = maxDataPoints, MetricDataQueries = dataQueries, }); await foreach (var data in paginatedMetricData.MetricDataResults) { metricData.Add(data); } return metricData; } /// <summary> /// Add a metric alarm to send an email when the metric passes a threshold. /// </summary> /// <param name="alarmDescription">A description of the alarm.</param> /// <param name="alarmName">The name for the alarm.</param> /// <param name="comparison">The type of comparison to use.</param> /// <param name="metricName">The name of the metric for the alarm.</param> /// <param name="metricNamespace">The namespace of the metric.</param> /// <param name="threshold">The threshold value for the alarm.</param> /// <param name="alarmActions">Optional actions to execute when in an alarm state.</param> /// <returns>True if successful.</returns> public async Task<bool> PutMetricEmailAlarm(string alarmDescription, string alarmName, ComparisonOperator comparison, string metricName, string metricNamespace, double threshold, List<string> alarmActions = null!) { try { var putEmailAlarmResponse = await _amazonCloudWatch.PutMetricAlarmAsync( new PutMetricAlarmRequest() { AlarmActions = alarmActions, AlarmDescription = alarmDescription, AlarmName = alarmName, ComparisonOperator = comparison, Threshold = threshold, Namespace = metricNamespace, MetricName = metricName, EvaluationPeriods = 1, Period = 10, Statistic = new Statistic("Maximum"), DatapointsToAlarm = 1, TreatMissingData = "ignore" }); return putEmailAlarmResponse.HttpStatusCode == HttpStatusCode.OK; } catch (LimitExceededException lex) { _logger.LogError(lex, $"Unable to add alarm {alarmName}. Alarm quota has already been reached."); } return false; } /// <summary> /// Add specific email actions to a list of action strings for a CloudWatch alarm. /// </summary> /// <param name="accountId">The AccountId for the alarm.</param> /// <param name="region">The region for the alarm.</param> /// <param name="emailTopicName">An Amazon Simple Notification Service (SNS) topic for the alarm email.</param> /// <param name="alarmActions">Optional list of existing alarm actions to append to.</param> /// <returns>A list of string actions for an alarm.</returns> public List<string> AddEmailAlarmAction(string accountId, string region, string emailTopicName, List<string>? alarmActions = null) { alarmActions ??= new List<string>(); var snsAlarmAction = $"arn:aws:sns:{region}:{accountId}:{emailTopicName}"; alarmActions.Add(snsAlarmAction); return alarmActions; } /// <summary> /// Describe the current alarms, optionally filtered by state. /// </summary> /// <param name="stateValue">Optional filter for alarm state.</param> /// <returns>The list of alarm data.</returns> public async Task<List<MetricAlarm>> DescribeAlarms(StateValue? stateValue = null) { List<MetricAlarm> alarms = new List<MetricAlarm>(); var paginatedDescribeAlarms = _amazonCloudWatch.Paginators.DescribeAlarms( new DescribeAlarmsRequest() { StateValue = stateValue }); await foreach (var data in paginatedDescribeAlarms.MetricAlarms) { alarms.Add(data); } return alarms; } /// <summary> /// Describe the current alarms for a specific metric. /// </summary> /// <param name="metricNamespace">The namespace of the metric.</param> /// <param name="metricName">The name of the metric.</param> /// <returns>The list of alarm data.</returns> public async Task<List<MetricAlarm>> DescribeAlarmsForMetric(string metricNamespace, string metricName) { var alarmsResult = await _amazonCloudWatch.DescribeAlarmsForMetricAsync( new DescribeAlarmsForMetricRequest() { Namespace = metricNamespace, MetricName = metricName }); return alarmsResult.MetricAlarms; } /// <summary> /// Describe the history of an alarm for a number of days in the past. /// </summary> /// <param name="alarmName">The name of the alarm.</param> /// <param name="historyDays">The number of days in the past.</param> /// <returns>The list of alarm history data.</returns> public async Task<List<AlarmHistoryItem>> DescribeAlarmHistory(string alarmName, int historyDays) { List<AlarmHistoryItem> alarmHistory = new List<AlarmHistoryItem>(); var paginatedAlarmHistory = _amazonCloudWatch.Paginators.DescribeAlarmHistory( new DescribeAlarmHistoryRequest() { AlarmName = alarmName, EndDateUtc = DateTime.UtcNow, HistoryItemType = HistoryItemType.StateUpdate, StartDateUtc = DateTime.UtcNow.AddDays(-historyDays) }); await foreach (var data in paginatedAlarmHistory.AlarmHistoryItems) { alarmHistory.Add(data); } return alarmHistory; } /// <summary> /// Delete a list of alarms from CloudWatch. /// </summary> /// <param name="alarmNames">A list of names of alarms to delete.</param> /// <returns>True if successful.</returns> public async Task<bool> DeleteAlarms(List<string> alarmNames) { var deleteAlarmsResult = await _amazonCloudWatch.DeleteAlarmsAsync( new DeleteAlarmsRequest() { AlarmNames = alarmNames }); return deleteAlarmsResult.HttpStatusCode == HttpStatusCode.OK; } /// <summary> /// Disable the actions for a list of alarms from CloudWatch. /// </summary> /// <param name="alarmNames">A list of names of alarms.</param> /// <returns>True if successful.</returns> public async Task<bool> DisableAlarmActions(List<string> alarmNames) { var disableAlarmActionsResult = await _amazonCloudWatch.DisableAlarmActionsAsync( new DisableAlarmActionsRequest() { AlarmNames = alarmNames }); return disableAlarmActionsResult.HttpStatusCode == HttpStatusCode.OK; } /// <summary> /// Enable the actions for a list of alarms from CloudWatch. /// </summary> /// <param name="alarmNames">A list of names of alarms.</param> /// <returns>True if successful.</returns> public async Task<bool> EnableAlarmActions(List<string> alarmNames) { var enableAlarmActionsResult = await _amazonCloudWatch.EnableAlarmActionsAsync( new EnableAlarmActionsRequest() { AlarmNames = alarmNames }); return enableAlarmActionsResult.HttpStatusCode == HttpStatusCode.OK; } /// <summary> /// Add an anomaly detector for a single metric. /// </summary> /// <param name="anomalyDetector">A single metric anomaly detector.</param> /// <returns>True if successful.</returns> public async Task<bool> PutAnomalyDetector(SingleMetricAnomalyDetector anomalyDetector) { var putAlarmDetectorResult = await _amazonCloudWatch.PutAnomalyDetectorAsync( new PutAnomalyDetectorRequest() { SingleMetricAnomalyDetector = anomalyDetector }); return putAlarmDetectorResult.HttpStatusCode == HttpStatusCode.OK; } /// <summary> /// Describe anomaly detectors for a metric and namespace. /// </summary> /// <param name="metricNamespace">The namespace of the metric.</param> /// <param name="metricName">The metric of the anomaly detectors.</param> /// <returns>The list of detectors.</returns> public async Task<List<AnomalyDetector>> DescribeAnomalyDetectors(string metricNamespace, string metricName) { List<AnomalyDetector> detectors = new List<AnomalyDetector>(); var paginatedDescribeAnomalyDetectors = _amazonCloudWatch.Paginators.DescribeAnomalyDetectors( new DescribeAnomalyDetectorsRequest() { MetricName = metricName, Namespace = metricNamespace }); await foreach (var data in paginatedDescribeAnomalyDetectors.AnomalyDetectors) { detectors.Add(data); } return detectors; } /// <summary> /// Delete a single metric anomaly detector. /// </summary> /// <param name="anomalyDetector">The anomaly detector to delete.</param> /// <returns>True if successful.</returns> public async Task<bool> DeleteAnomalyDetector(SingleMetricAnomalyDetector anomalyDetector) { var deleteAnomalyDetectorResponse = await _amazonCloudWatch.DeleteAnomalyDetectorAsync( new DeleteAnomalyDetectorRequest() { SingleMetricAnomalyDetector = anomalyDetector }); return deleteAnomalyDetectorResponse.HttpStatusCode == HttpStatusCode.OK; } /// <summary> /// Delete a list of CloudWatch dashboards. /// </summary> /// <param name="dashboardNames">List of dashboard names to delete.</param> /// <returns>True if successful.</returns> public async Task<bool> DeleteDashboards(List<string> dashboardNames) { var deleteDashboardsResponse = await _amazonCloudWatch.DeleteDashboardsAsync( new DeleteDashboardsRequest() { DashboardNames = dashboardNames }); return deleteDashboardsResponse.HttpStatusCode == HttpStatusCode.OK; } }