private void OnBeginRequest(object sender, EventArgs eventArgs) { Scope scope = null; try { var tracer = Tracer.Instance; if (!tracer.Settings.IsIntegrationEnabled(IntegrationName)) { // integration disabled return; } var httpContext = (sender as HttpApplication)?.Context; if (httpContext == null) { return; } HttpRequest httpRequest = httpContext.Request; SpanContext propagatedContext = null; if (tracer.ActiveScope == null) { try { // extract propagated http headers var headers = httpRequest.Headers.Wrap(); propagatedContext = SpanContextPropagator.Instance.Extract(headers); } catch (Exception ex) { Log.Error(ex, "Error extracting propagated HTTP headers."); } } string host = httpRequest.Headers.Get("Host"); string httpMethod = httpRequest.HttpMethod.ToUpperInvariant(); string url = httpRequest.RawUrl.ToLowerInvariant(); string path = UriHelpers.GetRelativeUrl(httpRequest.Url, tryRemoveIds: true); string resourceName = $"{httpMethod} {path.ToLowerInvariant()}"; scope = tracer.StartActive(_requestOperationName, propagatedContext); scope.Span.DecorateWebServerSpan(resourceName, httpMethod, host, url); // set analytics sample rate if enabled var analyticsSampleRate = tracer.Settings.GetIntegrationAnalyticsSampleRate(IntegrationName, enabledWithGlobalSetting: true); scope.Span.SetMetric(Tags.Analytics, analyticsSampleRate); httpContext.Items[_httpContextScopeKey] = scope; } catch (Exception ex) { // Dispose here, as the scope won't be in context items and won't get disposed on request end in that case... scope?.Dispose(); Log.Error(ex, "Datadog ASP.NET HttpModule instrumentation error"); } }
public static object ExecuteReaderAsync( object command, object boxedCancellationToken, int opCode, int mdToken, long moduleVersionPtr) { const string methodName = AdoNetConstants.MethodNames.ExecuteReaderAsync; var cancellationToken = (CancellationToken)boxedCancellationToken; Type npgsqlComandType; Type npgsqlDataReaderType; try { npgsqlComandType = command.GetInstrumentedType(NpgsqlCommandTypeName); npgsqlDataReaderType = npgsqlComandType.Assembly.GetType(NpgsqlDataReaderTypeName); } catch (Exception ex) { // This shouldn't happen because the assembly holding the Npgsql.NpgsqlDataReader type should have been loaded already // profiled app will not continue working as expected without this method Log.Error(ex, "Error finding the Npgsql.NpgsqlDataReader type"); throw; } Func <DbCommand, CancellationToken, object> instrumentedMethod; try { instrumentedMethod = MethodBuilder <Func <DbCommand, CancellationToken, object> > .Start(moduleVersionPtr, mdToken, opCode, methodName) .WithConcreteType(npgsqlComandType) .WithParameters(cancellationToken) .WithNamespaceAndNameFilters(ClrNames.GenericTask, ClrNames.CancellationToken) .Build(); } catch (Exception ex) { Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: NpgsqlCommandTypeName, methodName: methodName, instanceType: command.GetType().AssemblyQualifiedName); throw; } return(AsyncHelper.InvokeGenericTaskDelegate( owningType: command.GetType(), taskResultType: npgsqlDataReaderType, nameOfIntegrationMethod: nameof(ExecuteReaderAsyncInternal), integrationType: typeof(NpgsqlCommandIntegration), (DbCommand)command, cancellationToken, instrumentedMethod)); }
/// <summary> /// Creates a scope for outbound http requests and populates some common details. /// </summary> /// <param name="tracer">The tracer instance to use to create the new scope.</param> /// <param name="httpMethod">The HTTP method used by the request.</param> /// <param name="requestUri">The URI requested by the request.</param> /// <param name="integrationName">The name of the integration creating this scope.</param> /// <returns>A new pre-populated scope.</returns> public static Scope CreateOutboundHttpScope(Tracer tracer, string httpMethod, Uri requestUri, string integrationName) { if (!tracer.Settings.IsIntegrationEnabled(integrationName)) { // integration disabled, don't create a scope, skip this trace return(null); } Scope scope = null; try { Span parent = tracer.ActiveScope?.Span; if (parent != null && parent.Type == SpanTypes.Http && parent.GetTag(Tags.InstrumentationName) != null) { // we are already instrumenting this, // don't instrument nested methods that belong to the same stacktrace // e.g. HttpClientHandler.SendAsync() -> SocketsHttpHandler.SendAsync() return(null); } string resourceUrl = requestUri != null?UriHelpers.CleanUri(requestUri, removeScheme : true, tryRemoveIds : true) : null; string httpUrl = requestUri != null?UriHelpers.CleanUri(requestUri, removeScheme : false, tryRemoveIds : false) : null; scope = tracer.StartActive(OperationName, serviceName: $"{tracer.DefaultServiceName}-{ServiceName}"); var span = scope.Span; span.Type = SpanTypes.Http; span.ResourceName = $"{httpMethod} {resourceUrl}"; span.SetTag(Tags.SpanKind, SpanKinds.Client); span.SetTag(Tags.HttpMethod, httpMethod?.ToUpperInvariant()); span.SetTag(Tags.HttpUrl, httpUrl); span.SetTag(Tags.InstrumentationName, integrationName); // set analytics sample rate if enabled if (integrationName != null) { var analyticsSampleRate = tracer.Settings.GetIntegrationAnalyticsSampleRate(integrationName, enabledWithGlobalSetting: false); span.SetMetric(Tags.Analytics, analyticsSampleRate); } } catch (Exception ex) { Log.Error(ex, "Error creating or populating scope."); } // always returns the scope, even if it's null because we couldn't create it, // or we couldn't populate it completely (some tags is better than no tags) return(scope); }
/// <summary> /// Creates a scope for outbound http requests and populates some common details. /// </summary> /// <param name="tracer">The tracer instance to use to create the new scope.</param> /// <param name="httpMethod">The HTTP method used by the request.</param> /// <param name="requestUri">The URI requested by the request.</param> /// <param name="integrationId">The id of the integration creating this scope.</param> /// <param name="tags">The tags associated to the scope</param> /// <returns>A new pre-populated scope.</returns> public static Scope CreateOutboundHttpScope(Tracer tracer, string httpMethod, Uri requestUri, IntegrationInfo integrationId, out HttpTags tags) { tags = null; if (!tracer.Settings.IsIntegrationEnabled(integrationId)) { // integration disabled, don't create a scope, skip this trace return(null); } Scope scope = null; try { Span parent = tracer.ActiveScope?.Span; if (parent != null && parent.Type == SpanTypes.Http && parent.GetTag(Tags.InstrumentationName) != null) { // we are already instrumenting this, // don't instrument nested methods that belong to the same stacktrace // e.g. HttpClientHandler.SendAsync() -> SocketsHttpHandler.SendAsync() return(null); } string resourceUrl = requestUri != null?UriHelpers.CleanUri(requestUri, removeScheme : true, tryRemoveIds : true) : null; string httpUrl = requestUri != null?UriHelpers.CleanUri(requestUri, removeScheme : false, tryRemoveIds : false) : null; tags = new HttpTags(); string serviceName = tracer.Settings.GetServiceName(tracer, ServiceName); scope = tracer.StartActiveWithTags(OperationName, tags: tags, serviceName: serviceName); var span = scope.Span; span.Type = SpanTypes.Http; span.ResourceName = $"{httpMethod} {resourceUrl}"; tags.HttpMethod = httpMethod?.ToUpperInvariant(); tags.HttpUrl = httpUrl; tags.InstrumentationName = IntegrationRegistry.GetName(integrationId); tags.SetAnalyticsSampleRate(integrationId, tracer.Settings, enabledWithGlobalSetting: false); } catch (Exception ex) { Log.Error(ex, "Error creating or populating scope."); } // always returns the scope, even if it's null because we couldn't create it, // or we couldn't populate it completely (some tags is better than no tags) return(scope); }
public static object ExecuteAsyncGeneric( object wireProtocol, object connection, object cancellationTokenSource, int opCode, int mdToken, long moduleVersionPtr) { // The generic type for this method comes from the declaring type of wireProtocol if (wireProtocol == null) { throw new ArgumentNullException(nameof(wireProtocol)); } var tokenSource = cancellationTokenSource as CancellationTokenSource; var cancellationToken = tokenSource?.Token ?? CancellationToken.None; var wireProtocolType = wireProtocol.GetType(); var wireProtocolGenericArgs = GetGenericsFromWireProtocol(wireProtocolType); const string methodName = nameof(ExecuteAsync); Func <object, object, CancellationToken, object> executeAsync; try { executeAsync = MethodBuilder <Func <object, object, CancellationToken, object> > .Start(moduleVersionPtr, mdToken, opCode, methodName) .WithConcreteType(wireProtocolType) .WithDeclaringTypeGenerics(wireProtocolGenericArgs) .WithParameters(connection, cancellationToken) .WithNamespaceAndNameFilters(ClrNames.GenericTask, "MongoDB.Driver.Core.Connections.IConnection", ClrNames.CancellationToken) .Build(); } catch (Exception ex) { // profiled app will not continue working as expected without this method Log.Error(ex, $"Error resolving {wireProtocolType.Name}.{methodName}(IConnection connection, CancellationToken cancellationToken)"); throw; } return(AsyncHelper.InvokeGenericTaskDelegate( wireProtocolType, wireProtocolGenericArgs[0], nameof(ExecuteAsyncInternalGeneric), typeof(MongoDbIntegration), wireProtocol, connection, cancellationToken, executeAsync)); }
private void OnBeginRequest(object sender, EventArgs eventArgs) { var tracer = Tracer.Instance; if (!tracer.Settings.IsIntegrationEnabled(IntegrationName)) { // integration disabled return; } Scope scope = null; try { if (!TryGetContext(sender, out var httpContext)) { return; } SpanContext propagatedContext = null; if (tracer.ActiveScope == null) { try { // extract propagated http headers var headers = httpContext.Request.Headers.Wrap(); propagatedContext = SpanContextPropagator.Instance.Extract(headers); } catch (Exception ex) { Log.Error(ex, "Error extracting propagated HTTP headers."); } } scope = tracer.StartActive(_operationName, propagatedContext); // set analytics sample rate if enabled var analyticsSampleRate = tracer.Settings.GetIntegrationAnalyticsSampleRate(IntegrationName, enabledWithGlobalSetting: true); scope.Span.SetMetric(Tags.Analytics, analyticsSampleRate); httpContext.Items[_httpContextDelegateKey] = HttpContextSpanIntegrationDelegate.CreateAndBegin(httpContext, scope); } catch (Exception ex) { // Dispose here, as the scope won't be in context items and won't get disposed on request end in that case... scope?.Dispose(); Log.Error(ex, "Datadog ASP.NET HttpModule instrumentation error"); } }
/// <summary> /// Gets a <see cref="ConcurrentDictionary{TKey, TValue}"/> containing all of the values. /// </summary> /// <remarks> /// Example JSON where `globalTags` is the configuration key. /// { /// "globalTags": { /// "name1": "value1", /// "name2": "value2" /// } /// } /// </remarks> /// <param name="key">The key that identifies the setting.</param> /// <returns><see cref="IDictionary{TKey, TValue}"/> containing all of the key-value pairs.</returns> /// <exception cref="JsonReaderException">Thrown if the configuration value is not a valid JSON string.</exception>" public IDictionary <string, string> GetDictionary(string key) { var token = _configuration.SelectToken(key, errorWhenNoMatch: false); if (token == null) { return(null); } if (token.Type == JTokenType.Object) { try { var dictionary = token ?.ToObject <ConcurrentDictionary <string, string> >(); return(dictionary); } catch (Exception e) { Log.Error(e, "Unable to parse configuration value for {0} as key-value pairs of strings.", key); return(null); } } return(StringConfigurationSource.ParseCustomKeyValues(token.ToString())); }
private bool DoesNotMatch(string input, string pattern) { try { if (pattern != null && !Regex.IsMatch( input: input, pattern: pattern, options: RegexOptions.None, matchTimeout: RegexTimeout)) { return(true); } } catch (RegexMatchTimeoutException timeoutEx) { _hasPoisonedRegex = true; Log.Error( timeoutEx, "Timeout when trying to match against {0} on {1}.", input, pattern); } return(false); }
// IMPORTANT: For all logging frameworks, do not set any default values for // "dd.trace_id" and "dd.span_id" when initializing the subscriber // because the Tracer may be initialized at a time when it is not safe // to add properties logging context of the underlying logging framework. // // Failure to abide by this can cause a SerializationException when // control is passed from one AppDomain to another where the originating // AppDomain used a logging framework that stored logging context properties // inside the System.Runtime.Remoting.Messaging.CallContext structure // but the target AppDomain is unable to de-serialize the object -- // this can easily happen if the target AppDomain cannot find/load the // logging framework assemblies. public LibLogScopeEventSubscriber(IScopeManager scopeManager) { _scopeManager = scopeManager; try { _logProvider = LogProvider.CurrentLogProvider ?? LogProvider.ResolveLogProvider(); if (_logProvider is SerilogLogProvider) { // Do not set default values for Serilog because it is unsafe to set // except at the application startup, but this would require auto-instrumentation _scopeManager.SpanOpened += StackOnSpanOpened; _scopeManager.SpanClosed += StackOnSpanClosed; } else { _scopeManager.SpanActivated += MapOnSpanActivated; _scopeManager.TraceEnded += MapOnTraceEnded; } } catch (Exception ex) { Log.Error(ex, "Could not successfully start the LibLogScopeEventSubscriber. There was an issue resolving the application logger."); } }
private async Task FlushTracesTaskLoopAsync() { while (true) { try { await Task.WhenAny(Task.Delay(TimeSpan.FromSeconds(1)), _processExit.Task) .ConfigureAwait(false); if (_processExit.Task.IsCompleted) { await FlushTracesAsync().ConfigureAwait(false); return; } else { await FlushTracesAsync().ConfigureAwait(false); } } catch (Exception ex) { Log.Error(ex, "An unhandled error occurred during the flushing task"); } } }
public static void ErrorRetrievingMethod( this Vendors.Serilog.ILogger logger, Exception exception, long moduleVersionPointer, int mdToken, int opCode, string instrumentedType, string methodName, string instanceType = null, string[] relevantArguments = null) { var instrumentedMethod = $"{instrumentedType}.{methodName}(...)"; if (instanceType != null) { instrumentedMethod = $"{instrumentedMethod} on {instanceType}"; } if (relevantArguments != null) { instrumentedMethod = $"{instrumentedMethod} with {string.Join(", ", relevantArguments)}"; } var moduleVersionId = PointerHelpers.GetGuidFromNativePointer(moduleVersionPointer); logger.Error( exception, $"Error (MVID: {moduleVersionId}, mdToken: {mdToken}, opCode: {opCode}) could not retrieve: {instrumentedMethod}"); }
public AzureAppServices(IDictionary environmentVariables) { try { IsRelevant = GetVariableIfExists(AzureAppServicesContextKey, environmentVariables)?.ToBoolean() ?? false; if (IsRelevant) { var apiKey = GetVariableIfExists(Configuration.ConfigurationKeys.ApiKey, environmentVariables); if (apiKey == null) { Log.Error("The Azure Site Extension will not work if you have not configured DD_API_KEY."); IsUnsafeToTrace = true; return; } // Azure App Services Basis SubscriptionId = GetSubscriptionId(environmentVariables); ResourceGroup = GetVariableIfExists(ResourceGroupKey, environmentVariables); SiteName = GetVariableIfExists(SiteNameKey, environmentVariables); ResourceId = CompileResourceId(); InstanceId = GetVariableIfExists(InstanceIdKey, environmentVariables); InstanceName = GetVariableIfExists(InstanceNameKey, environmentVariables); OperatingSystem = GetVariableIfExists(OperatingSystemKey, environmentVariables); // Functions FunctionsWorkerRuntime = GetVariableIfExists( FunctionsWorkerRuntimeKey, environmentVariables, i => AzureContext = AzureContext.AzureFunction); FunctionsExtensionVersion = GetVariableIfExists( FunctionsExtensionVersionKey, environmentVariables, i => AzureContext = AzureContext.AzureFunction); switch (AzureContext) { case AzureContext.AzureFunction: SiteKind = "functionapp"; SiteType = "function"; break; case AzureContext.AzureAppService: SiteKind = "app"; SiteType = "app"; break; } Runtime = FrameworkDescription.Instance.Name; } } catch (Exception ex) { IsUnsafeToTrace = true; Log.SafeLogError(ex, "Unable to initialize AzureAppServices metadata."); } }
private static SpanContext ExtractPropagatedContext(HttpRequest request) { try { // extract propagation details from http headers var requestHeaders = request.Headers; if (requestHeaders != null) { var headersCollection = new DictionaryHeadersCollection(); foreach (var header in requestHeaders) { string key = header.Key; string[] values = header.Value.ToArray(); if (key != null && values.Length > 0) { headersCollection.Add(key, values); } } return(B3SpanContextPropagator.Instance.Extract(headersCollection)); } } catch (Exception ex) { Log.Error(ex, "Error extracting propagated HTTP headers."); } return(null); }
public async Task SendTracesAsync(Span[][] traces) { // retry up to 5 times with exponential back-off var retryLimit = 5; var retryCount = 1; var sleepDuration = 100; // in milliseconds while (true) { HttpResponseMessage responseMessage; try { // re-create content on every retry because some versions of HttpClient always dispose of it, so we can't reuse. using (var content = new ZipkinContent(traces, _settings)) { responseMessage = await _client.PostAsync(_settings.EndpointUrl, content).ConfigureAwait(false); responseMessage.EnsureSuccessStatusCode(); return; } } catch (Exception ex) { #if DEBUG if (ex.InnerException is InvalidOperationException ioe) { Log.Error("An error occurred while sending traces to {Endpoint}\n{Exception}", ex, _settings.EndpointUrl, ex.ToString()); return; } #endif if (retryCount >= retryLimit) { // stop retrying Log.Error("An error occurred while sending traces to {Endpoint}", ex, _settings.EndpointUrl); return; } // retry await Task.Delay(sleepDuration).ConfigureAwait(false); retryCount++; sleepDuration *= 2; } } }
private static Scope CreateScope(object controllerContext) { Scope scope = null; try { if (!Tracer.Instance.Settings.IsIntegrationEnabled(IntegrationName)) { // integration disabled, don't create a scope, skip this trace return(null); } var tracer = Tracer.Instance; var request = controllerContext.GetProperty <HttpRequestMessage>("Request").GetValueOrDefault(); SpanContext propagatedContext = null; if (request != null && tracer.ActiveScope == null) { try { // extract propagated http headers var headers = request.Headers.Wrap(); propagatedContext = SpanContextPropagator.Instance.Extract(headers); } catch (Exception ex) { Log.Error(ex, "Error extracting propagated HTTP headers."); } } scope = tracer.StartActive(OperationName, propagatedContext); UpdateSpan(controllerContext, scope.Span); // set analytics sample rate if enabled var analyticsSampleRate = tracer.Settings.GetIntegrationAnalyticsSampleRate(IntegrationName, enabledWithGlobalSetting: true); scope.Span.SetMetric(Tags.Analytics, analyticsSampleRate); } catch (Exception ex) { Log.Error(ex, "Error creating scope."); } return(scope); }
void IObserver <KeyValuePair <string, object> > .OnNext(KeyValuePair <string, object> value) { try { OnNext(value.Key, value.Value); } catch (Exception ex) { Log.Error(ex, "Event Exception: {0}", value.Key); } }
/// <summary> /// Creates a scope for outbound http requests and populates some common details. /// </summary> /// <param name="tracer">The tracer instance to use to create the new scope.</param> /// <param name="httpMethod">The HTTP method used by the request.</param> /// <param name="requestUri">The URI requested by the request.</param> /// <param name="integrationName">The name of the integration creating this scope.</param> /// <returns>A new pre-populated scope.</returns> public static Scope CreateOutboundHttpScope(Tracer tracer, string httpMethod, Uri requestUri, string integrationName) { if (!tracer.Settings.IsIntegrationEnabled(integrationName)) { // integration disabled, don't create a scope, skip this trace return(null); } Scope scope = null; try { scope = tracer.StartActive(OperationName); var span = scope.Span; span.Type = SpanTypes.Http; span.ServiceName = $"{tracer.DefaultServiceName}-{ServiceName}"; span.ResourceName = string.Join( " ", httpMethod, UriHelpers.CleanUri(requestUri, removeScheme: true, tryRemoveIds: true)); span.SetTag(Tags.SpanKind, SpanKinds.Client); span.SetTag(Tags.HttpMethod, httpMethod?.ToUpperInvariant()); span.SetTag(Tags.HttpUrl, UriHelpers.CleanUri(requestUri, removeScheme: false, tryRemoveIds: false)); span.SetTag(Tags.InstrumentationName, integrationName); // set analytics sample rate if enabled var analyticsSampleRate = tracer.Settings.GetIntegrationAnalyticsSampleRate(integrationName, enabledWithGlobalSetting: false); span.SetMetric(Tags.Analytics, analyticsSampleRate); } catch (Exception ex) { Log.Error(ex, "Error creating or populating scope."); } // always returns the scope, even if it's null because we couldn't create it, // or we couldn't populate it completely (some tags is better than no tags) return(scope); }
public static Scope CreateScope(Tracer tracer, string integrationName, object pipeline, object requestData) { if (!tracer.Settings.IsIntegrationEnabled(integrationName)) { // integration disabled, don't create a scope, skip this trace return(null); } string requestName = pipeline.GetProperty("RequestParameters") .GetValueOrDefault() ?.GetType() .Name .Replace("RequestParameters", string.Empty); var pathAndQuery = requestData.GetProperty <string>("PathAndQuery").GetValueOrDefault() ?? requestData.GetProperty <string>("Path").GetValueOrDefault(); string method = requestData.GetProperty("Method").GetValueOrDefault()?.ToString(); var url = requestData.GetProperty("Uri").GetValueOrDefault()?.ToString(); var serviceName = $"{tracer.DefaultServiceName}-{ServiceName}"; Scope scope = null; try { var tags = new ElasticsearchTags(); scope = tracer.StartActiveWithTags(OperationName, serviceName: serviceName, tags: tags); var span = scope.Span; span.ResourceName = requestName ?? pathAndQuery ?? string.Empty; span.Type = SpanType; tags.InstrumentationName = ComponentValue; tags.SpanKind = SpanKinds.Client; tags.Action = requestName; tags.Method = method; tags.Url = url; // set analytics sample rate if enabled var analyticsSampleRate = tracer.Settings.GetIntegrationAnalyticsSampleRate(integrationName, enabledWithGlobalSetting: false); if (analyticsSampleRate != null) { tags.AnalyticsSampleRate = analyticsSampleRate; } } catch (Exception ex) { Log.Error(ex, "Error creating or populating scope."); } return(scope); }
public static int ExecuteNonQuery( object command, int opCode, int mdToken, long moduleVersionPtr) { Func <IDbCommand, int> instrumentedMethod; try { instrumentedMethod = MethodBuilder <Func <IDbCommand, int> > .Start(moduleVersionPtr, mdToken, opCode, AdoNetConstants.MethodNames.ExecuteNonQuery) .WithConcreteType(typeof(IDbCommand)) .WithNamespaceAndNameFilters(ClrNames.Int32) .Build(); } catch (Exception ex) { Log.Error(ex, $"Error resolving {DbCommandTypeName}.{AdoNetConstants.MethodNames.ExecuteNonQuery}(...)"); throw; } var dbCommand = command as IDbCommand; using (var scope = ScopeFactory.CreateDbCommandScope(Tracer.Instance, dbCommand, IntegrationName)) { try { return(instrumentedMethod(dbCommand)); } catch (Exception ex) { scope?.Span.SetException(ex); throw; } } }
private static FrameworkDescription CreateFromRuntimeInformation() { string frameworkName = null; string osPlatform = null; try { // RuntimeInformation.FrameworkDescription returns a string like ".NET Framework 4.7.2" or ".NET Core 2.1", // we want to return everything before the last space string frameworkDescription = RuntimeInformation.FrameworkDescription; int index = frameworkDescription.LastIndexOf(' '); frameworkName = frameworkDescription.Substring(0, index).Trim(); } catch (Exception e) { Log.Error(e, "Error getting framework name from RuntimeInformation"); } if (RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows)) { osPlatform = "Windows"; } else if (RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Linux)) { osPlatform = "Linux"; } else if (RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.OSX)) { osPlatform = "MacOS"; } return(new FrameworkDescription( frameworkName ?? "unknown", GetNetCoreVersion() ?? "unknown", osPlatform ?? "unknown", RuntimeInformation.OSArchitecture.ToString().ToLowerInvariant(), RuntimeInformation.ProcessArchitecture.ToString().ToLowerInvariant())); }
/// <summary> /// Gets an "application name" for the executing application by looking at /// the hosted app name (.NET Framework on IIS only), assembly name, and process name. /// </summary> /// <returns>The default service name.</returns> private static string GetApplicationName() { try { #if !NETSTANDARD2_0 // System.Web.dll is only available on .NET Framework if (System.Web.Hosting.HostingEnvironment.IsHosted) { // if this app is an ASP.NET application, return "SiteName/ApplicationVirtualPath". // note that ApplicationVirtualPath includes a leading slash. return((System.Web.Hosting.HostingEnvironment.SiteName + System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath).TrimEnd('/')); } #endif return(Assembly.GetEntryAssembly()?.GetName().Name ?? Process.GetCurrentProcess().ProcessName); } catch (Exception ex) { Log.Error(ex, "Error creating default service name."); return(null); } }
internal static Scope CreateScope(Tracer tracer, string integrationName, string host, string port, string rawCommand) { if (!Tracer.Instance.Settings.IsIntegrationEnabled(integrationName)) { // integration disabled, don't create a scope, skip this trace return(null); } string serviceName = $"{tracer.DefaultServiceName}-{ServiceName}"; Scope scope = null; try { var tags = new RedisTags(); scope = tracer.StartActiveWithTags(OperationName, serviceName: serviceName, tags: tags); int separatorIndex = rawCommand.IndexOf(' '); string command; if (separatorIndex >= 0) { command = rawCommand.Substring(0, separatorIndex); } else { command = rawCommand; } var span = scope.Span; span.Type = SpanTypes.Redis; span.ResourceName = command; tags.RawCommand = rawCommand; tags.Host = host; tags.Port = port; // set analytics sample rate if enabled var analyticsSampleRate = tracer.Settings.GetIntegrationAnalyticsSampleRate(integrationName, enabledWithGlobalSetting: false); if (analyticsSampleRate != null) { tags.AnalyticsSampleRate = analyticsSampleRate; } } catch (Exception ex) { Log.Error(ex, "Error creating or populating scope."); } return(scope); }
public static Module Get(Guid moduleVersionId) { // First attempt at cached values with no blocking if (_modules.TryGetValue(moduleVersionId, out Module value)) { return(value); } // Block if a population event is happening _populationResetEvent.Wait(); // See if the previous population event populated what we need if (_modules.TryGetValue(moduleVersionId, out value)) { return(value); } if (_failures >= MaxFailures) { // For some unforeseeable reason we have failed on a lot of AppDomain lookups if (!_shortCircuitLogicHasLogged) { Log.Warning("Datadog is unable to continue attempting module lookups for this AppDomain. Falling back to legacy method lookups."); } return(null); } // Block threads on this event _populationResetEvent.Reset(); try { PopulateModules(); } catch (Exception ex) { _failures++; Log.Error(ex, "Error when populating modules."); } finally { // Continue threads blocked on this event _populationResetEvent.Set(); } _modules.TryGetValue(moduleVersionId, out value); return(value); }
private string CompileResourceId() { string resourceId = null; try { var success = true; if (SubscriptionId == null) { success = false; Log.Warning("Could not successfully retrieve the subscription ID from variable: {0}", WebsiteOwnerNameKey); } if (SiteName == null) { success = false; Log.Warning("Could not successfully retrieve the deployment ID from variable: {0}", SiteNameKey); } if (ResourceGroup == null) { success = false; Log.Warning("Could not successfully retrieve the resource group name from variable: {0}", ResourceGroupKey); } if (success) { resourceId = $"/subscriptions/{SubscriptionId}/resourcegroups/{ResourceGroup}/providers/microsoft.web/sites/{SiteName}".ToLowerInvariant(); } } catch (Exception ex) { Log.Error(ex, "Could not successfully setup the resource id for azure app services."); } return(resourceId); }
internal static Scope CreateScope(Tracer tracer, string integrationName, string componentName, string host, string port, string rawCommand) { if (!Tracer.Instance.Settings.IsIntegrationEnabled(integrationName)) { // integration disabled, don't create a scope, skip this trace return(null); } Scope scope = null; try { int separatorIndex = rawCommand.IndexOf(' '); string command; if (separatorIndex >= 0) { command = rawCommand.Substring(0, separatorIndex); } else { command = rawCommand; } scope = tracer.StartActive(command ?? OperationName, serviceName: tracer.DefaultServiceName); var span = scope.Span; span.SetTag(Tags.InstrumentationName, componentName); span.SetTag(Tags.DbType, SpanTypes.Redis); span.SetTag(Tags.SpanKind, SpanKinds.Client); if (Tracer.Instance.Settings.TagRedisCommands) { span.SetTag(Tags.DbStatement, rawCommand); } span.SetTag(Tags.OutHost, host); span.SetTag(Tags.OutPort, port); // set analytics sample rate if enabled var analyticsSampleRate = tracer.Settings.GetIntegrationAnalyticsSampleRate(integrationName, enabledWithGlobalSetting: false); span.SetMetric(Tags.Analytics, analyticsSampleRate); } catch (Exception ex) { Log.Error(ex, "Error creating or populating scope."); } return(scope); }
void IObserver <KeyValuePair <string, object> > .OnNext(KeyValuePair <string, object> value) { try { OnNext(value.Key, value.Value); } catch (Exception ex) { Log.Error(ex, "Event Exception: {0}", value.Key); #if DEBUG // In debug mode we allow exceptions to be catch in the test suite throw; #endif } }
/// <summary> /// Entry method for invoking the beginning of every web server request pipeline /// </summary> /// <param name="httpContext">Instance being instrumented.</param> /// <param name="features">Initialize features.</param> /// <param name="opCode">The OpCode used in the original method call.</param> /// <param name="mdToken">The mdToken of the original method call.</param> /// <param name="moduleVersionPtr">A pointer to the module version GUID.</param> // [InterceptMethod( // TargetAssembly = "Microsoft.AspNetCore.Http.Abstractions", // TargetType = DefaultHttpContextTypeName, // TargetSignatureTypes = new[] { ClrNames.Void, ClrNames.Ignore })] // *************************************************************** // DISABLED UNTIL WE FIX SCOPING ISSUES AT HTTP CONTEXT LEVEL // *************************************************************** public static void Initialize(object httpContext, object features, int opCode, int mdToken, long moduleVersionPtr) { if (httpContext == null) { throw new ArgumentNullException(nameof(httpContext)); } var httpContextType = httpContext.GetInstrumentedType(DefaultHttpContextTypeName); Action <object, object> instrumentedMethod; try { instrumentedMethod = MethodBuilder <Action <object, object> > .Start(moduleVersionPtr, mdToken, opCode, nameof(Initialize)) .WithConcreteType(httpContextType) .WithParameters(features) .Build(); } catch (Exception ex) { Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: DefaultHttpContextTypeName, methodName: nameof(Initialize), instanceType: httpContext.GetType().AssemblyQualifiedName); throw; } try { instrumentedMethod.Invoke(httpContext, features); } catch (Exception ex) { Log.Error(ex, $"Error calling {DefaultHttpContextTypeName}.{nameof(Initialize)}(...)"); throw; } if (Tracer.Instance.Settings.IsIntegrationEnabled(IntegrationName)) { AspNetAmbientContext.Initialize(httpContext); } }
public static Scope CreateScope(Tracer tracer, string integrationName, object pipeline, object requestData) { if (!tracer.Settings.IsIntegrationEnabled(integrationName)) { // integration disabled, don't create a scope, skip this trace return(null); } string requestName = pipeline.GetProperty("RequestParameters") .GetValueOrDefault() ?.GetType() .Name .Replace("RequestParameters", string.Empty); var pathAndQuery = requestData.GetProperty <string>("PathAndQuery").GetValueOrDefault() ?? requestData.GetProperty <string>("Path").GetValueOrDefault(); string method = requestData.GetProperty("Method").GetValueOrDefault()?.ToString(); var url = requestData.GetProperty("Uri").GetValueOrDefault()?.ToString(); var serviceName = string.Join("-", tracer.DefaultServiceName, ServiceName); Scope scope = null; try { scope = tracer.StartActive(OperationName, serviceName: serviceName); var span = scope.Span; span.ResourceName = requestName ?? pathAndQuery ?? string.Empty; span.Type = SpanType; span.SetTag(Tags.InstrumentationName, ComponentValue); span.SetTag(Tags.SpanKind, SpanKinds.Client); span.SetTag(ElasticsearchActionKey, requestName); span.SetTag(ElasticsearchMethodKey, method); span.SetTag(ElasticsearchUrlKey, url); // set analytics sample rate if enabled var analyticsSampleRate = tracer.Settings.GetIntegrationAnalyticsSampleRate(integrationName, enabledWithGlobalSetting: false); span.SetMetric(Tags.Analytics, analyticsSampleRate); } catch (Exception ex) { Log.Error(ex, "Error creating or populating scope."); } return(scope); }
internal static Scope CreateScope(Tracer tracer, string integrationName, string host, string port, string rawCommand) { if (!Tracer.Instance.Settings.IsIntegrationEnabled(integrationName)) { // integration disabled, don't create a scope, skip this trace return(null); } string serviceName = string.Join("-", tracer.DefaultServiceName, ServiceName); Scope scope = null; try { scope = tracer.StartActive(OperationName, serviceName: serviceName); int separatorIndex = rawCommand.IndexOf(' '); string command; if (separatorIndex >= 0) { command = rawCommand.Substring(0, separatorIndex); } else { command = rawCommand; } var span = scope.Span; span.Type = SpanTypes.Redis; span.ResourceName = command; span.SetTag(Tags.RedisRawCommand, rawCommand); span.SetTag(Tags.OutHost, host); span.SetTag(Tags.OutPort, port); // set analytics sample rate if enabled var analyticsSampleRate = tracer.Settings.GetIntegrationAnalyticsSampleRate(integrationName, enabledWithGlobalSetting: false); span.SetMetric(Tags.Analytics, analyticsSampleRate); } catch (Exception ex) { Log.Error(ex, "Error creating or populating scope."); } return(scope); }
public static object ExecuteReader( object command, int opCode, int mdToken, long moduleVersionPtr) { Func <object, object> instrumentedMethod; try { var targetType = command.GetInstrumentedType(NpgsqlCommandTypeName); instrumentedMethod = MethodBuilder <Func <object, object> > .Start(moduleVersionPtr, mdToken, opCode, AdoNetConstants.MethodNames.ExecuteReader) .WithConcreteType(targetType) .WithNamespaceAndNameFilters(NpgsqlDataReaderTypeName) .Build(); } catch (Exception ex) { Log.Error(ex, $"Error resolving {NpgsqlCommandTypeName}.{AdoNetConstants.MethodNames.ExecuteReader}(...)"); throw; } using (var scope = ScopeFactory.CreateDbCommandScope(Tracer.Instance, command as DbCommand, IntegrationName)) { try { return(instrumentedMethod(command)); } catch (Exception ex) { scope?.Span.SetException(ex); throw; } } }