<commit_before>#region Copyright 2014 Exceptionless

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// 
//     http://www.apache.org/licenses/LICENSE-2.0

#endregion

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Security;
using System.Text;
using System.Threading;
using Exceptionless.ExtendedData;
using Exceptionless.Extensions;
using Exceptionless.Logging;
using Exceptionless.Models;
using Exceptionless.Net;
using Exceptionless.Plugins;
using Exceptionless.Queue;
using Exceptionless.Utility;
#if !PFX_LEGACY_3_5
using System.Threading.Tasks;
#endif
#if !SILVERLIGHT
using Exceptionless.Diagnostics;
#endif
using Config = Exceptionless.Configuration;

namespace Exceptionless {
    /// <summary>
    /// A class used to interact with the Exceptionless service.
    /// </summary>
    public class ExceptionlessClient : DisposableBase, IConfigurationAndLogAccessor {
        public const int ApiRevision = 1;

        private const string API_URI_FORMAT = "/api/v{0}/";

        private bool _updatingConfiguration;
        private readonly Timer _queueTimer;
        private bool _isProcessQueueScheduled;
        private ILastErrorIdManager _lastErrorIdManager;
        private static volatile bool _processingQueue;
        private static readonly object _queueLock = new object();
        private readonly ObservableConcurrentDictionary<string, IExceptionlessPlugin> _plugins = new ObservableConcurrentDictionary<string, IExceptionlessPlugin>();
        private IExceptionlessLog _log;
        private static readonly IExceptionlessLog _nullLogger = new NullExceptionlessLog();

        #region Events

        /// <summary>
        /// Occurs when the configuration updated.
        /// </summary>
        public event EventHandler<ConfigurationUpdatedEventArgs> ConfigurationUpdated;

        /// <summary>
        /// Raises the <see cref="ConfigurationUpdated" /> event.
        /// </summary>
        /// <param name="e">The <see cref="ConfigurationUpdatedEventArgs" /> instance containing the event data.</param>
        protected void OnConfigurationUpdated(ConfigurationUpdatedEventArgs e) {
            if (e.Error != null)
                Log.FormattedError(typeof(ExceptionlessClient), "Error updating configuration: {0}", e.Error.Message);
            else if (e.Configuration != null)
                Log.FormattedInfo(typeof(ExceptionlessClient), "Updated configuration to version {0}.", e.Configuration.Version);

            if (ConfigurationUpdated != null)
                ConfigurationUpdated(this, e);
        }

        /// <summary>
        /// Occurs when an unhandled exception is about to be reported.
        /// </summary>
        public event EventHandler<UnhandledExceptionReportingEventArgs> UnhandledExceptionReporting;

        /// <summary>
        /// Raises the <see cref="UnhandledExceptionReporting" /> event.
        /// </summary>
        /// <param name="e">The <see cref="UnhandledExceptionReportingEventArgs" /> instance containing the event data.</param>
        protected void OnUnhandledExceptionReporting(UnhandledExceptionReportingEventArgs e) {
            if (UnhandledExceptionReporting != null)
                UnhandledExceptionReporting(this, e);
        }

        /// <summary>
        /// Occurs when the error is being sent to the server.
        /// </summary>
        public event EventHandler<ErrorModelEventArgs> SendingError;

        /// <summary>
        /// Occurs when the error has been sent to the server.
        /// </summary>
        public event EventHandler<SendErrorCompletedEventArgs> SendErrorCompleted;

        /// <summary>
        /// Raises the <see cref="SendErrorCompleted" /> event.
        /// </summary>
        /// <param name="e">The <see cref="SendErrorCompletedEventArgs" /> instance containing the event data.</param>
        protected void OnSendErrorCompleted(SendErrorCompletedEventArgs e) {
            if (e.Error != null)
                Log.FormattedError(typeof(ExceptionlessClient), "Sending error report failed: {0}", e.Error.Message);
            else
                Log.FormattedDebug(typeof(ExceptionlessClient), "Report completed for {0}.", e.ErrorId);

            if (SendErrorCompleted != null)
                SendErrorCompleted(this, e);
        }

