private static void RecordReservedAndReleaseCapacity(
            IAudit auditClient,
            int numberOfEvents,
            int numberOfThreads,
            string eventHubsTopic,
            string eventHubsHost,
            AppConfigMeterData meterData,
            AppConfigReservedAndReleaseCapacityData data)
        {
            var reservedCapacityDestination = new AuditClientReservedCapacityMetricsDestination(auditClient);

            var groupId        = Guid.NewGuid();
            var subscriptionId = meterData.SubscriptionId;
            var resourceId     = meterData.ResourceId;
            var meter          = meterData.Meter;

            Log.Information(
                "Sending {NumberOfEvents} {EventKind} events ({NumberOfThreads} threads) in GroupId {GroupId} to the {EventHubsTopic} topic on EventHubs {EventHubsHost}",
                numberOfEvents,
                ConsumptionKind.ReserveAndReleaseCapacity,
                numberOfThreads,
                groupId,
                eventHubsTopic,
                eventHubsHost);

            var reservedCapacity = new ReservedCapacityMetrics(reservedCapacityDestination);

            using (Operation.Time(
                       "Sending {NumberOfEvents} {EventKind} events ({NumberOfThreads} threads) in GroupId {GroupId} to the {EventHubsTopic} topic on EventHubs {EventHubsHost}",
                       numberOfEvents,
                       ConsumptionKind.ReserveAndReleaseCapacity,
                       numberOfThreads,
                       groupId,
                       eventHubsTopic,
                       eventHubsHost))
            {
                Enumerable
                .Range(0, numberOfEvents)
                .AsParallel()
                .WithDegreeOfParallelism(degreeOfParallelism: numberOfThreads)
                .WithExecutionMode(ParallelExecutionMode.ForceParallelism)
                .Select(eventNumber =>
                {
                    var contextReservedCapacity = reservedCapacity
                                                  .ForInternalContext("GroupId", $"{groupId}")
                                                  .ForInternalContext("EventNumber", $"{eventNumber}");

                    contextReservedCapacity
                    .Increase(
                        subscriptionId: subscriptionId,
                        resourceId: resourceId,
                        meter: meter,
                        amount: data.CapacityAmount,
                        dateTime: data.ReservedDateTime);

                    contextReservedCapacity
                    .Decrease(
                        subscriptionId: subscriptionId,
                        resourceId: resourceId,
                        meter: meter,
                        amount: data.CapacityAmount,
                        dateTime: data.ReservedDateTime);

                    return(eventNumber);
                })
                .ToArray();
            }
        }
        private static void RecordConsumedAmount(
            IAudit auditClient,
            int numberOfEvents,
            int numberOfThreads,
            string eventHubsTopic,
            string eventHubsHost,
            AppConfigMeterData meterData,
            AppConfigConsumedAmountData consumedAmountData)
        {
            var auditConsumptionDestination = new AuditClientConsumptionMetricsDestination(auditClient);

            var groupId        = Guid.NewGuid();
            var subscriptionId = meterData.SubscriptionId;
            var resourceId     = meterData.ResourceId;
            var meter          = meterData.Meter;
            var resourceType   = consumedAmountData.ResourceType;
            var resourceName   = consumedAmountData.ResourceName;

            Log.Information(
                "Sending {NumberOfEvents} {EventKind} events ({NumberOfThreads} threads) in GroupId {GroupId} to the {EventHubsTopic} topic on EventHubs {EventHubsHost}",
                numberOfEvents,
                ConsumptionKind.ConsumedAmount,
                numberOfThreads,
                groupId,
                eventHubsTopic,
                eventHubsHost);

            var consumptionClient = new ConsumptionMetrics(auditConsumptionDestination);

            using (Operation.Time(
                       "Sending {NumberOfEvents} {EventKind} events ({NumberOfThreads} threads) in GroupId {GroupId} to the {EventHubsTopic} topic on EventHubs {EventHubsHost}",
                       numberOfEvents,
                       ConsumptionKind.ConsumedAmount,
                       numberOfThreads,
                       groupId,
                       eventHubsTopic,
                       eventHubsHost))
            {
                Enumerable
                .Range(0, numberOfEvents)
                .AsParallel()
                .WithDegreeOfParallelism(degreeOfParallelism: numberOfThreads)
                .WithExecutionMode(ParallelExecutionMode.ForceParallelism)
                .Select(eventNumber =>
                {
                    consumptionClient
                    .ForInternalContext("GroupId", $"{groupId}")
                    .ForInternalContext("EventNumber", $"{eventNumber}")
                    .ForSubscriptionOwnerContext("Resource Type", resourceType)
                    .ForSubscriptionOwnerContext("Resource Name", resourceName)
                    .Record(
                        subscriptionId: subscriptionId,
                        resourceId: resourceId,
                        meter: meter,
                        amount: consumedAmountData.Amount,
                        consumedDateTime: consumedAmountData.ConsumedDateTime,
                        reason: consumedAmountData.Reason);

                    return(eventNumber);
                })
                .ToArray();
            }
        }