Skip to content

Instantly share code, notes, and snippets.

@justinyoo
Created May 19, 2021 12:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save justinyoo/9679433b6d886897cc09d8bcf1c8b6de to your computer and use it in GitHub Desktop.
Save justinyoo/9679433b6d886897cc09d8bcf1c8b6de to your computer and use it in GitHub Desktop.
Tracing End-to-End Data from Power Apps to Azure Cosmos DB
public async Task<IActionResult> CreateRoutineAsync(
[HttpTrigger(AuthorizationLevel.Function, HttpVerbs.Post, Route = "routines")] HttpRequest req,
ExecutionContext context,
ILogger log)
{
var request = await req.ToRequestMessageAsync<RoutineRequestMessage>().ConfigureAwait(false);
var @interface = request.Interface;
var correlationId = request.CorrelationId;
var spanId = request.SpanId;
var eventId = context.InvocationId;
log.LogData(LogLevel.Information, request,
EventType.RoutineReceived, EventStatusType.Succeeded, eventId,
SpanType.Publisher, SpanStatusType.PublisherInitiated, spanId,
@interface, correlationId);
...
}
public async Task<IActionResult> CreateRoutineAsync(
[HttpTrigger(AuthorizationLevel.Function, HttpVerbs.Post, Route = "routines")] HttpRequest req,
ExecutionContext context,
ILogger log)
{
...
try
{
...
await this._client.CreateTableIfNotExistsAsync(this._settings.GymLog.StorageAccount.Table.TableName).ConfigureAwait(false);
var table = this._client.GetTableClient(this._settings.GymLog.StorageAccount.Table.TableName);
var response = await table.UpsertEntityAsync(entity).ConfigureAwait(false);
...
log.LogData(response.Status.ToLogLevel(), res.Value,
EventType.RoutineCreated, EventStatusType.Succeeded, eventId,
SpanType.Publisher, SpanStatusType.PublisherInProgress, spanId,
@interface, correlationId,
clientRequestId: response.ClientRequestId,
message: response.Status.ToResponseMessage(res));
}
catch (Exception ex)
{
...
log.LogData(LogLevel.Error, res.Value,
EventType.RoutineNotCreated, EventStatusType.Failed, eventId,
SpanType.Publisher, SpanStatusType.PublisherInProgress, spanId,
@interface, correlationId,
ex: ex,
message: ex.Message);
}
...
}
public async Task<IActionResult> PublishRoutineAsync(
[HttpTrigger(AuthorizationLevel.Function, HttpVerbs.Post, Route = "routines/{routineId}/publish")] HttpRequest req,
Guid routineId,
ExecutionContext context,
[ServiceBus(GymLogTopicKey)] IAsyncCollector<ServiceBusMessage> collector,
ILogger log)
{
var request = await req.ToRequestMessageAsync<PublishRequestMessage>().ConfigureAwait(false);
var @interface = request.Interface;
var correlationId = request.CorrelationId;
var spanId = request.SpanId;
var eventId = context.InvocationId;
try
{
...
var messageId = Guid.NewGuid();
var subSpanId = Guid.NewGuid();
var timestamp = DateTimeOffset.UtcNow;
var message = (RoutineQueueMessage)(PublishResponseMessage)res.Value;
var msg = new ServiceBusMessage(message.ToJson())
{
CorrelationId = correlationId.ToString(),
MessageId = messageId.ToString(),
ContentType = ContentTypes.ApplicationJson,
};
msg.ApplicationProperties.Add("pubSpanId", spanId);
msg.ApplicationProperties.Add("subSpanId", subSpanId);
msg.ApplicationProperties.Add("interface", @interface.ToString());
msg.ApplicationProperties.Add("timestamp", timestamp.ToString(CultureInfo.InvariantCulture));
await collector.AddAsync(msg).ConfigureAwait(false);
log.LogData(LogLevel.Information, msg,
EventType.MessagePublished, EventStatusType.Succeeded, eventId,
SpanType.Publisher, SpanStatusType.PublisherInProgress, spanId,
@interface, correlationId,
messageId: messageId.ToString(),
message: EventType.MessagePublished.ToDisplayName());
...
}
catch (Exception ex)
{
...
}
...
}
public async Task IngestAsync(
[ServiceBusTrigger(GymLogTopicKey, GymLogSubscriptionKey)] ServiceBusReceivedMessage msg,
ExecutionContext context,
ILogger log)
{
...
var @interface = Enum.Parse<InterfaceType>(msg.ApplicationProperties["interface"] as string, ignoreCase: true);
var correlationId = Guid.Parse(msg.CorrelationId);
var spanId = (Guid)msg.ApplicationProperties["subSpanId"];
var messageId = Guid.Parse(msg.MessageId);
var eventId = context.InvocationId;
log.LogData(LogLevel.Information, message,
EventType.MessageReceived, EventStatusType.Succeeded, eventId,
SpanType.Subscriber, SpanStatusType.SubscriberInitiated, spanId,
@interface, correlationId);
...
}
public async Task IngestAsync(
[ServiceBusTrigger(GymLogTopicKey, GymLogSubscriptionKey)] ServiceBusReceivedMessage msg,
ExecutionContext context,
ILogger log)
{
...
try
{
...
var response = await container.UpsertItemAsync<RoutineRecordItem>(record, new PartitionKey(record.ItemType.ToString())).ConfigureAwait(false);
...
log.LogData(LogLevel.Information, message,
EventType.MessageProcessed, EventStatusType.Succeeded, eventId,
SpanType.Subscriber, SpanStatusType.SubscriberCompleted, spanId,
@interface, correlationId,
recordId: record.EntityId.ToString(),
message: response.StatusCode.ToMessageEventType().ToDisplayName());
}
catch (Exception ex)
{
log.LogData(LogLevel.Error, message,
EventType.MessageNotProcessed, EventStatusType.Failed, eventId,
SpanType.Subscriber, SpanStatusType.SubscriberCompleted, spanId,
@interface, correlationId,
ex: ex,
message: ex.Message);
...
}
}
let correlationId = "5380912f-9c8f-466c-a78c-e5fe194bd21f";
traces
| sort by timestamp desc
| where customDimensions.prop__correlationId == correlationId
| project Timestamp = timestamp
, LogLevel = customDimensions.prop__logLevel
, CorrelationId = tostring(customDimensions.prop__correlationId)
, Interface = customDimensions.prop__interfaceType
, SpanType = customDimensions.prop__spanType
, SpanStatus = customDimensions.prop__spanStatus
, SpanId = tostring(customDimensions.prop__spanId)
, EventType = customDimensions.prop__eventType
, EventStatus = customDimensions.prop__eventStatus
, EventId = tostring(customDimensions.prop__eventId)
, EntityType = customDimensions.prop__entityType
, ClientRequestId = customDimensions.prop__clientRequestId
, MessageId = customDimensions.prop__messageId
, RecordId = customDimensions.prop__recordId
| project Timestamp
, CorrelationId
, SpanType
, SpanStatus
, EventType
, EventStatus
, EntityType
, MessageId
, RecordId
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment