public void SetUp() { _configuration = Mock.Create <IConfiguration>(); var configurationService = Mock.Create <IConfigurationService>(); Mock.Arrange(() => configurationService.Configuration).Returns(_configuration); _databaseService = new DatabaseService(Mock.Create <ICacheStatsReporter>()); _errorService = new ErrorService(configurationService); _distributedTracePayloadHandler = Mock.Create <IDistributedTracePayloadHandler>(); _attribDefSvc = new AttributeDefinitionService((f) => new AttributeDefinitions(f)); _transaction = new Transaction(_configuration, Mock.Create <ITransactionName>(), Mock.Create <ITimer>(), DateTime.UtcNow, Mock.Create <ICallStackManager>(), _databaseService, Priority, Mock.Create <IDatabaseStatementParser>(), _distributedTracePayloadHandler, _errorService, _attribDefs); _publishedEvent = null; _eventSubscription = new EventSubscription <TransactionFinalizedEvent>(e => _publishedEvent = e); _wrapperToken = new object(); }
private void OnTransactionFinalized(TransactionFinalizedEvent eventData) { var internalTransaction = eventData.Transaction; // When a transaction gets finalized it means it never ended cleanly, so we should try to estimate when it ended based on its last finished segment var immutableTransaction = internalTransaction.ConvertToImmutableTransaction(); var lastStartedSegment = TryGetLastStartedSegment(immutableTransaction); var lastFinishedSegment = TryGetLastFinishedSegment(immutableTransaction); var estimatedDuration = GetEstimatedTransactionDuration(internalTransaction, lastStartedSegment, lastFinishedSegment); var finishedTransaction = false; try { internalTransaction.ForceChangeDuration(estimatedDuration); // Then we should mark the transaction as cleanly finished so it won't get finalized again finishedTransaction = Finish(internalTransaction); if (finishedTransaction) { // Then we send it off to be transformed as with normal transactions _transactionTransformer.Transform(internalTransaction); } } finally { if (finishedTransaction) { // Finally, we announce the event to our agent health reporter var transactionMetricName = _transactionMetricNameMaker.GetTransactionMetricName(immutableTransaction.TransactionName); var lastFinishedSegmentName = lastFinishedSegment != null ? lastFinishedSegment.GetTransactionTraceName() : "<unknown>"; var lastStartedSegmentName = lastStartedSegment != null ? lastStartedSegment.GetTransactionTraceName() : "<unknown>"; _agentHealthReporter.ReportTransactionGarbageCollected(transactionMetricName, lastStartedSegmentName, lastFinishedSegmentName); } } }
public void TransactionFinalizedEvent_IsNotPublishedASecondTime_IfBuilderGoesOutOfScopeAgain() { Assert.NotNull(_transaction); _transaction = null; GC.Collect(); GC.WaitForFullGCComplete(); GC.WaitForPendingFinalizers(); Assert.NotNull(_publishedEvent); // The builder is now pinned to the event, but we can unpin it by unpinning the event _publishedEvent = null; GC.Collect(); GC.WaitForFullGCComplete(); GC.WaitForPendingFinalizers(); Assert.Null(_publishedEvent); }