        private void OnSendingError(Error error) {
            var args = new ErrorModelEventArgs(error);
            OnSendingError(args);
        }

        /// <summary>
        /// Raises the <see cref="SendingError" /> event.
        /// </summary>
        /// <param name="e">The <see cref="ErrorModelEventArgs" /> instance containing the event data.</param>
        protected void OnSendingError(ErrorModelEventArgs e) {
            if (SendingError != null)
                SendingError(this, e);
        }

        #endregion

        /// <summary>
        /// Initializes a new instance of the <see cref="ExceptionlessClient" /> class.
        /// </summary>
        internal ExceptionlessClient(IQueueStore store = null, IExceptionlessLog log = null) {
            _queueTimer = new Timer(OnQueueTimer, null, Timeout.Infinite, Timeout.Infinite);
            _log = log ?? new NullExceptionlessLog();

            try {
                _configuration = Config.ClientConfiguration.Create(this);
                Log.FormattedTrace(typeof(ExceptionlessClient), "Configuration Values: ApiKey={0}, EnableSSL={1}, Enabled={2}, ServerUrl={3}", _configuration.ApiKey, _configuration.EnableSSL, _configuration.Enabled, _configuration.ServerUrl);
            } catch (Exception ex) {
                Log.FormattedError(typeof(ExceptionlessClient), "Critical error in ExceptionlessClient constructor: {0}", ex.Message);
            }

            try {
                _localConfiguration = Config.LocalConfigurationDictionary.Create(_configuration.StoreId, this);
            } catch (Exception ex) {
                Log.FormattedError(typeof(ExceptionlessClient), "Critical error in ExceptionlessClient constructor: {0}", ex.Message);<commit_msg>Using _nullLogger instead of instantiating a new NullExceptionlessLog<commit_after>#region Copyright 2014 Exceptionless

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// 
//     http://www.apache.org/licenses/LICENSE-2.0

#endregion

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Security;
using System.Text;
using System.Threading;
using Exceptionless.ExtendedData;
using Exceptionless.Extensions;
using Exceptionless.Logging;
using Exceptionless.Models;
using Exceptionless.Net;
using Exceptionless.Plugins;
using Exceptionless.Queue;
using Exceptionless.Utility;
#if !PFX_LEGACY_3_5
using System.Threading.Tasks;
#endif
#if !SILVERLIGHT
using Exceptionless.Diagnostics;
#endif
using Config = Exceptionless.Configuration;

namespace Exceptionless {
    /// <summary>
    /// A class used to interact with the Exceptionless service.
    /// </summary>
    public class ExceptionlessClient : DisposableBase, IConfigurationAndLogAccessor {
        public const int ApiRevision = 1;

        private const string API_URI_FORMAT = "/api/v{0}/";

        private bool _updatingConfiguration;
        private readonly Timer _queueTimer;
        private bool _isProcessQueueScheduled;
        private ILastErrorIdManager _lastErrorIdManager;
        private static volatile bool _processingQueue;
        private static readonly object _queueLock = new object();
        private readonly ObservableConcurrentDictionary<string, IExceptionlessPlugin> _plugins = new ObservableConcurrentDictionary<string, IExceptionlessPlugin>();
        private IExceptionlessLog _log;
        private static readonly IExceptionlessLog _nullLogger = new NullExceptionlessLog();

        #region Events

        /// <summary>
        /// Occurs when the configuration updated.
        /// </summary>
        public event EventHandler<ConfigurationUpdatedEventArgs> ConfigurationUpdated;

        /// <summary>
        /// Raises the <see cref="ConfigurationUpdated" /> event.
        /// </summary>
        /// <param name="e">The <see cref="ConfigurationUpdatedEventArgs" /> instance containing the event data.</param>
        protected void OnConfigurationUpdated(ConfigurationUpdatedEventArgs e) {
            if (e.Error != null)
                Log.FormattedError(typeof(ExceptionlessClient), "Error updating configuration: {0}", e.Error.Message);
            else if (e.Configuration != null)
                Log.FormattedInfo(typeof(ExceptionlessClient), "Updated configuration to version {0}.", e.Configuration.Version);

            if (ConfigurationUpdated != null)
                ConfigurationUpdated(this, e);
        }

        /// <summary>
        /// Occurs when an unhandled exception is about to be reported.
        /// </summary>
        public event EventHandler<UnhandledExceptionReportingEventArgs> UnhandledExceptionReporting;

        /// <summary>
        /// Raises the <see cref="UnhandledExceptionReporting" /> event.
        /// </summary>
        /// <param name="e">The <see cref="UnhandledExceptionReportingEventArgs" /> instance containing the event data.</param>
        protected void OnUnhandledExceptionReporting(UnhandledExceptionReportingEventArgs e) {
            if (UnhandledExceptionReporting != null)
                UnhandledExceptionReporting(this, e);
        }

        /// <summary>
        /// Occurs when the error is being sent to the server.
        /// </summary>
        public event EventHandler<ErrorModelEventArgs> SendingError;

        /// <summary>
        /// Occurs when the error has been sent to the server.
        /// </summary>
        public event EventHandler<SendErrorCompletedEventArgs> SendErrorCompleted;

        /// <summary>
        /// Raises the <see cref="SendErrorCompleted" /> event.
        /// </summary>
        /// <param name="e">The <see cref="SendErrorCompletedEventArgs" /> instance containing the event data.</param>
        protected void OnSendErrorCompleted(SendErrorCompletedEventArgs e) {
            if (e.Error != null)
                Log.FormattedError(typeof(ExceptionlessClient), "Sending error report failed: {0}", e.Error.Message);
            else
                Log.FormattedDebug(typeof(ExceptionlessClient), "Report completed for {0}.", e.ErrorId);

            if (SendErrorCompleted != null)
                SendErrorCompleted(this, e);
        }

        private void OnSendingError(Error error) {
            var args = new ErrorModelEventArgs(error);
            OnSendingError(args);
        }

        /// <summary>
        /// Raises the <see cref="SendingError" /> event.
        /// </summary>
        /// <param name="e">The <see cref="ErrorModelEventArgs" /> instance containing the event data.</param>
        protected void OnSendingError(ErrorModelEventArgs e) {
            if (SendingError != null)
                SendingError(this, e);
        }

        #endregion

        /// <summary>
        /// Initializes a new instance of the <see cref="ExceptionlessClient" /> class.
        /// </summary>
        internal ExceptionlessClient(IQueueStore store = null, IExceptionlessLog log = null) {
            _queueTimer = new Timer(OnQueueTimer, null, Timeout.Infinite, Timeout.Infinite);
            _log = log ?? _nullLogger;

            try {
                _configuration = Config.ClientConfiguration.Create(this);
                Log.FormattedTrace(typeof(ExceptionlessClient), "Configuration Values: ApiKey={0}, EnableSSL={1}, Enabled={2}, ServerUrl={3}", _configuration.ApiKey, _configuration.EnableSSL, _configuration.Enabled, _configuration.ServerUrl);
            } catch (Exception ex) {
                Log.FormattedError(typeof(ExceptionlessClient), "Critical error in ExceptionlessClient constructor: {0}", ex.Message);
            }

            try {
                _localConfiguration = Config.LocalConfigurationDictionary.Create(_configuration.StoreId, this);
            } catch (Exception ex) {
                Log.FormattedError(typeof(ExceptionlessClient), "Critical error in ExceptionlessClient constructor: {0}", ex.Message);
{'fraction_non_alphanumeric': 0.09973711463395205, 'fraction_numerical': 0.0035051382139727554, 'mean_word_length': 2.787028657616893, 'pattern_counts': {'":': 0, '<': 89, '<?xml version=': 0, '>': 89, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4032289', 'n_tokens_mistral': 3105, 'n_tokens_neox': 3027, 'n_words': 851}