in telemetry/csharp/AwsToolkit.Telemetry.Events.Generator.Core/DefinitionsBuilder.cs [355:576]
private CodeMemberMethod CreateRecordMetricMethodByDataClass(Metric metric)
{
CodeMemberMethod recordMethod = new CodeMemberMethod
{
Attributes = MemberAttributes.Public | MemberAttributes.Static,
Name = $"Record{SanitizeName(metric.name)}",
ReturnType = new CodeTypeReference()
};
if (!string.IsNullOrWhiteSpace(metric.description))
{
recordMethod.Comments.Add(new CodeCommentStatement("Records Telemetry Event:", true));
recordMethod.Comments.Add(new CodeCommentStatement(metric.description, true));
}
// RecordXxx Parameters
var telemetryLogger = new CodeParameterDeclarationExpression("this ITelemetryLogger", "telemetryLogger");
recordMethod.Parameters.Add(telemetryLogger);
recordMethod.Parameters.Add(new CodeParameterDeclarationExpression(SanitizeName(metric.name), "payload"));
recordMethod.Parameters.Add(new CodeParameterDeclarationExpression("Func<MetricDatum, MetricDatum>", "transformDatum = null"));
// Generate method body
var tryStatements = new List<CodeStatement>();
var catchClauses = new List<CodeCatchClause>();
// Create a metrics object from the given payload
// Generate the method body
var metrics = new CodeVariableReferenceExpression("metrics");
var metricsDataField = new CodeFieldReferenceExpression(metrics, "Data");
var payload = new CodeArgumentReferenceExpression("payload");
var transformDatum = new CodeArgumentReferenceExpression("transformDatum");
var datum = new CodeVariableReferenceExpression("datum");
var datumAddData = new CodeMethodReferenceExpression(datum, AddMetadataMethodName);
var datetimeNow = new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(typeof(DateTime)), nameof(DateTime.Now));
// Instantiate metrics
tryStatements.Add(new CodeVariableDeclarationStatement("var", metrics.VariableName, new CodeObjectCreateExpression("Metrics")));
// Set metrics.CreatedOn to (payload.CreatedOn ?? DateTime.Now)
var payloadCreatedOn = new CodeFieldReferenceExpression(payload, "CreatedOn");
var metricsCreatedOn = new CodeFieldReferenceExpression(metrics, "CreatedOn");
var createdOnCond = new CodeConditionStatement();
createdOnCond.Condition = new CodeFieldReferenceExpression(payloadCreatedOn, "HasValue");
createdOnCond.TrueStatements.Add(new CodeAssignStatement(metricsCreatedOn, new CodeFieldReferenceExpression(payloadCreatedOn, "Value")));
createdOnCond.FalseStatements.Add(new CodeAssignStatement(metricsCreatedOn, datetimeNow));
tryStatements.Add(createdOnCond);
// Instantiate a Data list
tryStatements.Add(new CodeAssignStatement(metricsDataField, new CodeObjectCreateExpression($"List<{MetricDatumFullName}>")));
// Instantiate MetricDatum
tryStatements.Add(new CodeSnippetStatement());
tryStatements.Add(new CodeVariableDeclarationStatement("var", datum.VariableName, new CodeObjectCreateExpression(MetricDatumFullName)));
tryStatements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(datum, "MetricName"), new CodePrimitiveExpression(metric.name)));
tryStatements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(datum, "Unit"), GetMetricUnitExpression(metric)));
tryStatements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(datum, "Passive"), new CodeFieldReferenceExpression(payload, "Passive")));
tryStatements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(datum, "TrackPerformance"), new CodeFieldReferenceExpression(payload, "TrackPerformance")));
// Set Datum.Value to (payload.Value ?? 1)
var payloadValue = new CodeFieldReferenceExpression(payload, "Value");
var datumValue = new CodeFieldReferenceExpression(datum, "Value");
var valueCond = new CodeConditionStatement();
valueCond.Condition = new CodeFieldReferenceExpression(payloadValue, "HasValue");
valueCond.TrueStatements.Add(new CodeAssignStatement(datumValue, new CodeFieldReferenceExpression(payloadValue, "Value")));
valueCond.FalseStatements.Add(new CodeAssignStatement(datumValue, new CodePrimitiveExpression(1)));
tryStatements.Add(valueCond);
// Generate: datum.AddMetadata("awsAccount", payload.AwsAccount);
var payloadAwsAccount = new CodeFieldReferenceExpression(payload, "AwsAccount");
tryStatements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(datumAddData,
new CodePrimitiveExpression("awsAccount"), payloadAwsAccount)));
// Generate: datum.AddMetadata("awsRegion", payload.AwsRegion);
var payloadAwsRegion = new CodeFieldReferenceExpression(payload, "AwsRegion");
tryStatements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(datumAddData,
new CodePrimitiveExpression("awsRegion"), payloadAwsRegion)));
// Generate: datum.AddMetadata("reason", payload.Reason);
var payloadReason = new CodeFieldReferenceExpression(payload, "Reason");
tryStatements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(datumAddData,
new CodePrimitiveExpression("reason"), payloadReason)));
// Generate: datum.AddMetadata("reasonDesc", payload.ReasonDescription);
var payloadReasonDescription = new CodeFieldReferenceExpression(payload, "ReasonDescription");
tryStatements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(datumAddData,
new CodePrimitiveExpression("reasonDesc"), payloadReasonDescription)));
// Generate: datum.AddMetadata("source", payload.Source);
var payloadSource = new CodeFieldReferenceExpression(payload, "Source");
tryStatements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(datumAddData,
new CodePrimitiveExpression("source"), payloadSource)));
// Generate: datum.AddMetadata("errorCode", payload.ErrorCode);
var payloadErrorCode = new CodeFieldReferenceExpression(payload, "ErrorCode");
tryStatements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(datumAddData,
new CodePrimitiveExpression("errorCode"), payloadErrorCode)));
// Generate: datum.AddMetadata("causedBy", payload.CausedBy);
var payloadCausedBy = new CodeFieldReferenceExpression(payload, "CausedBy");
tryStatements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(datumAddData,
new CodePrimitiveExpression("causedBy"), payloadCausedBy)));
// Generate: datum.AddMetadata("httpStatusCode", payload.HttpStatusCode);
var payloadHttpStatusCode = new CodeFieldReferenceExpression(payload, "HttpStatusCode");
tryStatements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(datumAddData,
new CodePrimitiveExpression("httpStatusCode"), payloadHttpStatusCode)));
// Generate: datum.AddMetadata("requestId", payload.RequestId);
var payloadRequestId = new CodeFieldReferenceExpression(payload, "RequestId");
tryStatements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(datumAddData,
new CodePrimitiveExpression("requestId"), payloadRequestId)));
// Generate: datum.AddMetadata("requestServiceType", payload.RequestServiceType);
var payloadRequestServiceType = new CodeFieldReferenceExpression(payload, "RequestServiceType");
tryStatements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(datumAddData,
new CodePrimitiveExpression("requestServiceType"), payloadRequestServiceType)));
// Generate: datum.AddMetadata("traceId", payload.TraceId);
var payloadTraceId = new CodeFieldReferenceExpression(payload, "TraceId");
tryStatements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(datumAddData,
new CodePrimitiveExpression("traceId"), payloadTraceId)));
// Generate: datum.AddMetadata("metricId", payload.MetricId);
var payloadMetricId = new CodeFieldReferenceExpression(payload, "MetricId");
tryStatements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(datumAddData,
new CodePrimitiveExpression("metricId"), payloadMetricId)));
// Generate: datum.AddMetadata("parentId", payload.ParentId);
var payloadParentId = new CodeFieldReferenceExpression(payload, "ParentId");
tryStatements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(datumAddData,
new CodePrimitiveExpression("parentId"), payloadParentId)));
// Generate:
// if (payload.Duration.HasValue)
// {
// datum.AddMetadata("duration", payload.Duration.Value);
// }
var payloadDuration= new CodeFieldReferenceExpression(payload, "Duration");
var hasValueDuration = new CodeFieldReferenceExpression(payloadDuration, "HasValue");
var durationMetadata = new CodeMethodInvokeExpression(datumAddData,
new CodePrimitiveExpression("duration"), new CodeFieldReferenceExpression(payloadDuration, "Value"));
tryStatements.Add(new CodeConditionStatement(hasValueDuration, new CodeExpressionStatement(durationMetadata)));
// Generate: datum.AddMetadata("locale", payload.Locale);
var payloadLocale = new CodeFieldReferenceExpression(payload, "Locale");
tryStatements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(datumAddData,
new CodePrimitiveExpression("locale"), payloadLocale)));
// Set MetricDatum Metadata values
metric.metadata?
.Where(metadata => !ImplicitFields.Contains(metadata.type))
.ToList().ForEach(metadata =>
{
tryStatements.Add(new CodeSnippetStatement());
var payloadField = new CodeFieldReferenceExpression(payload, SanitizeName(metadata.type));
if (IsNullable(metadata))
{
// Generate:
// if (payload.foo.HasValue)
// {
// datum.AddMetadata("foo", payload.foo.Value);
// }
var hasValue = new CodeFieldReferenceExpression(payloadField, "HasValue");
var addMetadata = new CodeMethodInvokeExpression(datumAddData,
new CodePrimitiveExpression(metadata.type), new CodeFieldReferenceExpression(payloadField, "Value"));
tryStatements.Add(
new CodeConditionStatement(hasValue, new CodeExpressionStatement(addMetadata)));
}
else
{
// Generate: datum.AddMetadata("foo", payload.foo);
tryStatements.Add(new CodeExpressionStatement (new CodeMethodInvokeExpression(datumAddData,
new CodePrimitiveExpression(metadata.type), payloadField)));
}
});
// Generate: "InvokeTransform function on datum"
// datum = datum.InvokeTransform(transformDatum)
var datumInvoke = new CodeMethodReferenceExpression(datum, InvokeTransformMethodName);
var invokeTransform = new CodeMethodInvokeExpression(datumInvoke, transformDatum);
var assignTransform = new CodeAssignStatement(datum, invokeTransform);
tryStatements.Add(new CodeSnippetStatement());
tryStatements.Add(assignTransform);
// Generate: metrics.Data.Add(datum);
tryStatements.Add(new CodeSnippetStatement());
tryStatements.Add(new CodeExpressionStatement (new CodeMethodInvokeExpression(metricsDataField, "Add", datum)));
// Generate: telemetryLogger.Record(metrics);
tryStatements.Add(new CodeExpressionStatement (new CodeMethodInvokeExpression(new CodeArgumentReferenceExpression("telemetryLogger"), "Record", metrics)));
var catchClause = new CodeCatchClause("e", new CodeTypeReference(typeof(Exception)));
catchClause.Statements.Add(new CodeExpressionStatement(
new CodeMethodInvokeExpression(
new CodeFieldReferenceExpression(new CodeArgumentReferenceExpression("telemetryLogger"), "Logger"),
"Error",
new CodePrimitiveExpression("Error recording telemetry event"),
new CodeArgumentReferenceExpression("e"))
));
// System.Diagnostics.Debug.Assert(false, "Error Recording Telemetry");
catchClause.Statements.Add(new CodeExpressionStatement(
new CodeMethodInvokeExpression(
_debugAssert,
new CodePrimitiveExpression(false),
new CodePrimitiveExpression("Error Recording Telemetry"))
));
catchClauses.Add(catchClause);
recordMethod.Statements.Add(
new CodeTryCatchFinallyStatement(tryStatements.ToArray(), catchClauses.ToArray())
);
return recordMethod;
}