Ejemplo n.º 1
0
        private async Task <string> LoadInstrumentationKey()
        {
            //if the AI key is specified in the Telimena Portal, it should override the local one
            //however, checking if it is specified in Telimena will take time, and we are inside a constructor here - we don't want to block
            string key = null;

            try
            {
                using (HttpClient client = new HttpClient()
                {
                    BaseAddress = this.telimenaProperties.TelemetryApiBaseUrl
                })
                {
                    HttpResponseMessage response = await client.GetAsync(ApiRoutes.GetInstrumentationKey(this.telimenaProperties.TelemetryKey));

                    key = await response.Content.ReadAsStringAsync();

                    response.EnsureSuccessStatusCode();
                    return(key?.Trim('"'));
                }
            }
            catch (Exception ex)
            {
                TelemetryDebugWriter.WriteError($"Error while loading instrumentation key. Error: {ex}. Response: {key}");
                return(null);
            }
        }
        public async Task <string> GetUserTrackingSettings(Guid telemetryKey)
        {
            string stringified = null;

            try
            {
                using (HttpClient client = new HttpClient()
                {
                    BaseAddress = this.baseUrl
                })
                {
                    HttpResponseMessage response = await client.GetAsync(ApiRoutes.GetTelemetrySettings(telemetryKey));

                    stringified = await response.Content.ReadAsStringAsync();

                    response.EnsureSuccessStatusCode();
                    return(stringified);
                }
            }
            catch (Exception ex)
            {
                TelemetryDebugWriter.WriteError($"Error while loading instrumentation key. Error: {ex}. Response: {stringified}");
                return(null);
            }
        }
 private void LogResult(HttpWebResponseWrapper response, string endpoint)
 {
     if (response.StatusCode < 200 || response.StatusCode >= 300)
     {
         TelemetryDebugWriter.WriteLine($"Error while transmitting telemetry to {endpoint}. Status code: {response.StatusCode}. Description: [{response.StatusDescription}]. {response.Content}");
     }
 }
        public void Track(ITelemetry telemetry)
        {
            // TALK TO YOUR TEAM MATES BEFORE CHANGING THIS.
            // This method needs to be public so that we can build and ship new telemetry types without having to ship core.
            // It is hidden from intellisense to prevent customer confusion.
            if (this.IsEnabled())
            {
                this.Initialize(telemetry);

                if (string.IsNullOrEmpty(telemetry.Context.InstrumentationKey))
                {
                    TelemetryDebugWriter.WriteTelemetry(telemetry);
                    return;
                }

                // If someone created configuration from scratch and forgot to initialize channel - use default
                if (this.configuration.TelemetryChannel == null)
                {
                    this.configuration.TelemetryChannel = new InMemoryChannel();
                }

                // invokes the Process in the first processor in the chain
                this.configuration.TelemetryProcessorChain.Process(telemetry);

#if !CORE_PCL
                // logs rich payload ETW event for any partners to process it
                RichPayloadEventSource.Log.Process(telemetry);
#endif
            }
        }
Ejemplo n.º 5
0
        public TelemetryClient GetClient()
        {
            try
            {
                lock (this.telemetryClientBuildingLock)
                {
                    TelemetryConfiguration config = TelemetryConfiguration.Active;

                    this.LoadTelemetryChannel(config);

                    this.LoadInitializers(config);

                    var client = new TelemetryClient(config);

                    this.InitializeContext(client);

                    if (this.properties.InstrumentationKey != null)
                    {
                        config.InstrumentationKey = this.properties.InstrumentationKey;
                        client.InstrumentationKey = this.properties.InstrumentationKey;
                    }
                    return(client);
                }
            }
            catch (Exception e)
            {
                TelemetryDebugWriter.WriteLine($"Failed to load {nameof(TelemetryClient)}. Error: {e}");
                return(null);
            }
        }
