Skip to content

Commit e5bf022

Browse files
authored
Merge pull request #48 from rayabagi/feature/emf-high-resolution
Add support for high-resolution metrics in EMF
2 parents 454772d + ef3fe75 commit e5bf022

File tree

29 files changed

+278
-94
lines changed

29 files changed

+278
-94
lines changed

README.md

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@ using (var logger = new MetricsLogger()) {
3636
var dimensionSet = new DimensionSet();
3737
dimensionSet.AddDimension("Service", "aggregator");
3838
logger.SetDimensions(dimensionSet);
39-
logger.PutMetric("ProcessingLatency", 100, Unit.MILLISECONDS);
39+
logger.PutMetric("ProcessingLatency", 100, Unit.MILLISECONDS,StorageResolution.STANDARD);
40+
logger.PutMetric("Memory.HeapUsed", "1600424.0", Unit.BYTES, StorageResolution.HIGH);
4041
logger.PutProperty("RequestId", "422b1569-16f6-4a03-b8f0-fe3fd9b100f8");
42+
4143
}
4244
```
4345

@@ -66,6 +68,7 @@ using (var logger = new MetricsLogger()) {
6668
dimensionSet.AddDimension("Service", "aggregator");
6769
logger.SetDimensions(dimensionSet);
6870
logger.PutMetric("ProcessingLatency", 100, Unit.MILLISECONDS);
71+
logger.PutMetric("Memory.HeapUsed", "1600424.0", Unit.BYTES, StorageResolution.HIGH);
6972
logger.PutProperty("RequestId", "422b1569-16f6-4a03-b8f0-fe3fd9b100f8");
7073
}
7174

@@ -155,19 +158,28 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
155158

156159
### MetricsLogger
157160

158-
The `MetricsLogger` is the interface you will use to publish embedded metrics.
161+
The `MetricsLogger` is the interface you will use to publish embedded metrics.
159162

160-
- MetricsLogger **PutMetric**(string key, double value, Unit unit)
161163
- MetricsLogger **PutMetric**(string key, double value)
164+
- MetricsLogger **PutMetric**(string key, double value, Unit unit)
165+
- MetricsLogger **PutMetric**(string key, double value, StorageResolution storageResolution)
166+
- MetricsLogger **PutMetric**(string key, double value, Unit unit, StorageResolution storageResolution)
162167

163-
Adds a new metric to the current logger context. Multiple metrics using the same key will be appended to an array of values. The Embedded Metric Format supports a maxumum of 100 metrics per key.
168+
Adds a new metric to the current logger context. Multiple metrics using the same key will be appended to an array of values. Multiple metrics cannot have the same key but different storage resolutions. Same metric cannot have different storage resolutions otherwise a `InvalidMetricException` will be thrown. The Embedded Metric Format supports a maxumum of 100 metrics per key.
164169

165170
Metrics must meet CloudWatch Metrics requirements, otherwise a `InvalidMetricException` will be thrown. See [MetricDatum](https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_MetricDatum.html) for valid values.
166171

172+
##### Storage Resolution.
173+
An OPTIONAL value representing the storage resolution for the corresponding metric. Setting this to `High` specifies this metric as a high-resolution metric, so that CloudWatch stores the metric with sub-minute resolution down to one second. Setting this to `Standard` specifies this metric as a standard-resolution metric, which CloudWatch stores at 1-minute resolution. If a value is not provided, then a default value of `Standard` is assumed. See [Cloud Watch High-Resolution metrics](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/publishingMetrics.html#high-resolution-metrics)
174+
167175
Example:
168176

169177
```c#
178+
// Standard Resolution Example
170179
metrics.PutMetric("ProcessingLatency", 101, Unit.MILLISECONDS);
180+
181+
// High Resolution Example
182+
logger.PutMetric("Memory.HeapUsed", "1600424.0", Unit.BYTES, StorageResolution.HIGH);
171183
```
172184

173185
- MetricsLogger **PutProperty**(string key, object value)

examples/Amazon.CloudWatch.EMF.Examples.ConsoleApp/Program.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ static void Main(string[] args)
3838
}
3939

4040
logger.LogInformation("Shutting down");
41-
4241
environment.Sink.Shutdown().Wait(TimeSpan.FromSeconds(120));
4342
}
4443

@@ -50,9 +49,14 @@ private static void EmitMetrics(ILogger logger, IMetricsLogger metrics)
5049
dimensionSet.AddDimension("Region", "us-west-2");
5150
metrics.SetDimensions(dimensionSet);
5251

52+
// Standard Resolutions
5353
metrics.PutMetric("ProcessingLatency", 101, Unit.MILLISECONDS);
5454
metrics.PutMetric("ProcessingLatency", 100, Unit.MILLISECONDS);
5555
metrics.PutMetric("ProcessingLatency", 99, Unit.MILLISECONDS);
56+
57+
// High Resolution
58+
metrics.PutMetric("Memory.HeapUsed", GC.GetTotalMemory(false), Unit.BYTES, StorageResolution.HIGH);
59+
5660
metrics.PutMetric("Count", 3, Unit.COUNT);
5761
metrics.PutProperty("AccountId", "123456789");
5862
metrics.PutProperty("RequestId", "422b1569-16f6-4a03-b8f0-fe3fd9b100f8");

examples/Amazon.CloudWatch.EMF.Examples.Lambda/Function.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using Amazon.CloudWatch.EMF.Logger;
55
using Amazon.CloudWatch.EMF.Model;
66
using Amazon.Lambda.Core;
7+
using System.Text;
78

89
// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
910
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
@@ -32,6 +33,7 @@ public string FunctionHandler(string input, ILambdaContext context)
3233
logger.PutMetric("ProcessingLatency", 100, Unit.MILLISECONDS);
3334
logger.PutMetric("ProcessingLatency", 99, Unit.MILLISECONDS);
3435
logger.PutMetric("Count", 3, Unit.COUNT);
36+
logger.PutMetric("InputPayloadSize", ASCIIEncoding.ASCII.GetByteCount(input), Unit.BYTES, StorageResolution.HIGH);
3537
logger.PutProperty("AccountId", "123456789");
3638
logger.PutProperty("RequestId", "422b1569-16f6-4a03-b8f0-fe3fd9b100f8");
3739
logger.PutProperty("DeviceId", "61270781-c6ac-46f1-baf7-22c808af8162");

examples/Amazon.CloudWatch.EMF.Examples.Web/Controllers/WeatherForecastController.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public class WeatherForecastController : ControllerBase
2323
private readonly IMetricsLogger _metrics;
2424

2525
public WeatherForecastController(
26-
ILogger<WeatherForecastController> logger,
26+
ILogger<WeatherForecastController> logger,
2727
IMetricsLogger metrics)
2828
{
2929
_logger = logger;
@@ -36,8 +36,10 @@ public IEnumerable<WeatherForecast> Get()
3636
Thread.Sleep(100);
3737
var rng = new Random();
3838
var temperature = rng.Next(-20, 55);
39+
var WindSpeed = rng.Next(10, 100);
3940

4041
_metrics.PutMetric("Temperature", temperature, Unit.NONE);
42+
_metrics.PutMetric("WindSpeed", WindSpeed, Unit.NONE, StorageResolution.HIGH);
4143

4244
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
4345
{

examples/Amazon.CloudWatch.EMF.Examples.Web/Startup.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace Amazon.CloudWatch.EMF.Web
99
public class Startup
1010
{
1111
public Startup(
12-
IConfiguration configuration,
12+
IConfiguration configuration,
1313
IHostEnvironment hostEnv)
1414
{
1515
Configuration = configuration;
@@ -19,10 +19,10 @@ public Startup(
1919
ServiceName = "WeatherApp",
2020
LogGroupName = "/Canary/Dotnet/CloudWatchAgent/Metrics",
2121
EnvironmentOverride = hostEnv.IsDevelopment()
22-
? EMF.Environment.Environments.Local
23-
// Setting this to unknown will cause the SDK to attempt to
24-
// detect the environment. If you know the compute environment
25-
// you will be running on, then you can set this yourself.
22+
? EMF.Environment.Environments.Local
23+
// Setting this to unknown will cause the SDK to attempt to
24+
// detect the environment. If you know the compute environment
25+
// you will be running on, then you can set this yourself.
2626
: EMF.Environment.Environments.Unknown
2727
};
2828
}

src/Amazon.CloudWatch.EMF/Config/ConfigurationKeys.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ namespace Amazon.CloudWatch.EMF.Config
22
{
33
public class ConfigurationKeys
44
{
5-
public const string ENV_VAR_PREFIX = "AWS_EMF";
6-
public const string SERVICE_NAME = "SERVICE_NAME";
7-
public const string SERVICE_TYPE = "SERVICE_TYPE";
8-
public const string LOG_GROUP_NAME = "LOG_GROUP_NAME";
9-
public const string LOG_STREAM_NAME = "LOG_STREAM_NAME";
10-
public const string AGENT_ENDPOINT = "AGENT_ENDPOINT";
11-
public const string AGENT_BUFFER_SIZE = "AGENT_BUFFER_SIZE";
12-
public const string ENVIRONMENT_OVERRIDE = "ENVIRONMENT";
5+
public const string EnvVarPrefix = "AWS_EMF";
6+
public const string ServiceName = "SERVICE_NAME";
7+
public const string ServiceType = "SERVICE_TYPE";
8+
public const string LogGroupName = "LOG_GROUP_NAME";
9+
public const string LogStreamName = "LOG_STREAM_NAME";
10+
public const string AgentEndpoint = "AGENT_ENDPOINT";
11+
public const string AgentBufferSize = "AGENT_BUFFER_SIZE";
12+
public const string EnvironmentOverride = "ENVIRONMENT";
1313
}
1414
}

src/Amazon.CloudWatch.EMF/Config/EnvironmentConfigurationProvider.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,16 @@ public static IConfiguration Config
1616
get
1717
{
1818
var bufferSize = Int32.TryParse(
19-
GetEnvVar(ConfigurationKeys.AGENT_BUFFER_SIZE), out var parsedBufferSize)
19+
GetEnvVar(ConfigurationKeys.AgentBufferSize), out var parsedBufferSize)
2020
? parsedBufferSize
2121
: Configuration.DEFAULT_AGENT_BUFFER_SIZE;
2222

2323
return _config ??= new Configuration(
24-
GetEnvVar(ConfigurationKeys.SERVICE_NAME),
25-
GetEnvVar(ConfigurationKeys.SERVICE_TYPE),
26-
GetEnvVar(ConfigurationKeys.LOG_GROUP_NAME),
27-
GetEnvVar(ConfigurationKeys.LOG_STREAM_NAME),
28-
GetEnvVar(ConfigurationKeys.AGENT_ENDPOINT),
24+
GetEnvVar(ConfigurationKeys.ServiceName),
25+
GetEnvVar(ConfigurationKeys.ServiceType),
26+
GetEnvVar(ConfigurationKeys.LogGroupName),
27+
GetEnvVar(ConfigurationKeys.LogStreamName),
28+
GetEnvVar(ConfigurationKeys.AgentEndpoint),
2929
bufferSize,
3030
GetEnvironmentOverride());
3131
}
@@ -34,7 +34,7 @@ public static IConfiguration Config
3434

3535
private static Environments GetEnvironmentOverride()
3636
{
37-
var environmentName = GetEnvVar(ConfigurationKeys.ENVIRONMENT_OVERRIDE);
37+
var environmentName = GetEnvVar(ConfigurationKeys.EnvironmentOverride);
3838
if (string.IsNullOrEmpty(environmentName))
3939
{
4040
return Environments.Unknown;
@@ -52,7 +52,7 @@ private static Environments GetEnvironmentOverride()
5252

5353
private static string GetEnvVar(string key)
5454
{
55-
var name = string.Join(string.Empty, ConfigurationKeys.ENV_VAR_PREFIX, "_", key);
55+
var name = string.Join(string.Empty, ConfigurationKeys.EnvVarPrefix, "_", key);
5656
return EnvUtils.GetEnv(name);
5757
}
5858
}

src/Amazon.CloudWatch.EMF/Constants.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@ namespace Amazon.CloudWatch.EMF
22
{
33
public class Constants
44
{
5-
public const int MAX_DIMENSION_SET_SIZE = 30;
6-
public const int MAX_DIMENSION_NAME_LENGTH = 250;
7-
public const int MAX_DIMENSION_VALUE_LENGTH = 1024;
8-
public const int MAX_METRIC_NAME_LENGTH = 1024;
9-
public const int MAX_NAMESPACE_LENGTH = 256;
10-
public const string VALID_NAMESPACE_REGEX = "^[a-zA-Z0-9._#:/-]+$";
5+
public const int MaxDimensionSetSize = 30;
6+
public const int MaxDimensionNameLength = 250;
7+
public const int MaxDimensionValueLength = 1024;
8+
public const int MaxMetricNameLength = 1024;
9+
public const int MaxNamespaceLength = 256;
10+
public const string ValidNamespaceRegex = "^[a-zA-Z0-9._#:/-]+$";
1111

12-
public const int DEFAULT_AGENT_PORT = 25888;
12+
public const int DefaultAgentPort = 25888;
1313

14-
public const string UNKNOWN = "Unknown";
14+
public const string Unknown = "Unknown";
1515

16-
public const int MAX_METRICS_PER_EVENT = 100;
16+
public const int MaxMetricsPerEvent = 100;
1717

18-
public const string DEFAULT_NAMESPACE = "aws-embedded-metrics";
18+
public const string DefaultNamespace = "aws-embedded-metrics";
1919
}
2020
}

src/Amazon.CloudWatch.EMF/Environment/AgentBasedEnvironment.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ protected AgentBasedEnvironment(IConfiguration configuration, ILoggerFactory log
1818
_loggerFactory = loggerFactory;
1919
}
2020

21-
public virtual string Name => !string.IsNullOrEmpty(_configuration.ServiceName) ? _configuration.ServiceName : Constants.UNKNOWN;
21+
public virtual string Name => !string.IsNullOrEmpty(_configuration.ServiceName) ? _configuration.ServiceName : Constants.Unknown;
2222

23-
public virtual string Type => !string.IsNullOrEmpty(_configuration.ServiceType) ? _configuration.ServiceType : Constants.UNKNOWN;
23+
public virtual string Type => !string.IsNullOrEmpty(_configuration.ServiceType) ? _configuration.ServiceType : Constants.Unknown;
2424

2525
public virtual string LogGroupName => !string.IsNullOrEmpty(_configuration.LogGroupName) ? _configuration.LogGroupName : Name + "_metrics";
2626

src/Amazon.CloudWatch.EMF/Environment/EC2Environment.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public override string Type
103103
return CFN_EC2_TYPE;
104104
}
105105

106-
return Constants.UNKNOWN;
106+
return Constants.Unknown;
107107
}
108108
}
109109

0 commit comments

Comments
 (0)