public void GetErrorEvent_InTransaction_IfStatusCodeIs404_ContainsCorrectAttributes() { var transaction = BuildTestTransaction(statusCode: 404, uri: "http://www.newrelic.com/test?param=value", isSynthetics: false, isCAT: false, referrerUri: "http://referrer.uri"); var immutableTransaction = transaction.ConvertToImmutableTransaction(); var errorData = transaction.TransactionMetadata.TransactionErrorState.ErrorData; var transactionMetricName = _transactionMetricNameMaker.GetTransactionMetricName(immutableTransaction.TransactionName); var txStats = new TransactionMetricStatsCollection(transactionMetricName); var attributes = _transactionAttributeMaker.GetAttributes(immutableTransaction, transactionMetricName, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(15), txStats); var errorEvent = _errorEventMaker.GetErrorEvent(immutableTransaction, attributes); var intrinsicAttributes = errorEvent.IntrinsicAttributes().Keys.ToArray(); var agentAttributes = errorEvent.AgentAttributes().Keys.ToArray(); var userAttributes = errorEvent.UserAttributes().Keys.ToArray(); NrAssert.Multiple( () => Assert.AreEqual(false, errorEvent.IsSynthetics), () => Assert.AreEqual(7, agentAttributes.Length), () => Assert.AreEqual(7, intrinsicAttributes.Length), () => Assert.AreEqual(0, userAttributes.Length), () => Assert.Contains("queue_wait_time_ms", agentAttributes), () => Assert.Contains("response.status", agentAttributes), () => Assert.Contains("http.statusCode", agentAttributes), () => Assert.Contains("original_url", agentAttributes), () => Assert.Contains("request.uri", agentAttributes), () => Assert.Contains("request.referer", agentAttributes), () => Assert.Contains("host.displayName", agentAttributes), () => Assert.Contains("duration", intrinsicAttributes), () => Assert.Contains("error.class", intrinsicAttributes), () => Assert.Contains("error.message", intrinsicAttributes), () => Assert.Contains("queueDuration", intrinsicAttributes), () => Assert.Contains("transactionName", intrinsicAttributes), () => Assert.Contains("timestamp", intrinsicAttributes), () => Assert.Contains("type", intrinsicAttributes) ); }
private void Transform(ImmutableTransaction immutableTransaction, TransactionMetricName transactionMetricName) { if (!immutableTransaction.Segments.Any()) { throw new ArgumentException("Transaction does not have any segments"); } FinishSegments(immutableTransaction.Segments); TryGenerateExplainPlans(immutableTransaction.Segments); var totalTime = GetTotalExclusiveTime(immutableTransaction.Segments); var transactionApdexMetricName = MetricNames.GetTransactionApdex(transactionMetricName); var apdexT = GetApdexT(immutableTransaction, transactionMetricName.PrefixedName); var txStats = new TransactionMetricStatsCollection(transactionMetricName); GenerateAndCollectSqlTrace(immutableTransaction, transactionMetricName, txStats); GenerateAndCollectMetrics(immutableTransaction, apdexT, transactionApdexMetricName, totalTime, txStats); // defer the creation of attributes until something asks for them. Func <IAttributeValueCollection> attributes = () => _transactionAttributeMaker.GetAttributes(immutableTransaction, transactionMetricName, apdexT, totalTime, txStats); attributes = attributes.Memoize(); // Must generate errors first so other wire models get attribute updates if (immutableTransaction.TransactionMetadata.ReadOnlyTransactionErrorState.HasError) { GenerateAndCollectErrorEventTracesAndEvents(immutableTransaction, attributes.Invoke(), transactionMetricName); } GenerateAndCollectTransactionEvent(immutableTransaction, attributes); GenerateAndCollectTransactionTrace(immutableTransaction, transactionMetricName, attributes); GenerateAndCollectSpanEvents(immutableTransaction, transactionMetricName.PrefixedName, attributes); }
public void GetSpanEvent_ReturnsSpanEventPerSegment_ValidateCount() { // ARRANGE var segments = new List <Segment>() { _baseGenericSegment.CreateSimilar(TimeSpan.FromMilliseconds(1), TimeSpan.FromMilliseconds(5), new List <KeyValuePair <string, object> >()), _childGenericSegment.CreateSimilar(TimeSpan.FromMilliseconds(1), TimeSpan.FromMilliseconds(5), new List <KeyValuePair <string, object> >()) }; var immutableTransaction = BuildTestTransaction(segments, sampled: true, hasIncomingPayload: false); var transactionMetricName = _transactionMetricNameMaker.GetTransactionMetricName(immutableTransaction.TransactionName); var metricStatsCollection = new TransactionMetricStatsCollection(transactionMetricName); var transactionAttribs = _transactionAttribMaker.GetAttributes(immutableTransaction, transactionMetricName, TimeSpan.FromSeconds(1), immutableTransaction.Duration, metricStatsCollection); // ACT var spanEvents = _spanEventMaker.GetSpanEvents(immutableTransaction, TransactionName, transactionAttribs); // ASSERT // +1 is for the faux root segment. Assert.AreEqual(segments.Count + 1, spanEvents.Count()); }
public void Test(TestCase testCase) { Mock.Arrange(() => _configuration.ApplicationNames).Returns(new[] { testCase.AppName }); // ConvertToImmutableTransaction a transaction for the test data _transaction = GetTransactionBuilderFor(_configuration, testCase); // Simulate external requests as dictated by the test data var namePriority = 10; var expectedAndActualOutboundRequestPayloads = new Dictionary <CrossApplicationRequestData, CrossApplicationRequestData>(); testCase.OutboundRequests?.ForEach(request => { var transactionName = GetTransactionNameFromString(request.OutboundTxnName); _transaction.CandidateTransactionName.TrySet(transactionName, (TransactionNamePriority)namePriority++); var outboundHeaders = _agent.CurrentTransaction.GetRequestMetadata().ToDictionary(); var actualOutboundPayload = _catHeaderHandler.TryDecodeInboundRequestHeaders(outboundHeaders, GetHeaderValue); var requestData = new CrossApplicationRequestData( (string)request.ExpectedOutboundPayload[0], (bool)request.ExpectedOutboundPayload[1], (string)request.ExpectedOutboundPayload[2], (string)request.ExpectedOutboundPayload[3] ); expectedAndActualOutboundRequestPayloads.Add(requestData, actualOutboundPayload); _transaction.TransactionMetadata.MarkHasCatResponseHeaders(); List <string> GetHeaderValue(Dictionary <string, string> headers, string key) { var headerValues = new List <string>(); foreach (var item in headers) { if (item.Key.Equals(key, StringComparison.OrdinalIgnoreCase)) { headerValues.Add(item.Value); } } return(headerValues); } }); // Simulate the transaction ending (this logic is normally performed by Agent.EndTransaction) _transaction.CandidateTransactionName.TrySet(GetTransactionNameFromString(testCase.TransactionName), (TransactionNamePriority)9999); var currentTransactionName = _transaction.CandidateTransactionName.CurrentTransactionName; var currentTransactionMetricName = _transactionMetricNameMaker.GetTransactionMetricName(currentTransactionName); var pathHash = _pathHashMaker.CalculatePathHash(currentTransactionMetricName.PrefixedName, _transaction.TransactionMetadata.CrossApplicationReferrerPathHash); _transaction.TransactionMetadata.SetCrossApplicationPathHash(pathHash); var transaction = _transaction.ConvertToImmutableTransaction(); var totalTime = transaction.Duration; // Get the attributes that would be created for this transaction var transactionMetricName = _transactionMetricNameMaker.GetTransactionMetricName(transaction.TransactionName); var txStats = new TransactionMetricStatsCollection(transactionMetricName); var attributes = _transactionAttributeMaker.GetAttributes(transaction, transactionMetricName, null, totalTime, txStats); var intrinsics = attributes.GetAttributeValuesDic(AttributeClassification.Intrinsics); // Run assertions testCase.ExpectedIntrinsicFields.ForEach(kvp => { Assert.True(intrinsics.ContainsKey(kvp.Key), $"Expected intrinsic attribute '{kvp.Key}' was not found"); Assert.AreEqual(kvp.Value, intrinsics[kvp.Key], $"Attribute '{kvp.Key}': expected value '{kvp.Value}' but found '{intrinsics[kvp.Key]}'"); }); testCase.NonExpectedIntrinsicFields.ForEach(field => { Assert.False(intrinsics.ContainsKey(field), $"Found unexpected intrinsic attribute '{field}'"); }); if (testCase.OutboundRequests != null) { expectedAndActualOutboundRequestPayloads.ForEach(kvp => { var expected = kvp.Key; var actual = kvp.Value; Assert.NotNull(actual, "Outbound request did not have any CAT headers"); Assert.AreEqual(expected.TransactionGuid, actual.TransactionGuid, $"Expected outbound.TransactionGuid to be '{expected.TransactionGuid}' but found '{actual.TransactionGuid}'"); Assert.AreEqual(expected.PathHash, actual.PathHash, $"Expected outbound.PathHash to be '{expected.TransactionGuid}' but found '{actual.TransactionGuid}'"); Assert.AreEqual(expected.TripId, actual.TripId, $"Expected outbound.TripId to be '{expected.TransactionGuid}' but found '{actual.TransactionGuid}'"); Assert.AreEqual(expected.Unused, actual.Unused, $"Expected outbound.Unused to be '{expected.Unused}' but found '{actual.Unused}'"); }); } }