Ejemplo n.º 6
0
 private void LogResult(HttpWebResponseWrapper response)
 {
     if (response.StatusCode < 200 || response.StatusCode >= 300)
     {
         TelemetryDebugWriter.WriteLine($"Status code: {response.StatusCode}. Description: [{response.StatusDescription}]. {response.Content}");
     }
 }
Ejemplo n.º 7
0
        internal Telimena(ITelimenaStartupInfo startupInfo)
        {
            try
            {
                this.SetConnectionSecurityProtocol();

                this.propertiesInternal = new TelimenaProperties(startupInfo);
                this.Locator            = new Locator(this.Properties.StaticProgramInfo);

                this.telemetryModule = new TelemetryModule(this.Properties);
                this.updates         = new UpdatesModule(this);

                this.httpClient = new TelimenaHttpClient(new HttpClient
                {
                    BaseAddress = this.propertiesInternal.StartupInfo.TelemetryApiBaseUrl
                });
                this.Messenger = new Messenger(this.Serializer, this.httpClient);

                ((TelemetryModule)this.telemetryModule).InitializeTelemetryClient();
                if (startupInfo.RegisterUnhandledExceptionsTracking)
                {
                    AppDomain.CurrentDomain.UnhandledException += this.CurrentDomain_UnhandledException;
                }
            }
            catch (Exception e)
            {
                TelemetryDebugWriter.WriteLine($"Error while initializing {nameof(Telimena)}. Error: {e}");
                //above all, we don't want to throw errors in client apps.
                //No telemetry is better than boom.
                throw;
            }
        }
Ejemplo n.º 8
0
        private void StoreSettings(UserTrackingSettings settings)
        {
            try
            {
                string stringified = this.serializer.Serialize(settings);

                string path = Path.Combine(this.locator.GetWorkingDirectory().FullName, TrackingSettingsFileName);
                File.WriteAllText(path, stringified);
            }
            catch (Exception ex)
            {
                TelemetryDebugWriter.WriteError("Error while storing user tracking settings: " + ex);
            }
        }
Ejemplo n.º 9
0
 private UserTrackingSettings Deserialize(string serializedSettings)
 {
     if (string.IsNullOrEmpty(serializedSettings))
     {
         return(null);
     }
     try
     {
         return(this.serializer.Deserialize <UserTrackingSettings>(serializedSettings));
     }
     catch (Exception ex)
     {
         TelemetryDebugWriter.WriteError("Error while deserializing user tracking settings: " + ex);
         return(null);
     }
 }
Ejemplo n.º 10
0
 private UserTrackingSettings GetStoredSettings()
 {
     try
     {
         string path = Path.Combine(this.locator.GetWorkingDirectory().FullName, TrackingSettingsFileName);
         if (File.Exists(path))
         {
             var stringified = File.ReadAllText(path);
             return(this.serializer.Deserialize <UserTrackingSettings>(stringified));
         }
     }
     catch (Exception ex)
     {
         TelemetryDebugWriter.WriteError("Error while restoring user tracking settings: " + ex);
     }
     return(null);
 }
        /// <summary>
        /// Process a collected telemetry item.
        /// </summary>
        /// <param name="item">A collected Telemetry item.</param>
        public void Process(ITelemetry item)
        {
            if (this.SamplingPercentage < 100.0 - 1.0E-12)
            {
                var samplingSupportingTelemetry = item as ISupportSampling;

                if (samplingSupportingTelemetry != null)
                {
                    var excludedTypesHashSetRef = this.excludedTypesHashSet;
                    var includedTypesHashSetRef = this.includedTypesHashSet;

                    if (excludedTypesHashSetRef.Count > 0 && excludedTypesHashSetRef.Contains(item.GetType()))
                    {
                        if (TelemetryChannelEventSource.Log.IsVerboseEnabled)
                        {
                            TelemetryChannelEventSource.Log.SamplingSkippedByType(item.ToString());
                        }
                    }
                    else if (includedTypesHashSetRef.Count > 0 && !includedTypesHashSetRef.Contains(item.GetType()))
                    {
                        if (TelemetryChannelEventSource.Log.IsVerboseEnabled)
                        {
                            TelemetryChannelEventSource.Log.SamplingSkippedByType(item.ToString());
                        }
                    }
                    else if (!samplingSupportingTelemetry.SamplingPercentage.HasValue)
                    {
                        samplingSupportingTelemetry.SamplingPercentage = this.SamplingPercentage;

                        if (!this.IsSampledIn(item))
                        {
                            if (TelemetryChannelEventSource.Log.IsVerboseEnabled)
                            {
                                TelemetryChannelEventSource.Log.ItemSampledOut(item.ToString());
                            }

                            TelemetryDebugWriter.WriteTelemetry(item, this.GetType().Name);
                            return;
                        }
                    }
                }
            }

            this.Next.Process(item);
        }
