public void CreatedTransactionIdTraceIdSpanIdShouldBeLowerCase() { EventBus <AgentConnectedEvent> .Publish(new AgentConnectedEvent()); var transaction = _agent.CreateTransaction( isWeb: true, category: EnumNameCache <WebTransactionType> .GetName(WebTransactionType.Action), transactionDisplayName: "name", doNotTrackAsUnitOfWork: false); var segment = _agent.StartTransactionSegmentOrThrow("segment"); segment.End(); transaction.End(); _compositeTestAgent.Harvest(); foreach (var span in _compositeTestAgent.SpanEvents) { var intrinsicAttributes = span.IntrinsicAttributes(); Assert.IsTrue(IsLowerCase(intrinsicAttributes["traceId"].ToString())); Assert.IsTrue(IsLowerCase(intrinsicAttributes["transactionId"].ToString())); } foreach (TransactionEventWireModel tx in _compositeTestAgent.TransactionEvents) { Assert.IsTrue(IsLowerCase(tx.IntrinsicAttributes()["guid"].ToString())); Assert.IsTrue(IsLowerCase(tx.IntrinsicAttributes()["traceId"].ToString())); } }
public void ShouldAcceptStringDistributedTracePayloadWhenDTEnabled() { var agentWrapperApi = _compositeTestAgent.GetAgent(); var transaction = agentWrapperApi.CreateTransaction( isWeb: true, category: EnumNameCache <WebTransactionType> .GetName(WebTransactionType.ASP), transactionDisplayName: "TransactionName", doNotTrackAsUnitOfWork: true); var transactionBridgeApi = new TransactionBridgeApi(transaction, _apiSupportabilityMetricCounters, _configSvc); var segment = agentWrapperApi.StartTransactionSegmentOrThrow("segment"); transactionBridgeApi.AcceptDistributedTracePayload(_distributedTracePayload.ToJson(), 0 /*Unknown TransportType see Agent\NewRelic.Api.Agent\TransportType.cs for more info*/); segment.End(); transaction.End(); _compositeTestAgent.Harvest(); var transactionEvent = _compositeTestAgent.TransactionEvents.First(); var transactionAttributes = transactionEvent.IntrinsicAttributes(); NrAssert.Multiple( () => Assert.AreEqual(_traceId, transactionAttributes["traceId"]), () => Assert.AreEqual(_type.ToString(), transactionAttributes["parent.type"]), () => Assert.AreEqual(_appId, transactionAttributes["parent.app"]), () => Assert.AreEqual(_accountId, transactionAttributes["parent.account"]), () => Assert.AreEqual("Unknown", transactionAttributes["parent.transportType"]), () => Assert.True(transactionAttributes.ContainsKey("parent.transportDuration")), () => Assert.AreEqual(_transactionId, transactionAttributes["parentId"]), () => Assert.AreEqual(_priority, transactionAttributes["priority"]), () => Assert.AreEqual(_sampled, transactionAttributes["sampled"]) ); }
public void keytransaction_trace_not_created_when_not_configured() { // ARRANGE var keyTransactions = new Dictionary <string, double> { { "WebTransaction/Action/other", 0.1 } }; _compositeTestAgent.ServerConfiguration.WebTransactionsApdex = keyTransactions; _compositeTestAgent.ServerConfiguration.ApdexT = 10.0; _compositeTestAgent.ServerConfiguration.RpmConfig.TransactionTracerThreshold = 10.0; _compositeTestAgent.PushConfiguration(); // ==== ACT ==== var tx = _agent.CreateTransaction( isWeb: true, category: EnumNameCache <WebTransactionType> .GetName(WebTransactionType.Action), transactionDisplayName: "name", doNotTrackAsUnitOfWork: true); var segment = _agent.StartTransactionSegmentOrThrow("segmentName"); segment.End(); tx.End(); _compositeTestAgent.Harvest(); // ==== ACT ==== // ASSERT Assert.IsEmpty(_compositeTestAgent.TransactionTraces); }
public void apdexPerfZone_satisfying_if_time_is_less_than_apdexT() { // ARRANGE var apdexT = TimeSpan.FromMilliseconds(100); _compositeTestAgent.ServerConfiguration.ApdexT = apdexT.TotalSeconds; _compositeTestAgent.PushConfiguration(); // ==== ACT ==== var tx = _agent.CreateTransaction( isWeb: true, category: EnumNameCache <WebTransactionType> .GetName(WebTransactionType.Action), transactionDisplayName: "name", doNotTrackAsUnitOfWork: true); var segment = _agent.StartTransactionSegmentOrThrow("segmentName"); segment.End(); tx.End(); _compositeTestAgent.Harvest(); // ==== ACT ==== // ASSERT var expectedEventAttributes = new List <ExpectedAttribute> { new ExpectedAttribute { Key = "nr.apdexPerfZone", Value = "S" } }; var transactionEvent = _compositeTestAgent.TransactionEvents.First(); TransactionEventAssertions.HasAttributes(expectedEventAttributes, AttributeClassification.Intrinsics, transactionEvent); }
public void TransactionTrace_HasSqlParameter() { _compositeTestAgent.LocalConfiguration.transactionTracer.explainThreshold = 0; _compositeTestAgent.PushConfiguration(); var tx = _agent.CreateTransaction( isWeb: true, category: EnumNameCache <WebTransactionType> .GetName(WebTransactionType.Action), transactionDisplayName: "name", doNotTrackAsUnitOfWork: true); var segment = _agent.StartDatastoreRequestSegmentOrThrow("SELECT", DatastoreVendor.MSSQL, "Table1", "SELECT * FROM Table1"); segment.End(); tx.End(); _compositeTestAgent.Harvest(); var transactionTrace = _compositeTestAgent.TransactionTraces.First(); var parameters = transactionTrace.TransactionTraceData.RootSegment.Children[0].Children[0].Parameters; Assert.AreEqual("SELECT * FROM Table1", parameters["sql"]); }
private void HarvestAndValidateMetric(string expectedMetricName) { _compositeTestAgent.Harvest(); // ASSERT var expectedMetrics = new List <ExpectedMetric> { new ExpectedCountMetric { Name = SupportabilityMetricPrefix + expectedMetricName, CallCount = 1 } }; MetricAssertions.MetricsExist(expectedMetrics, _compositeTestAgent.Metrics); }
private void CreateATransactionWithDatastoreSegmentAndHarvest(bool instanceReportingEnabled, bool databaseNameReportingEnabled, DatastoreVendor vendor = DatastoreVendor.MSSQL, string host = "myhost", string portPathOrId = "myport", string databaseName = "mydatabase") { _compositeTestAgent.LocalConfiguration.transactionTracer.explainThreshold = 0; _compositeTestAgent.LocalConfiguration.datastoreTracer.instanceReporting.enabled = instanceReportingEnabled; _compositeTestAgent.LocalConfiguration.datastoreTracer.databaseNameReporting.enabled = databaseNameReportingEnabled; _compositeTestAgent.PushConfiguration(); var tx = _agent.CreateTransaction( isWeb: true, category: EnumNameCache <WebTransactionType> .GetName(WebTransactionType.Action), transactionDisplayName: "name", doNotTrackAsUnitOfWork: true); var segment = _agent.StartDatastoreRequestSegmentOrThrow("SELECT", vendor, "Table1", "SELECT * FROM Table1", null, host, portPathOrId, databaseName); segment.End(); tx.End(); _compositeTestAgent.Harvest(); }
public void SimpleTransaction_CreatesDatastoreTransactionAndSqlTrace() { _compositeTestAgent.LocalConfiguration.transactionTracer.explainThreshold = 0; // Config to run explain plans on queries with any nonzero duration _compositeTestAgent.PushConfiguration(); var tx = _agent.CreateTransaction( isWeb: true, category: EnumNameCache <WebTransactionType> .GetName(WebTransactionType.Action), transactionDisplayName: "name", doNotTrackAsUnitOfWork: true); var segment = _agent.StartDatastoreRequestSegmentOrThrow("SELECT", DatastoreVendor.MSSQL, "Table1", "SELECT * FROM Table1"); segment.End(); tx.End(); _compositeTestAgent.Harvest(); var sqlTrace = _compositeTestAgent.SqlTraces.First(); NrAssert.Multiple( () => Assert.IsNotNull(sqlTrace), () => Assert.AreEqual("Datastore/statement/MSSQL/Table1/SELECT", sqlTrace.DatastoreMetricName), () => Assert.AreEqual("SELECT * FROM Table1", sqlTrace.Sql) ); }
public void synthetics_attributes_when_header_is_present() { // ARRANGE var encodingKey = "foo"; var version = 1; var clientAccountId = 123; var resourceId = "resourceId"; var jobId = "jobId"; var monitorId = "monitorId"; _compositeTestAgent.ServerConfiguration.TrustedIds = new long[] { clientAccountId }; _compositeTestAgent.ServerConfiguration.EncodingKey = encodingKey; _compositeTestAgent.PushConfiguration(); var syntheticsHeaderValue = Strings.Base64Encode( string.Format(@"[{0}, {1}, ""{2}"", ""{3}"", ""{4}""]", version, clientAccountId, resourceId, jobId, monitorId), encodingKey); var requestHeaders = new List <KeyValuePair <string, string> >() { new KeyValuePair <string, string>(SyntheticsHeaderKey, syntheticsHeaderValue) }; // ==== ACT ==== var tx = _agent.CreateTransaction( isWeb: true, category: EnumNameCache <WebTransactionType> .GetName(WebTransactionType.Action), transactionDisplayName: "name", doNotTrackAsUnitOfWork: true); tx.AcceptDistributedTraceHeaders(requestHeaders, HeaderFunctions.GetHeaders, TransportType.HTTP); var segment = _agent.StartTransactionSegmentOrThrow("segmentName"); segment.End(); tx.End(); _compositeTestAgent.Harvest(); // ASSERT var unexpectedEventAttributes = new List <string> { "nr.alternatePathHashes" }; var expectedEventAttributes = new List <ExpectedAttribute> { new ExpectedAttribute { Key = "nr.guid" }, new ExpectedAttribute { Key = "nr.syntheticsResourceId", Value = resourceId }, new ExpectedAttribute { Key = "nr.syntheticsJobId", Value = jobId }, new ExpectedAttribute { Key = "nr.syntheticsMonitorId", Value = monitorId } }; var expectedTraceAttributes = new List <ExpectedAttribute> { new ExpectedAttribute { Key = "synthetics_resource_id", Value = resourceId }, new ExpectedAttribute { Key = "synthetics_job_id", Value = jobId }, new ExpectedAttribute { Key = "synthetics_monitor_id", Value = monitorId } }; var transactionEvent = _compositeTestAgent.TransactionEvents.First(); var transactionTrace = _compositeTestAgent.TransactionTraces.First(); NrAssert.Multiple( () => TransactionEventAssertions.HasAttributes(expectedEventAttributes, AttributeClassification.Intrinsics, transactionEvent), () => TransactionEventAssertions.DoesNotHaveAttributes(unexpectedEventAttributes, AttributeClassification.Intrinsics, transactionEvent), () => TransactionTraceAssertions.HasAttributes(expectedTraceAttributes, AttributeClassification.Intrinsics, transactionTrace) ); }
public void cat_attributes_when_header_is_present() { // ARRANGE var encodingKey = "foo"; var clientAccountId = 123; var crossProcessId = $"{clientAccountId}#456"; var clientTransactionGuid = "transaction guid"; var clientTripId = "trip id"; var clientPathHash = "path hash"; _compositeTestAgent.ServerConfiguration.TrustedIds = new long[] { clientAccountId }; _compositeTestAgent.ServerConfiguration.EncodingKey = encodingKey; _compositeTestAgent.PushConfiguration(); var newRelicIdHeader = new KeyValuePair <string, string>("X-NewRelic-ID", Strings.Base64Encode(crossProcessId, encodingKey)); var newRelicTransactionHeader = new KeyValuePair <string, string>("X-NewRelic-Transaction", Strings.Base64Encode($@"[""{clientTransactionGuid}"", ""{false}"", ""{clientTripId}"", ""{clientPathHash}""]", encodingKey)); var requestHeaders = new[] { newRelicIdHeader, newRelicTransactionHeader }; // ==== ACT ==== var tx = _agent.CreateTransaction( isWeb: true, category: EnumNameCache <WebTransactionType> .GetName(WebTransactionType.Action), transactionDisplayName: "name", doNotTrackAsUnitOfWork: true); _agent.CurrentTransaction.AcceptDistributedTraceHeaders(requestHeaders, HeaderFunctions.GetHeaders, TransportType.HTTP); var segment = _agent.StartTransactionSegmentOrThrow("segmentName"); segment.End(); tx.End(); _compositeTestAgent.Harvest(); // ASSERT var unexpectedEventAttributes = new List <string> { "nr.alternatePathHashes" }; var expectedEventAttributes = new List <ExpectedAttribute> { new ExpectedAttribute { Key = "nr.guid" }, new ExpectedAttribute { Key = "nr.tripId", Value = clientTripId }, new ExpectedAttribute { Key = "nr.pathHash", Value = "b5880367" }, new ExpectedAttribute { Key = "nr.referringTransactionGuid", Value = clientTransactionGuid }, new ExpectedAttribute { Key = "nr.referringPathHash", Value = "path hash" } }; var expectedTraceAttributes = new List <ExpectedAttribute> { new ExpectedAttribute { Key = "client_cross_process_id", Value = crossProcessId }, new ExpectedAttribute { Key = "trip_id", Value = clientTripId }, new ExpectedAttribute { Key = "path_hash", Value = "b5880367" }, new ExpectedAttribute { Key = "referring_transaction_guid", Value = clientTransactionGuid }, }; var transactionEvent = _compositeTestAgent.TransactionEvents.First(); var transactionTrace = _compositeTestAgent.TransactionTraces.First(); NrAssert.Multiple ( () => TransactionEventAssertions.HasAttributes(expectedEventAttributes, AttributeClassification.Intrinsics, transactionEvent), () => TransactionEventAssertions.DoesNotHaveAttributes(unexpectedEventAttributes, AttributeClassification.Intrinsics, transactionEvent), () => TransactionTraceAssertions.HasAttributes(expectedTraceAttributes, AttributeClassification.Intrinsics, transactionTrace) ); }
public void SetWebTransactionName_UpdatesTransactionNameCorrectly() { var transaction = _agent.CreateTransaction( isWeb: true, category: EnumNameCache <WebTransactionType> .GetName(WebTransactionType.Action), transactionDisplayName: "name", doNotTrackAsUnitOfWork: true); transaction.SetWebTransactionName(WebTransactionType.ASP, "foo", TransactionNamePriority.Route); var segment = _agent.StartTransactionSegmentOrThrow("simpleName"); segment.End(); transaction.End(); _compositeTestAgent.Harvest(); var expectedMetrics = new[] { new ExpectedMetric { Name = "WebTransaction/ASP/foo" } }; var actualMetrics = _compositeTestAgent.Metrics.ToList(); var transactionTrace = _compositeTestAgent.TransactionTraces.First(); NrAssert.Multiple( () => MetricAssertions.MetricsExist(expectedMetrics, actualMetrics), () => Assert.AreEqual("WebTransaction/ASP/foo", transactionTrace.TransactionMetricName) ); }
public void SingleAddedSegment_IsNestedBelowRootSegment() { var tx = _agent.CreateTransaction( isWeb: true, category: EnumNameCache <WebTransactionType> .GetName(WebTransactionType.Action), transactionDisplayName: "name", doNotTrackAsUnitOfWork: true); var segment = _agent.StartTransactionSegmentOrThrow("childSegment"); segment.End(); tx.End(); _compositeTestAgent.Harvest(); var rootSegment = GetFirstSegmentOrThrow(); NrAssert.Multiple( () => Assert.AreEqual(1, rootSegment.Children.Count), () => Assert.AreEqual("childSegment", rootSegment.Children[0].Name), () => Assert.AreEqual(0, rootSegment.Children[0].Children.Count) ); }
public void UnknownRequestUriInTransactionEvent() { var tx = _agent.CreateTransaction( isWeb: true, category: EnumNameCache <WebTransactionType> .GetName(WebTransactionType.Action), transactionDisplayName: "name", doNotTrackAsUnitOfWork: true); var segment = _agent.StartTransactionSegmentOrThrow("segmentName"); segment.End(); tx.End(); _compositeTestAgent.Harvest(); var transactionEvent = _compositeTestAgent.TransactionEvents.First(); Assert.AreEqual("/Unknown", transactionEvent.GetAttributes(AttributeClassification.AgentAttributes)["request.uri"]); }
public void SimpleTransaction_EndedMultipleTimes() { _compositeTestAgent.LocalConfiguration.service.completeTransactionsOnThread = true; _compositeTestAgent.PushConfiguration(); var doBackgroundJob = new AutoResetEvent(false); var completedForegroundExternal = new AutoResetEvent(false); var completedBackgroundExternal = new AutoResetEvent(false); bool?transactionFlowedToBackgroundThread = null; InstrumentationThatStartsATransaction(); HttpClientInstrumentation("foregroundExternal", completedForegroundExternal); System.Threading.Tasks.Task.Run((Action)BackgroundJob); completedForegroundExternal.WaitOne(); InstrumentationThatEndsTheTransaction(); doBackgroundJob.Set(); completedBackgroundExternal.WaitOne(); _compositeTestAgent.Harvest(); var transactionEvents = _compositeTestAgent.TransactionEvents; var metrics = _compositeTestAgent.Metrics; var errors = _compositeTestAgent.ErrorEvents; Assert.AreEqual(true, transactionFlowedToBackgroundThread); Assert.AreEqual(1, transactionEvents.Count); Assert.AreEqual("foregroundExternal", transactionEvents.First().AgentAttributes()["request.uri"]); CollectionAssert.IsEmpty(errors); CollectionAssert.IsEmpty(metrics.Where(x => x.MetricName.Name.Contains("backgroundExternal"))); CollectionAssert.IsNotEmpty(metrics.Where(x => x.MetricName.Name.Contains("foregroundExternal"))); void InstrumentationThatStartsATransaction() { _agent.CreateTransaction( isWeb: true, category: EnumNameCache <WebTransactionType> .GetName(WebTransactionType.Action), transactionDisplayName: "name", doNotTrackAsUnitOfWork: true); _agent.CurrentTransaction.AttachToAsync(); _agent.CurrentTransaction.DetachFromPrimary(); } void InstrumentationThatEndsTheTransaction() { _agent.CurrentTransaction.End(); } void BackgroundJob() { transactionFlowedToBackgroundThread = _agent.CurrentTransaction.IsValid; doBackgroundJob.WaitOne(); HttpClientInstrumentation("backgroundExternal", completedBackgroundExternal); _agent.CurrentTransaction.NoticeError(new Exception()); }; System.Threading.Tasks.Task HttpClientInstrumentation(string segmentName, AutoResetEvent autoResetEvent) { var transactionWrapperApi = _agent.CurrentTransaction; var segment = _agent.StartTransactionSegmentOrThrow(segmentName); _agent.CurrentTransaction.SetUri(segmentName); segment.RemoveSegmentFromCallStack(); transactionWrapperApi.Hold(); return(System.Threading.Tasks.Task.Delay(1000).ContinueWith(task => { segment.End(); transactionWrapperApi.Release(); autoResetEvent.Set(); })); }; }
public void SqlParsingCacheMetricsAreGenerated() { var transaction = _agent.CreateTransaction( isWeb: true, category: EnumNameCache <WebTransactionType> .GetName(WebTransactionType.Action), transactionDisplayName: "name", doNotTrackAsUnitOfWork: true); _agent.StartDatastoreRequestSegmentOrThrow(DatastoreVendor.MSSQL, CommandType.Text, "SELECT * FROM Table1").End(); _agent.StartDatastoreRequestSegmentOrThrow(DatastoreVendor.MSSQL, CommandType.Text, "SELECT * FROM Table1").End(); _agent.StartDatastoreRequestSegmentOrThrow(DatastoreVendor.MSSQL, CommandType.Text, "SELECT * FROM Table1").End(); _agent.StartDatastoreRequestSegmentOrThrow(DatastoreVendor.MSSQL, CommandType.Text, "SELECT * FROM Table2").End(); _agent.StartDatastoreRequestSegmentOrThrow(DatastoreVendor.MSSQL, CommandType.Text, "SELECT * FROM Table2").End(); _agent.StartDatastoreRequestSegmentOrThrow(DatastoreVendor.IBMDB2, CommandType.Text, "SELECT * FROM Table1").End(); _agent.StartDatastoreRequestSegmentOrThrow(DatastoreVendor.IBMDB2, CommandType.Text, "SELECT * FROM Table1").End(); transaction.End(); _compositeTestAgent.Harvest(); const int defaultCapacity = 1000; // ASSERT var expectedMetrics = new List <ExpectedMetric> { new ExpectedCountMetric { Name = SqlParsingCacheMetricPrefix + "/MSSQL/Capacity", CallCount = 1, Total = defaultCapacity }, new ExpectedCountMetric { Name = SqlParsingCacheMetricPrefix + "/MSSQL/Hits", CallCount = 3 }, new ExpectedCountMetric { Name = SqlParsingCacheMetricPrefix + "/MSSQL/Misses", CallCount = 2 }, new ExpectedCountMetric { Name = SqlParsingCacheMetricPrefix + "/MSSQL/Ejections", CallCount = 0 }, new ExpectedCountMetric { Name = SqlParsingCacheMetricPrefix + "/MSSQL/Size", CallCount = 1, Total = 2 }, new ExpectedCountMetric { Name = SqlParsingCacheMetricPrefix + "/IBMDB2/Capacity", CallCount = 1, Total = defaultCapacity }, new ExpectedCountMetric { Name = SqlParsingCacheMetricPrefix + "/IBMDB2/Hits", CallCount = 1 }, new ExpectedCountMetric { Name = SqlParsingCacheMetricPrefix + "/IBMDB2/Misses", CallCount = 1 }, new ExpectedCountMetric { Name = SqlParsingCacheMetricPrefix + "/IBMDB2/Ejections", CallCount = 0 }, new ExpectedCountMetric { Name = SqlParsingCacheMetricPrefix + "/IBMDB2/Size", CallCount = 1, Total = 1 }, new ExpectedCountMetric { Name = SqlObfuscationMetricPrefix + "/MSSQL/Capacity", CallCount = 1, Total = defaultCapacity }, new ExpectedCountMetric { Name = SqlObfuscationMetricPrefix + "/MSSQL/Hits", CallCount = 3 }, new ExpectedCountMetric { Name = SqlObfuscationMetricPrefix + "/MSSQL/Misses", CallCount = 2 }, new ExpectedCountMetric { Name = SqlObfuscationMetricPrefix + "/MSSQL/Ejections", CallCount = 0 }, new ExpectedCountMetric { Name = SqlObfuscationMetricPrefix + "/MSSQL/Size", CallCount = 1, Total = 2 }, new ExpectedCountMetric { Name = SqlObfuscationMetricPrefix + "/IBMDB2/Capacity", CallCount = 1, Total = defaultCapacity }, new ExpectedCountMetric { Name = SqlObfuscationMetricPrefix + "/IBMDB2/Hits", CallCount = 1 }, new ExpectedCountMetric { Name = SqlObfuscationMetricPrefix + "/IBMDB2/Misses", CallCount = 1 }, new ExpectedCountMetric { Name = SqlObfuscationMetricPrefix + "/IBMDB2/Ejections", CallCount = 0 }, new ExpectedCountMetric { Name = SqlObfuscationMetricPrefix + "/IBMDB2/Size", CallCount = 1, Total = 1 } }; var unexpectedMetrics = new List <ExpectedMetric> { new ExpectedCountMetric { Name = SqlParsingCacheMetricPrefix + "/MongoDB/Hits" }, new ExpectedCountMetric { Name = SqlParsingCacheMetricPrefix + "/MongoDB/Misses" }, new ExpectedCountMetric { Name = SqlParsingCacheMetricPrefix + "/MongoDB/Ejections" }, new ExpectedCountMetric { Name = SqlParsingCacheMetricPrefix + "/MongoDB/Size" }, new ExpectedCountMetric { Name = SqlObfuscationMetricPrefix + "/MongoDB/Hits" }, new ExpectedCountMetric { Name = SqlObfuscationMetricPrefix + "/MongoDB/Misses" }, new ExpectedCountMetric { Name = SqlObfuscationMetricPrefix + "/MongoDB/Ejections" }, new ExpectedCountMetric { Name = SqlObfuscationMetricPrefix + "/MongoDB/Size" } }; MetricAssertions.MetricsExist(expectedMetrics, _compositeTestAgent.Metrics); MetricAssertions.MetricsDoNotExist(unexpectedMetrics, _compositeTestAgent.Metrics); }