public void FetchWithMultipleObjectTypes() { PropertyFetcher fetcher = new PropertyFetcher("Name"); string value1 = (string)fetcher.Fetch(new TestClass1 { Name = "Value1" }); string value2 = (string)fetcher.Fetch(new TestClass2 { Name = "Value2" }); Assert.AreEqual("Value1", value1); Assert.AreEqual("Value2", value2); }
private void OnMvcBeforeAction(object arg) { var httpContext = (HttpContext)BeforeActionHttpContextFetcher.Fetch(arg); if (ShouldIgnore(httpContext)) { if (_isLogLevelDebugEnabled) { Log.Debug("Ignoring request"); } } else { Span span = _tracer.ScopeManager.Active?.Span; if (span != null) { // NOTE: This event is the start of the action pipeline. The action has been selected, the route // has been selected but no filters have run and model binding hasn't occured. var actionDescriptor = (ActionDescriptor)BeforeActionActionDescriptorFetcher.Fetch(arg); HttpRequest request = httpContext.Request; string httpMethod = request.Method?.ToUpperInvariant() ?? "UNKNOWN"; string controllerName = actionDescriptor.RouteValues["controller"]; string actionName = actionDescriptor.RouteValues["action"]; string routeTemplate = actionDescriptor.AttributeRouteInfo?.Template ?? $"{controllerName}/{actionName}"; string resourceName = $"{httpMethod} {routeTemplate}"; // override the parent's resource name with the MVC route template span.ResourceName = resourceName; } } }
private void ErrorRollbackHelper(KeyValuePair <string, object> evnt, PropertyFetcher operationIdFetcher, PropertyFetcher connectionFetcher, PropertyFetcher timestampFetcher, PropertyFetcher exceptionFetcher, PropertyFetcher numberFetcher) { var operationId = (Guid)operationIdFetcher.Fetch(evnt.Value); DependencyCollectorEventSource.Log.SqlClientDiagnosticSubscriberCallbackCalled(operationId, evnt.Key); var connection = connectionFetcher.Fetch(evnt.Value); var tuple = this.operationHolder.Get(connection); if (tuple != null) { this.operationHolder.Remove(connection); var telemetry = tuple.Item1; var timestamp = (long)timestampFetcher.Fetch(evnt.Value); telemetry.Stop(timestamp); var exception = (Exception)exceptionFetcher.Fetch(evnt.Value); ConfigureExceptionTelemetry(telemetry, exception, numberFetcher); this.client.TrackDependency(telemetry); } else { DependencyCollectorEventSource.Log.EndCallbackWithNoBegin(operationId.ToStringInvariant("N")); } }
protected override void OnNext(string eventName, object untypedArg) { switch (eventName) { case "System.Data.SqlClient.WriteCommandBefore": { var args = (SqlCommand)_activityCommand_RequestFetcher.Fetch(untypedArg); string operationName = _options.OperationNameResolver(args); Tracer.BuildSpan(operationName) .WithTag(Tags.SpanKind, Tags.SpanKindClient) .WithTag(Tags.Component, _options.ComponentName) .WithTag(Tags.DbInstance, args.Connection.Database) .WithTag(Tags.DbStatement, args.CommandText) .StartActive(); } break; case "System.Data.SqlClient.WriteCommandError": { Exception ex = (Exception)_exception_ExceptionFetcher.Fetch(untypedArg); DisposeActiveScope(isScopeRequired: true, exception: ex); } break; case "System.Data.SqlClient.WriteCommandAfter": { DisposeActiveScope(isScopeRequired: true); } break; } }
public void OnWriteCommand(string name, object payload) { switch (name) { case "Microsoft.Data.SqlClient.WriteCommandBefore": { commandTimestampContext.Value = Stopwatch.GetTimestamp(); } break; case "Microsoft.Data.SqlClient.WriteCommandAfter": { long operationTimeStamp = Stopwatch.GetTimestamp() - commandTimestampContext.Value; PrometheusCounters.SqlCommandsDuration.Observe(TimeSpan.FromTicks(operationTimeStamp).TotalSeconds); if (options.CollectStatistics) { if (statisticsFetcher.Fetch(payload) is IDictionary currentStatistics) { var connection = connectionFetcher.Fetch(payload).ToString(); WriteStatisticsMetrics(connection, currentStatistics); } } } break; case "Microsoft.Data.SqlClient.WriteCommandError": { PrometheusCounters.SqlCommandsErrors.WithLabels("command").Inc(); } break; } }
private void OnException(KeyValuePair <string, object> kv) { var activity = Activity.Current; if (activity is null) { Logger.Trace()?.Log("Current activity is null - exiting"); return; } if (!_processingSegments.TryRemove(activity.Id, out var segment)) { Logger.Trace()?.Log( "Could not find segment for activity {ActivityId} in tracked segments", activity.Id); return; } if (_exceptionProperty.Fetch(kv.Value) is Exception exception) { segment.CaptureException(exception); } segment.Outcome = Outcome.Failure; segment.End(); }
public EndMethodDelegate BeforeWrappedMethod(TraceMethodInfo traceMethodInfo) { var multiplexer = traceMethodInfo.InvocationTarget; var message = traceMethodInfo.MethodArguments[0]; var config = (string)ConfigPropertyFetcher.Fetch(multiplexer); var hostAndPort = GetHostAndPort(config); var rawCommand = (string)CommandAndKeyPropertyFetcher.Fetch(message); var span = _tracer.BuildSpan("redis.command") .AsChildOf(_tracer.ActiveSpan) .WithTag(Tags.SpanKind, Tags.SpanKindClient) .WithTag(Tags.Component, "StackExchange.Redis") .WithTag("redis.raw_command", rawCommand) .WithTag("out.host", hostAndPort.Item1) .WithTag("out.port", hostAndPort.Item2) .Start(); traceMethodInfo.TraceContext = span; if (traceMethodInfo.MethodBase.Name == ExecuteSyncImpl) { return(delegate(object returnValue, Exception ex) { Leave(traceMethodInfo, returnValue, ex); }); } else { return(delegate(object returnValue, Exception ex) { DelegateHelper.AsyncMethodEnd(Leave, traceMethodInfo, ex, returnValue); }); } }
private void AfterExecuteHelper(KeyValuePair <string, object> evnt, PropertyFetcher operationIdFetcher, PropertyFetcher commandFetcher, PropertyFetcher timestampFetcher) { var operationId = (Guid)operationIdFetcher.Fetch(evnt.Value); DependencyCollectorEventSource.Log.SqlClientDiagnosticSubscriberCallbackCalled(operationId, evnt.Key); var command = commandFetcher.Fetch(evnt.Value); var tuple = this.operationHolder.Get(command); if (tuple != null) { this.operationHolder.Remove(command); var telemetry = tuple.Item1; var timestamp = (long)timestampFetcher.Fetch(evnt.Value); telemetry.Stop(timestamp); this.client.TrackDependency(telemetry); } else { DependencyCollectorEventSource.Log.EndCallbackWithNoBegin(operationId.ToStringInvariant("N")); } }
public void FetchValidProperty() { var activity = new Activity("test"); var fetch = new PropertyFetcher <string>("DisplayName"); var result = fetch.Fetch(activity); Assert.Equal(activity.DisplayName, result); }
private void OnMvcBeforeAction(object arg) { var httpContext = (HttpContext)BeforeActionHttpContextFetcher.Fetch(arg); if (ShouldIgnore(httpContext)) { if (_isLogLevelDebugEnabled) { Log.Debug("Ignoring request"); } } else { Span span = _tracer.ScopeManager.Active?.Span; if (span != null) { // NOTE: This event is the start of the action pipeline. The action has been selected, the route // has been selected but no filters have run and model binding hasn't occured. var actionDescriptor = (ActionDescriptor)BeforeActionActionDescriptorFetcher.Fetch(arg); // Try to use the best tag values available. if (!span.Tags.ContainsKey(Tags.HttpMethod)) { HttpRequest request = httpContext.Request; string httpMethod = request.Method?.ToUpperInvariant(); if (!string.IsNullOrEmpty(httpMethod)) { span.Tags.Add(Tags.HttpMethod, httpMethod); } } if (actionDescriptor.RouteValues.TryGetValue("controller", out string controllerName)) { span.Tags[Tags.AspNetController] = controllerName; } if (actionDescriptor.RouteValues.TryGetValue("action", out string actionName)) { span.Tags[Tags.AspNetAction] = actionName; } string routeTemplate = actionDescriptor.AttributeRouteInfo?.Template; if (!string.IsNullOrEmpty(routeTemplate)) { span.OperationName = routeTemplate; } else if (!string.IsNullOrEmpty(controllerName) && !string.IsNullOrEmpty(actionName)) { span.OperationName = $"{controllerName}.{actionName}".ToLowerInvariant(); } ServerTimingHeader.SetHeaders(span.Context, httpContext.Response.Headers, (headers, name, value) => headers.Add(name, value)); } } }
public bool ProcessEvent(string eventName, object arg) { switch (eventName) { case "Microsoft.AspNetCore.Mvc.BeforeAction": { // NOTE: This event is the start of the action pipeline. The action has been selected, the route // has been selected but no filters have run and model binding hasn't occured. var actionDescriptor = (ActionDescriptor)_beforeAction_ActionDescriptorFetcher.Fetch(arg); var controllerActionDescriptor = actionDescriptor as ControllerActionDescriptor; string operationName = controllerActionDescriptor != null ? $"Action {controllerActionDescriptor.ControllerTypeInfo.FullName}/{controllerActionDescriptor.ActionName}" : $"Action {actionDescriptor.DisplayName}"; _tracer.BuildSpan(operationName) .WithTag(Tags.Component.Key, ActionComponent) .WithTag(ActionTagControllerName, controllerActionDescriptor?.ControllerTypeInfo.FullName) .WithTag(ActionTagActionName, controllerActionDescriptor?.ActionName) .StartActive(finishSpanOnDispose: true); } return(true); case "Microsoft.AspNetCore.Mvc.AfterAction": { _tracer.ScopeManager.Active?.Dispose(); } return(true); case "Microsoft.AspNetCore.Mvc.BeforeActionResult": { // NOTE: This event is the start of the result pipeline. The action has been executed, but // we haven't yet determined which view (if any) will handle the request object result = _beforeActionResult_ResultFetcher.Fetch(arg); string resultType = result.GetType().Name; string operationName = $"Result {resultType}"; _tracer.BuildSpan(operationName) .WithTag(Tags.Component.Key, ResultComponent) .WithTag(ResultTagType, resultType) .StartActive(finishSpanOnDispose: true); } return(true); case "Microsoft.AspNetCore.Mvc.AfterActionResult": { _tracer.ScopeManager.Active?.Dispose(); } return(true); default: return(false); } }
public void FetchInvalidProperty() { var activity = new Activity("test"); var fetch = new PropertyFetcher <string>("DisplayName2"); var result = fetch.Fetch(activity); var fetchInt = new PropertyFetcher <int>("DisplayName2"); var resultInt = fetchInt.Fetch(activity); Assert.Equal(default, result);
public void ValueTypeObject_FetchesValueTypeProperty() { const int expected = 123; var element = new ExampleValueType(expected, "ValueType"); var fetcher = new PropertyFetcher("Id"); var actual = fetcher.Fetch <int>(element); Assert.Equal(expected, actual); }
public void ValueTypeObject_FetchesReferenceTypeProperty() { const string expected = "ValueType"; var element = new ExampleValueType(123, expected); var fetcher = new PropertyFetcher("Name"); var actual = fetcher.Fetch <string>(element); Assert.Equal(expected, actual); }
public override void OnStopActivity(Activity activity, object payload) { var response = stopResponseFetcher.Fetch(payload); if (response is HttpResponseMessage httpResponse) { PrometheusCounters.GrpcClientRequestsDuration .WithLabels(httpResponse.StatusCode.ToString("D"), httpResponse.RequestMessage.RequestUri.Host) .Observe(activity.Duration.TotalSeconds); } }
public void Fetch_NameFoundDifferentCasing_ValueReturned() { var obj = new TestClass { TestProperty = "TestValue" }; var sut = new PropertyFetcher("testproperty"); var result = sut.Fetch(obj); Assert.Equal("TestValue", result); }
public void Fetch_NameNotFound_NullReturned() { var obj = new TestClass { TestProperty = "TestValue" }; var sut = new PropertyFetcher("DifferentProperty"); var result = sut.Fetch(obj); Assert.Null(result); }
private void OnHostingUnhandledException(object arg) { ISpan span = _tracer.ScopeManager.Active?.Span; if (span != null) { var exception = (Exception)UnhandledExceptionExceptionFetcher.Fetch(arg); var httpContext = (HttpContext)UnhandledExceptionHttpContextFetcher.Fetch(arg); span.SetException(exception); _options.OnError?.Invoke(span, exception, httpContext); } }
protected override void OnNext(string eventName, object arg) { switch (eventName) { case "System.Net.Http.Desktop.HttpRequestOut.Start": { var request = (HttpWebRequest)_activityStart_RequestFetcher.Fetch(arg); string operationName = _options.OperationNameResolver(request); ISpan span = Tracer.BuildSpan(operationName) .WithTag(Tags.SpanKind, Tags.SpanKindClient) .WithTag(Tags.Component, _options.ComponentName) .WithTag(Tags.HttpMethod, request.Method.ToString()) .WithTag(Tags.HttpUrl, request.RequestUri.ToString()) .WithTag(Tags.PeerHostname, request.RequestUri.Host) .WithTag(Tags.PeerPort, request.RequestUri.Port) .Start(); _options.OnRequest?.Invoke(span, request); if (_options.InjectEnabled?.Invoke(request) ?? true) { Tracer.Inject(span.Context, BuiltinFormats.HttpHeaders, new HttpHeadersInjectAdapter(request.Headers)); } spanContainer.TryAdd(request.Headers["uber-trace-id"], span); } break; case "System.Net.Http.Exception": break; case "System.Net.Http.Desktop.HttpRequestOut.Stop": { var request = (HttpWebRequest)_activityStop_RequestFetcher.Fetch(arg); if (spanContainer.TryRemove(request.Headers["uber-trace-id"], out var span)) { var response = (HttpWebResponse)_activityStop_ResponseFetcher.Fetch(arg); if (response != null) { span.SetTag(Tags.HttpStatus, (int)response.StatusCode); } span.Finish(); } } break; } }
/// <inheritdoc /> public void OnNext(KeyValuePair <string, object> value) { if (value.Key == "Microsoft.AspNetCore.Mvc.BeforeAction") { var context = httpContextFetcher.Fetch(value.Value) as HttpContext; var routeData = routeDataFetcher.Fetch(value.Value); var routeValues = routeValuesFetcher.Fetch(routeData) as IDictionary <string, object>; if (context != null && routeValues != null) { this.OnBeforeAction(context, routeValues); } } }
private static void ConfigureExceptionTelemetry(DependencyTelemetry telemetry, Exception exception, PropertyFetcher numberFetcher) { telemetry.Success = false; telemetry.Properties["Exception"] = exception.ToInvariantString(); try { var exceptionNumber = (int)numberFetcher.Fetch(exception); telemetry.ResultCode = exceptionNumber.ToString(CultureInfo.InvariantCulture); } catch (Exception) { // Ignore as it simply indicate exception was not a SqlException } }
private void OnHostingHttpRequestInStart(object arg) { var httpContext = (HttpContext)HttpRequestInStartHttpContextFetcher.Fetch(arg); if (ShouldIgnore(httpContext)) { if (_isLogLevelDebugEnabled) { Log.Debug("Ignoring request"); } } else { HttpRequest request = httpContext.Request; string host = request.Host.Value; string httpMethod = request.Method?.ToUpperInvariant() ?? "UNKNOWN"; string url = GetUrl(request); string resourceUrl = UriHelpers.GetRelativeUrl(new Uri(url), tryRemoveIds: true) .ToLowerInvariant(); var propagator = _tracer.Propagator; SpanContext propagatedContext = ExtractPropagatedContext(propagator, request); Span span = _tracer.StartSpan(HttpRequestInOperationName, propagatedContext) .SetTag(Tags.InstrumentationName, ComponentName); IPAddress remoteIp = null; if (Tracing.Tracer.Instance.Settings.AddClientIpToServerSpans) { remoteIp = httpContext?.Connection?.RemoteIpAddress; } span.DecorateWebServerSpan(resourceUrl, httpMethod, host, url, remoteIp); span.SetTag(Tags.InstrumentationName, IntegrationName); // set analytics sample rate if enabled var analyticsSampleRate = _tracer.Settings.GetIntegrationAnalyticsSampleRate(IntegrationName, enabledWithGlobalSetting: true); span.SetMetric(Tags.Analytics, analyticsSampleRate); Scope scope = _tracer.ActivateSpan(span); _options.OnRequest?.Invoke(scope.Span, httpContext); } }
private void OnHostingHttpRequestInStop(object arg) { IScope scope = _tracer.ScopeManager.Active; if (scope != null) { var httpContext = (HttpContext)HttpRequestInStopHttpContextFetcher.Fetch(arg); scope.Span.SetTag(Tags.HttpStatusCode, httpContext.Response.StatusCode.ToString()); if (httpContext.Response.StatusCode / 100 == 5) { // 5xx codes are server-side errors scope.Span.Error = true; } scope.Dispose(); } }
public override void OnStartActivity(Activity current, object valueValue) { var operationName = current.OperationName; var spanKind = SpanKind.Internal; foreach (var keyValuePair in current.Tags) { if (keyValuePair.Key == "http.url") { operationName = keyValuePair.Value; spanKind = SpanKind.Client; break; } if (keyValuePair.Key == "kind") { if (Enum.TryParse(keyValuePair.Value, true, out SpanKind parsedSpanKind)) { spanKind = parsedSpanKind; } } } List <Link> parentLinks = null; if (LinksPropertyFetcher.Fetch(valueValue) is IEnumerable <Activity> activityLinks) { if (activityLinks.Any()) { parentLinks = new List <Link>(); foreach (var link in activityLinks) { if (link != null) { parentLinks.Add(new Link(new SpanContext(link.TraceId, link.ParentSpanId, link.ActivityTraceFlags))); } } } } var span = this.Tracer.StartSpanFromActivity(operationName, current, spanKind, parentLinks); this.Tracer.WithSpan(span); }
private void BeforeRollbackHelper(KeyValuePair <string, object> evnt, PropertyFetcher operationIdFetcher, PropertyFetcher connectionFetcher, PropertyFetcher operationFetcher, PropertyFetcher timestampFetcher, PropertyFetcher isolationFetcher, PropertyFetcher datasourceFetcher, PropertyFetcher databaseFetcher) { { var operationId = (Guid)operationIdFetcher.Fetch(evnt.Value); DependencyCollectorEventSource.Log.SqlClientDiagnosticSubscriberCallbackCalled(operationId, evnt.Key); var connection = connectionFetcher.Fetch(evnt.Value); if (this.operationHolder.Get(connection) == null) { var operation = (string)operationFetcher.Fetch(evnt.Value); var timestamp = (long)timestampFetcher.Fetch(evnt.Value); var isolationLevel = isolationFetcher.Fetch(evnt.Value); var dataSource = (string)datasourceFetcher.Fetch(connection); var database = (string)databaseFetcher.Fetch(connection); var telemetry = new DependencyTelemetry() { Id = operationId.ToStringInvariant("N"), Name = string.Join(" | ", dataSource, database, operation, isolationLevel), Type = RemoteDependencyConstants.SQL, Target = string.Join(" | ", dataSource, database), Data = operation, Success = true, }; InitializeTelemetry(telemetry, operationId, timestamp); this.operationHolder.Store(connection, Tuple.Create(telemetry, /* isCustomCreated: */ false)); } else { DependencyCollectorEventSource.Log.TrackingAnExistingTelemetryItemVerbose(); } } }
/// <summary> /// Tries to get the value of an instance property with the specified name. /// </summary> /// <typeparam name="TResult">The type of the property.</typeparam> /// <param name="source">The value that contains the property.</param> /// <param name="propertyName">The name of the property.</param> /// <param name="value">The value of the property, or <c>null</c> if the property is not found.</param> /// <returns><c>true</c> if the property exists, otherwise <c>false</c>.</returns> public static bool TryGetPropertyValue <TResult>(this object source, string propertyName, out TResult value) { if (source != null) { var type = source.GetType(); PropertyFetcher fetcher = PropertyFetcherCache.GetOrAdd( GetKey <TResult>(propertyName, type), key => new PropertyFetcher(key.Name)); if (fetcher != null) { value = fetcher.Fetch <TResult>(source, type); return(true); } } value = default; return(false); }
private void AfterOpenConnectionHelper(KeyValuePair <string, object> evnt, PropertyFetcher operationIdFetcher, PropertyFetcher connectionFetcher) { var operationId = (Guid)operationIdFetcher.Fetch(evnt.Value); DependencyCollectorEventSource.Log.SqlClientDiagnosticSubscriberCallbackCalled(operationId, evnt.Key); var connection = connectionFetcher.Fetch(evnt.Value); var tuple = this.operationHolder.Get(connection); if (tuple != null) { this.operationHolder.Remove(connection); } else { DependencyCollectorEventSource.Log.EndCallbackWithNoBegin(operationId.ToStringInvariant("N")); } }
public override void OnStartActivity(Activity current, object valueValue) { var operationName = current.OperationName; SpanKind spanKind = SpanKind.Internal; foreach (var keyValuePair in current.Tags) { if (keyValuePair.Key == "http.url") { operationName = keyValuePair.Value; break; } if (keyValuePair.Key == "kind") { if (Enum.TryParse(keyValuePair.Value, true, out SpanKind parsedSpanKind)) { spanKind = parsedSpanKind; } } } var spanBuilder = this.tracer.SpanBuilder(operationName) .SetCreateChild(false) .SetSampler(this.sampler); var links = LinksPropertyFetcher.Fetch(valueValue) as IEnumerable <Activity> ?? Array.Empty <Activity>(); foreach (var link in links) { spanBuilder.AddLink(Link.FromSpanContext(SpanContext.Create(link.TraceId, link.ParentSpanId, link.ActivityTraceFlags, Tracestate.Empty))); } spanBuilder.SetSpanKind(spanKind); var span = spanBuilder.StartSpan(); span.Status = Status.Ok; this.tracer.WithSpan(span); }
/// <inheritdoc /> public void OnNext(KeyValuePair <string, object> value) { try { if (value.Key == "Microsoft.AspNetCore.Mvc.BeforeAction") { var context = httpContextFetcher.Fetch(value.Value) as HttpContext; var routeData = routeDataFetcher.Fetch(value.Value); var routeValues = routeValuesFetcher.Fetch(routeData) as IDictionary <string, object>; if (context != null && routeValues != null) { this.OnBeforeAction(context, routeValues); } } } catch (Exception ex) { AspNetCoreEventSource.Instance.DiagnosticListenerWarning("MvcDiagnosticsListener", value.Key, ex.Message); } }
private void OnMvcBeforeAction(object arg) { var httpContext = (HttpContext)BeforeActionHttpContextFetcher.Fetch(arg); if (ShouldIgnore(httpContext)) { if (_isLogLevelDebugEnabled) { Log.Debug("Ignoring request"); } } else { Span span = _tracer.ScopeManager.Active?.Span; if (span != null) { // NOTE: This event is the start of the action pipeline. The action has been selected, the route // has been selected but no filters have run and model binding hasn't occured. var actionDescriptor = (ActionDescriptor)BeforeActionActionDescriptorFetcher.Fetch(arg); HttpRequest request = httpContext.Request; string httpMethod = request.Method?.ToUpperInvariant() ?? "UNKNOWN"; string controllerName = actionDescriptor.RouteValues["controller"]; string actionName = actionDescriptor.RouteValues["action"]; string routeTemplate = actionDescriptor.AttributeRouteInfo?.Template; if (!string.IsNullOrEmpty(controllerName) && !string.IsNullOrEmpty(actionName)) { span.OperationName = $"{controllerName}.{actionName}".ToLowerInvariant(); } else if (!string.IsNullOrEmpty(routeTemplate)) { span.OperationName = routeTemplate; } } } }