Ejemplo n.º 12
0
        private static Uri GetTelemetryUriFromConfig(Uri telemetryApiBaseUrl)
        {
            var setting = ConfigurationManager.AppSettings.Get(TelimenaUrlSettingsKey);

            if (!string.IsNullOrEmpty(setting))
            {
                try
                {
                    var uri = new Uri(setting);
                    return(uri);
                }
                catch (Exception ex)
                {
                    TelemetryDebugWriter.WriteLine($"ERROR - Cannot convert AppSetting [{setting}] to URI. Telimena will NOT WORK. Error: {ex}");
                }
            }
            var path = Path.Combine(Directory.GetCurrentDirectory(), TelimenaUrlSettingsKey);

            if (File.Exists(path))
            {
                var text = File.ReadAllText(path);
                try
                {
                    var uri = new Uri(text);
                    return(uri);
                }
                catch (Exception ex)
                {
                    TelemetryDebugWriter.WriteError($"ERROR - Cannot convert content of file {path} - [{text}] to URI. Telimena will NOT WORK. Error: {ex}");
                    return(null);
                }
            }

            if (telemetryApiBaseUrl == null)
            {
                string message = $"ERROR - Telimena URL not specified. " +
                                 $"Either add AppSetting [{TelimenaUrlSettingsKey}] or create a [{TelimenaUrlSettingsKey}] file in your app working directory." +
                                 $"The setting value/file content should be JUST THE BASE URL to Telimena instance.";
                TelemetryDebugWriter.WriteError(message);
            }


            return(null);
        }
Ejemplo n.º 13
0
        private void SetUserIdentifier(UserInfo value, string fileName, bool shared)
        {
            var directory = this.locator.GetWorkingDirectory();

            if (shared)
            {
                directory = directory.Parent;
            }
            try
            {
                string filePath = Path.Combine(directory.FullName, fileName);
                var    lines    = new string[] { value.UserIdentifier, value.MachineName };

                File.WriteAllLines(filePath, lines);
            }
            catch (Exception e)
            {
                //thats bad, but maybe it will succeed next time. Impact is smaller than throwing an error.
                TelemetryDebugWriter.WriteError($"Error while storing user identifier. Error: {e}");
            }
        }
        /// <summary>
        /// Process a collected telemetry item.
        /// </summary>
        /// <param name="item">A collected Telemetry item.</param>
        public void Process(ITelemetry item)
        {
            if (this.SamplingPercentage < 100.0 - 1.0E-12)
            {
                var samplingSupportingTelemetry = item as ISupportSampling;

                if (samplingSupportingTelemetry != null)
                {
                    var excludedTypesHashSetRef = this.excludedTypesHashSet;
                    if (excludedTypesHashSetRef.Count > 0 && excludedTypesHashSetRef.Contains(item.GetType()))
                    {
                        if (TelemetryChannelEventSource.Log.IsVerboseEnabled)
                        {
                            TelemetryChannelEventSource.Log.SamplingSkippedByType(item.ToString());
                        }
                    }
                    else
                    {
                        // set sampling percentage on telemetry item, current codebase assumes it is the only one updating SamplingPercentage.
                        samplingSupportingTelemetry.SamplingPercentage = this.SamplingPercentage;

                        if (!this.IsSampledIn(item))
                        {
                            if (TelemetryChannelEventSource.Log.IsVerboseEnabled)
                            {
                                TelemetryChannelEventSource.Log.ItemSampledOut(item.ToString());
                            }

                            TelemetryDebugWriter.WriteTelemetry(item, this.GetType().Name);
                            return;
                        }
                    }
                }
            }

            this.Next.Process(item);
        }
        /// <summary>
        /// Process a collected telemetry item.
        /// </summary>
        /// <param name="item">A collected Telemetry item.</param>
        public void Process(ITelemetry item)
        {
            double samplingPercentage = this.SamplingPercentage;

            //// If sampling rate is 100% and we aren't distinguishing between evaluated/unevaluated items, there is nothing to do:
            if (samplingPercentage >= 100.0 - 1.0E-12 && this.SampledNext.Equals(this.UnsampledNext))
            {
                this.HandlePossibleProactiveSampling(item, samplingPercentage);
                return;
            }

            //// So sampling rate is not 100%, or we must evaluate further

            var advancedSamplingSupportingTelemetry = item as ISupportAdvancedSampling;

            // If someone implemented ISupportSampling and hopes that SamplingTelemetryProcessor will continue to work for them:
            var samplingSupportingTelemetry = advancedSamplingSupportingTelemetry ?? item as ISupportSampling;

            //// If null was passed in as item or if sampling not supported in general, do nothing:
            if (samplingSupportingTelemetry == null)
            {
                this.UnsampledNext.Process(item);
                return;
            }

            //// If telemetry was excluded by type, do nothing:
            if (advancedSamplingSupportingTelemetry != null && !this.IsSamplingApplicable(advancedSamplingSupportingTelemetry.ItemTypeFlag))
            {
                if (TelemetryChannelEventSource.IsVerboseEnabled)
                {
                    TelemetryChannelEventSource.Log.SamplingSkippedByType(item.ToString());
                }

                this.UnsampledNext.Process(item);
                return;
            }

            //// If telemetry was already sampled, do nothing:
            bool itemAlreadySampled = samplingSupportingTelemetry.SamplingPercentage.HasValue;

            if (itemAlreadySampled)
            {
                this.UnsampledNext.Process(item);
                return;
            }

            //// Ok, now we can actually sample:

            samplingSupportingTelemetry.SamplingPercentage = samplingPercentage;

            bool isSampledIn;

            // if this is executed in adaptive sampling processor (rate ratio has value),
            // and item supports proactive sampling and was sampled in before, we'll give it more weight
            if (this.ProactiveSamplingPercentage.HasValue &&
                advancedSamplingSupportingTelemetry != null &&
                advancedSamplingSupportingTelemetry.ProactiveSamplingDecision == SamplingDecision.SampledIn)
            {
                // if current rate of proactively sampled-in telemetry is too high, ProactiveSamplingPercentage is low:
                // we'll sample in as much proactively sampled in items as we can (based on their sampling score)
                // so that we still keep target rate.
                // if current rate of proactively sampled-in telemetry is less that configured, ProactiveSamplingPercentage
                // is high - it could be > 100 - and we'll sample in all items with proactive SampledIn decision (plus some more in else branch).
                isSampledIn = SamplingScoreGenerator.GetSamplingScore(item) < this.ProactiveSamplingPercentage;
            }
            else
            {
                isSampledIn = SamplingScoreGenerator.GetSamplingScore(item) < samplingPercentage;
            }

            if (isSampledIn)
            {
                if (advancedSamplingSupportingTelemetry != null)
                {
                    this.HandlePossibleProactiveSampling(item, samplingPercentage, advancedSamplingSupportingTelemetry);
                }
                else
                {
                    this.SampledNext.Process(item);
                }
            }
            else
            {
                if (TelemetryChannelEventSource.IsVerboseEnabled)
                {
                    TelemetryChannelEventSource.Log.ItemSampledOut(item.ToString());
                }

                TelemetryDebugWriter.WriteTelemetry(item, nameof(SamplingTelemetryProcessor));
            }
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Process a collected telemetry item.
        /// </summary>
        /// <param name="item">A collected Telemetry item.</param>
        public void Process(ITelemetry item)
        {
            double samplingPercentage = this.SamplingPercentage;

            //// If sampling rate is 100% and we aren't distinguishing between evaluated/unevaluated items, there is nothing to do:
            if (this.SampledNext.Equals(this.UnsampledNext) && samplingPercentage >= 100.0 - 1.0E-12)
            {
                this.SampledNext.Process(item);
                return;
            }

            //// So sampling rate is not 100%, or we must evaluate further

            //// If null was passed in as item or if sampling not supported in general, do nothing:
            var samplingSupportingTelemetry = item as ISupportSampling;

            if (samplingSupportingTelemetry == null)
            {
                this.UnsampledNext.Process(item);
                return;
            }

            //// If telemetry was excluded by type, do nothing:
            if (!this.IsSamplingApplicable(item.GetType()))
            {
                if (TelemetryChannelEventSource.IsVerboseEnabled)
                {
                    TelemetryChannelEventSource.Log.SamplingSkippedByType(item.ToString());
                }

                this.UnsampledNext.Process(item);
                return;
            }

            //// If telemetry was already sampled, do nothing:
            bool itemAlreadySampled = samplingSupportingTelemetry.SamplingPercentage.HasValue;

            if (itemAlreadySampled)
            {
                this.UnsampledNext.Process(item);
                return;
            }

            //// Ok, now we can actually sample:

            samplingSupportingTelemetry.SamplingPercentage = samplingPercentage;
            bool isSampledIn = SamplingScoreGenerator.GetSamplingScore(item) < samplingPercentage;

            if (isSampledIn)
            {
                this.SampledNext.Process(item);
            }
            else
            {
                if (TelemetryChannelEventSource.IsVerboseEnabled)
                {
                    TelemetryChannelEventSource.Log.ItemSampledOut(item.ToString());
                }

                TelemetryDebugWriter.WriteTelemetry(item, this.GetType().Name);
            }
        }
        /// <summary>
        /// Initializes/Adds operation id to the existing telemetry item.
        /// </summary>
        /// <param name="telemetryItem">Target telemetry item to add operation id.</param>
        public void Initialize(ITelemetry telemetryItem)
        {
            try
            {
                var  itemContext         = telemetryItem.Context.Operation;
                var  telemetryProp       = telemetryItem as ISupportProperties;
                bool isActivityAvailable = false;
                isActivityAvailable = ActivityExtensions.TryRun(() =>
                {
                    var currentActivity = Activity.Current;
                    if (currentActivity != null)
                    {
                        if (string.IsNullOrEmpty(itemContext.Id))
                        {
                            itemContext.Id = currentActivity.RootId;

                            if (string.IsNullOrEmpty(itemContext.ParentId))
                            {
                                itemContext.ParentId = currentActivity.Id;
                            }

                            foreach (var baggage in currentActivity.Baggage)
                            {
                                if (telemetryProp != null && !telemetryProp.Properties.ContainsKey(baggage.Key))
                                {
                                    telemetryProp.Properties.Add(baggage);
                                }
                            }
                        }

                        string operationName = currentActivity.GetOperationName();

                        if (string.IsNullOrEmpty(itemContext.Name) && !string.IsNullOrEmpty(operationName))
                        {
                            itemContext.Name = operationName;
                        }
                    }
                });

                if (!isActivityAvailable)
                {
                    if (string.IsNullOrEmpty(itemContext.ParentId) || string.IsNullOrEmpty(itemContext.Id) ||
                        string.IsNullOrEmpty(itemContext.Name))
                    {
                        var parentContext = CallContextHelpers.GetCurrentOperationContext();
                        if (parentContext != null)
                        {
                            if (string.IsNullOrEmpty(itemContext.ParentId) &&
                                !string.IsNullOrEmpty(parentContext.ParentOperationId))
                            {
                                itemContext.ParentId = parentContext.ParentOperationId;
                            }

                            if (string.IsNullOrEmpty(itemContext.Id) &&
                                !string.IsNullOrEmpty(parentContext.RootOperationId))
                            {
                                itemContext.Id = parentContext.RootOperationId;
                            }

                            if (string.IsNullOrEmpty(itemContext.Name) &&
                                !string.IsNullOrEmpty(parentContext.RootOperationName))
                            {
                                itemContext.Name = parentContext.RootOperationName;
                            }

                            if (parentContext.CorrelationContext != null)
                            {
                                foreach (var item in parentContext.CorrelationContext)
                                {
                                    if (telemetryProp != null && !telemetryProp.Properties.ContainsKey(item.Key))
                                    {
                                        telemetryProp.Properties.Add(item);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                TelemetryDebugWriter.WriteLine(
                    "Something went wrong when initializing [" + this.GetType().Name + "]. This initializer will be ignored." + ex);
            }
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Process a collected telemetry item.
        /// </summary>
        /// <param name="item">A collected Telemetry item.</param>
        public void Process(ITelemetry item)
        {
            double samplingPercentage = this.SamplingPercentage;

            //// If sampling rate is 100% and we aren't distinguishing between evaluated/unevaluated items, there is nothing to do:
            if (samplingPercentage >= 100.0 - 1.0E-12 && this.SampledNext.Equals(this.UnsampledNext))
            {
                this.HandlePossibleProactiveSampling(item, samplingPercentage);
                return;
            }

            //// So sampling rate is not 100%, or we must evaluate further

            var advancedSamplingSupportingTelemetry = item as ISupportAdvancedSampling;

            // If someone implemented ISupportSampling and hopes that SamplingTelemetryProcessor will continue to work for them:
            var samplingSupportingTelemetry = advancedSamplingSupportingTelemetry ?? item as ISupportSampling;

            //// If null was passed in as item or if sampling not supported in general, do nothing:
            if (samplingSupportingTelemetry == null)
            {
                this.UnsampledNext.Process(item);
                return;
            }

            //// If telemetry was excluded by type, do nothing:
            if (advancedSamplingSupportingTelemetry != null && !this.IsSamplingApplicable(advancedSamplingSupportingTelemetry.ItemTypeFlag))
            {
                if (TelemetryChannelEventSource.IsVerboseEnabled)
                {
                    TelemetryChannelEventSource.Log.SamplingSkippedByType(item.ToString());
                }

                this.UnsampledNext.Process(item);
                return;
            }

            //// If telemetry was already sampled, do nothing:
            bool itemAlreadySampled = samplingSupportingTelemetry.SamplingPercentage.HasValue;

            if (itemAlreadySampled)
            {
                this.UnsampledNext.Process(item);
                return;
            }

            //// Ok, now we can actually sample:

            samplingSupportingTelemetry.SamplingPercentage = samplingPercentage;
            bool isSampledIn = SamplingScoreGenerator.GetSamplingScore(item) < samplingPercentage;

            if (isSampledIn)
            {
                if (advancedSamplingSupportingTelemetry != null)
                {
                    this.HandlePossibleProactiveSampling(item, samplingPercentage, advancedSamplingSupportingTelemetry);
                }
                else
                {
                    this.SampledNext.Process(item);
                }
            }
            else
            {
                if (TelemetryChannelEventSource.IsVerboseEnabled)
                {
                    TelemetryChannelEventSource.Log.ItemSampledOut(item.ToString());
                }

                TelemetryDebugWriter.WriteTelemetry(item, nameof(SamplingTelemetryProcessor));
            }
        }