public static void UpdateSettings(ExceptionlessConfiguration config) { if (String.IsNullOrEmpty(config.ApiKey) || String.Equals(config.ApiKey, "API_KEY_HERE", StringComparison.OrdinalIgnoreCase)) { config.Resolver.GetLog().Error(typeof(SettingsManager), "Unable to update settings: ApiKey is not set."); return; } var serializer = config.Resolver.GetJsonSerializer(); var client = config.Resolver.GetSubmissionClient(); var response = client.GetSettings(config, serializer); if (!response.Success || response.Settings == null) return; var savedServerSettings = GetSavedServerSettings(config); config.Settings.Apply(response.Settings); // TODO: Store snapshot of settings after reading from config and attributes and use that to revert to defaults. // Remove any existing server settings that are not in the new server settings. foreach (string key in savedServerSettings.Keys.Except(response.Settings.Keys)) { if (config.Settings.ContainsKey(key)) config.Settings.Remove(key); } var persistedClientData = config.Resolver.Resolve<PersistedDictionary>(); persistedClientData[String.Concat(config.GetQueueName(), "-ServerConfigVersion")] = response.SettingsVersion.ToString(); var fileStorage = config.Resolver.GetFileStorage(); fileStorage.SaveObject(GetConfigPath(config), response.Settings); }
public static void AddDefaultPlugins(ExceptionlessConfiguration config) { config.AddPlugin<ConfigurationDefaultsPlugin>(); config.AddPlugin<SimpleErrorPlugin>(); config.AddPlugin<DuplicateCheckerPlugin>(); config.AddPlugin<EnvironmentInfoPlugin>(); config.AddPlugin<SubmissionMethodPlugin>(); }
public SettingsResponse GetSettings(ExceptionlessConfiguration config, int version, IJsonSerializer serializer) { if (!config.IsValid) return new SettingsResponse(false, message: "Invalid client configuration settings."); string url = String.Format("{0}/projects/config?v={1}", GetServiceEndPoint(config), version); HttpResponseMessage response; try { _client.Value.AddAuthorizationHeader(config.ApiKey); response = _client.Value.GetAsync(url).ConfigureAwait(false).GetAwaiter().GetResult(); } catch (Exception ex) { var message = String.Concat("Unable to retrieve configuration settings. Exception: ", ex.GetMessage()); return new SettingsResponse(false, message: message); } if (response != null && response.StatusCode == HttpStatusCode.NotModified) return new SettingsResponse(false, message: "Settings have not been modified."); if (response == null || response.StatusCode != HttpStatusCode.OK) return new SettingsResponse(false, message: String.Concat("Unable to retrieve configuration settings: ", GetResponseMessage(response))); var json = GetResponseText(response); if (String.IsNullOrWhiteSpace(json)) return new SettingsResponse(false, message: "Invalid configuration settings."); var settings = serializer.Deserialize<ClientConfiguration>(json); return new SettingsResponse(true, settings.Settings, settings.Version); }
public static void CheckVersion(int version, ExceptionlessConfiguration config) { var persistedClientData = config.Resolver.Resolve<PersistedDictionary>(); if (version <= persistedClientData.GetInt32(String.Concat(config.GetQueueName(), "-ServerConfigVersion"), -1)) return; UpdateSettings(config); }
public void CanUpdateSettingsFromServer() { var config = new ExceptionlessConfiguration(DependencyResolver.Default); config.ApiKey = "e3d51ea621464280bbcb79c11fd6483e"; config.Settings["LocalSetting"] = "1"; config.Settings["LocalSettingToOverride"] = "1"; var submissionClient = new Mock<ISubmissionClient>(); submissionClient.Setup(m => m.Submit(It.IsAny<IEnumerable<Event>>(), config, It.IsAny<IJsonSerializer>())) .Callback(() => SettingsManager.CheckVersion(1, config)) .Returns(() => new SubmissionResponse(202, "Accepted")); submissionClient.Setup(m => m.GetSettings(config, It.IsAny<IJsonSerializer>())) .Returns(() => new SettingsResponse(true, new SettingsDictionary { { "Test", "Test" }, { "LocalSettingToOverride", "2" } }, 1)); config.Resolver.Register<ISubmissionClient>(submissionClient.Object); var client = new ExceptionlessClient(config); Assert.Equal(2, client.Configuration.Settings.Count); Assert.False(client.Configuration.Settings.ContainsKey("Test")); Assert.Equal("1", client.Configuration.Settings["LocalSettingToOverride"]); client.SubmitEvent(new Event { Type = "Log", Message = "Test" }); client.ProcessQueue(); Assert.True(client.Configuration.Settings.ContainsKey("Test")); Assert.Equal("2", client.Configuration.Settings["LocalSettingToOverride"]); Assert.Equal(3, client.Configuration.Settings.Count); var storage = config.Resolver.GetFileStorage() as InMemoryFileStorage; Assert.True(storage.Exists(config.GetQueueName() + "\\server-settings.json")); config.Settings.Clear(); config.ApplySavedServerSettings(); Assert.True(client.Configuration.Settings.ContainsKey("Test")); Assert.Equal("2", client.Configuration.Settings["LocalSettingToOverride"]); Assert.Equal(2, client.Configuration.Settings.Count); }
public static void CheckVersion(int version, ExceptionlessConfiguration config) { int currentVersion = GetVersion(config); if (version <= currentVersion) return; UpdateSettings(config, currentVersion); }
public SubmissionResponse PostUserDescription(string referenceId, UserDescription description, ExceptionlessConfiguration config, IJsonSerializer serializer) { if (!config.IsValid) return new SubmissionResponse(500, message: "Invalid client configuration settings."); string data = serializer.Serialize(description); string url = String.Format("{0}/events/by-ref/{1}/user-description", GetServiceEndPoint(config), referenceId); HttpResponseMessage response; try { HttpContent content = new StringContent(data, Encoding.UTF8, "application/json"); // don't compress data smaller than 4kb if (data.Length > 1024 * 4) content = new GzipContent(content); _client.Value.AddAuthorizationHeader(config.ApiKey); response = _client.Value.PostAsync(url, content).ConfigureAwait(false).GetAwaiter().GetResult(); } catch (Exception ex) { return new SubmissionResponse(500, message: ex.Message); } int settingsVersion; if (Int32.TryParse(GetSettingsVersionHeader(response.Headers), out settingsVersion)) SettingsManager.CheckVersion(settingsVersion, config); return new SubmissionResponse((int)response.StatusCode, GetResponseMessage(response)); }
public static void UpdateSettings(ExceptionlessConfiguration config, int? version = null) { if (config == null || !config.IsValid || !config.Enabled) return; try { if (!version.HasValue || version < 0) version = GetVersion(config); var serializer = config.Resolver.GetJsonSerializer(); var client = config.Resolver.GetSubmissionClient(); var response = client.GetSettings(config, version.Value, serializer); if (!response.Success || response.Settings == null) return; var savedServerSettings = GetSavedServerSettings(config); config.Settings.Apply(response.Settings); // TODO: Store snapshot of settings after reading from config and attributes and use that to revert to defaults. // Remove any existing server settings that are not in the new server settings. foreach (string key in savedServerSettings.Keys.Except(response.Settings.Keys)) { if (config.Settings.ContainsKey(key)) config.Settings.Remove(key); } var persistedClientData = config.Resolver.Resolve<PersistedDictionary>(); persistedClientData[String.Concat(config.GetQueueName(), "-ServerConfigVersion")] = response.SettingsVersion.ToString(); var fileStorage = config.Resolver.GetFileStorage(); fileStorage.SaveObject(GetConfigPath(config), response.Settings); } catch (Exception ex) { config.Resolver.GetLog().Error(typeof(SettingsManager), ex, "Error occurred updating settings."); } }
public static void AddAuthorizationHeader(this WebRequest request, ExceptionlessConfiguration configuration) { var authorizationHeader = new AuthorizationHeader { Scheme = ExceptionlessHeaders.Bearer, ParameterText = configuration.ApiKey }; request.Headers[HttpRequestHeader.Authorization] = authorizationHeader.ToString(); }
public SubmissionResponse PostEvents(IEnumerable<Event> events, ExceptionlessConfiguration config, IJsonSerializer serializer) { foreach (Event e in events) { string data = serializer.Serialize(e); string referenceId = !string.IsNullOrWhiteSpace(e.ReferenceId) ? e.ReferenceId : Guid.NewGuid().ToString("D"); _eventContainer[referenceId] = data; } return new SubmissionResponse(200); }
public static void AddDefaultPlugins(ExceptionlessConfiguration config) { config.AddPlugin<ConfigurationDefaultsPlugin>(); config.AddPlugin<HandleAggregateExceptionsPlugin>(); config.AddPlugin<SimpleErrorPlugin>(); config.AddPlugin<DuplicateCheckerPlugin>(); config.AddPlugin<EnvironmentInfoPlugin>(); config.AddPlugin<SubmissionMethodPlugin>(); config.AddPlugin<CancelSessionsWithNoUserPlugin>(); }
public SubmissionResponse PostUserDescription(string referenceId, UserDescription description, ExceptionlessConfiguration config, IJsonSerializer serializer) { var ev = Events.FirstOrDefault(e => e.ReferenceId == referenceId); if (ev == null) return new SubmissionResponse(404, "Not Found"); ev.Data[Event.KnownDataKeys.UserDescription] = description; return new SubmissionResponse(200, "OK"); }
public static void ApplySavedServerSettings(ExceptionlessConfiguration config) { if (String.IsNullOrEmpty(config.ApiKey) || String.Equals(config.ApiKey, "API_KEY_HERE", StringComparison.OrdinalIgnoreCase)) { config.Resolver.GetLog().Error(typeof(SettingsManager), "Unable to apply saved server settings: ApiKey is not set."); return; } var savedServerSettings = GetSavedServerSettings(config); config.Settings.Apply(savedServerSettings); }
public static RequestInfo Collect(HttpContextBase context, ExceptionlessConfiguration config) { if (context == null) return null; var info = new RequestInfo { HttpMethod = context.Request.HttpMethod, UserAgent = context.Request.UserAgent, Path = String.IsNullOrEmpty(context.Request.Path) ? "/" : context.Request.Path }; try { info.ClientIpAddress = context.Request.UserHostAddress; } catch (ArgumentException ex) { config.Resolver.GetLog().Error(ex, "An error occurred while setting the Client Ip Address."); } try { info.IsSecure = context.Request.IsSecureConnection; } catch (ArgumentException ex) { config.Resolver.GetLog().Error(ex, "An error occurred while setting Is Secure Connection."); } if (context.Request.Url != null) info.Host = context.Request.Url.Host; if (context.Request.UrlReferrer != null) info.Referrer = context.Request.UrlReferrer.ToString(); if (context.Request.Url != null) info.Port = context.Request.Url.Port; info.Cookies = context.Request.Cookies.ToDictionary(config.DataExclusions); if (context.Request.Form.Count > 0) info.PostData = context.Request.Form.ToDictionary(config.DataExclusions); else if (context.Request.ContentLength > 0 && context.Request.ContentLength < 1024 * 4) { try { context.Request.InputStream.Position = 0; using (var inputStream = new StreamReader(context.Request.InputStream)) info.PostData = inputStream.ReadToEnd(); } catch (Exception ex) { info.PostData = "Error retrieving POST data: " + ex.Message; } } else if (context.Request.ContentLength > 0) { string value = Math.Round(context.Request.ContentLength / 1024m, 0).ToString("N0"); info.PostData = String.Format("Data is too large ({0}) to be included.", value + "kb"); } try { info.QueryString = context.Request.QueryString.ToDictionary(config.DataExclusions); } catch (Exception ex) { config.Resolver.GetLog().Error(ex, "An error occurred while getting the cookies"); } return info; }
/// <summary> /// Adds the current request info as extended data to the event. /// </summary> /// <param name="ev">The event model.</param> /// <param name="context">The http action context to gather information from.</param> /// <param name="config">The config.</param> public static Event AddHttpRequestInfo(this Event ev, HttpActionContext context, ExceptionlessConfiguration config = null) { if (context == null) return ev; if (config == null) config = ExceptionlessClient.Default.Configuration; ev.AddRequestInfo(context.GetRequestInfo(config)); return ev; }
public DefaultEventQueue(ExceptionlessConfiguration config, IExceptionlessLog log, ISubmissionClient client, IObjectStorage objectStorage, IJsonSerializer serializer, TimeSpan? processQueueInterval, TimeSpan? queueStartDelay) { _log = log; _config = config; _client = client; _storage = objectStorage; _serializer = serializer; if (processQueueInterval.HasValue) _processQueueInterval = processQueueInterval.Value; _queueTimer = new Timer(OnProcessQueue, null, queueStartDelay ?? TimeSpan.FromSeconds(2), _processQueueInterval); }
public static void CheckVersion(int version, ExceptionlessConfiguration config) { if (String.IsNullOrEmpty(config.ApiKey) || String.Equals(config.ApiKey, "API_KEY_HERE", StringComparison.OrdinalIgnoreCase)) { config.Resolver.GetLog().Error(typeof(SettingsManager), "Unable to check version: ApiKey is not set."); return; } var persistedClientData = config.Resolver.Resolve<PersistedDictionary>(); if (version <= persistedClientData.GetInt32(String.Concat(config.GetQueueName(), "-ServerConfigVersion"), -1)) return; UpdateSettings(config); }
public static void SetUserAgent(this HttpWebRequest request, ExceptionlessConfiguration configuration) { if (_userAgentProperty.Value != null) { try { _userAgentProperty.Value.SetValue(request, configuration.UserAgent, null); return; } catch (Exception ex) { configuration.Resolver.GetLog().Error(ex, "Error occurred setting the user agent."); } } request.Headers[ExceptionlessHeaders.Client] = configuration.UserAgent; }
public void CanReadFromAttributes() { var config = new ExceptionlessConfiguration(DependencyResolver.CreateDefault()); Assert.Null(config.ApiKey); Assert.Equal("https://collector.exceptionless.io", config.ServerUrl); Assert.Equal(0, config.Settings.Count); config.ReadFromAttributes(typeof(ConfigurationTests).Assembly); Assert.Equal("LhhP1C9gijpSKCslHHCvwdSIz298twx271n1l6xw", config.ApiKey); Assert.Equal("http://localhost:45000", config.ServerUrl); Assert.Equal(1, config.Settings.Count); Assert.Equal("configuration", config.Settings["testing"]); }
public SubmissionResponse PostEvents(IEnumerable<Event> events, ExceptionlessConfiguration config, IJsonSerializer serializer) { var data = events.ToList(); data.ForEach(e => { if (e.Date == DateTimeOffset.MinValue) e.Date = DateTimeOffset.Now; if (String.IsNullOrEmpty(e.Type)) e.Type = Event.KnownTypes.Log; }); Events.AddRange(data); return new SubmissionResponse(202, "Accepted"); }
public void GetSettingsAsync() { using (WebApp.Start(Settings.Current.BaseURL, AppBuilder.Build)) { var configuration = ExceptionlessConfiguration.CreateDefault(); var serializer = new DefaultJsonSerializer(); var client = new DefaultSubmissionClient(); var response = client.GetSettings(configuration, serializer); Assert.True(response.Success, response.Message); Assert.NotEqual(-1, response.SettingsVersion); Assert.NotNull(response.Settings); Assert.Null(response.Message); } }
public void CanReadFromAttributes() { var config = new ExceptionlessConfiguration(DependencyResolver.CreateDefault()); Assert.Null(config.ApiKey); Assert.Equal("https://collector.exceptionless.io", config.ServerUrl); Assert.Empty(config.Settings); config.ReadFromAttributes(typeof(ConfigurationTests).GetTypeInfo().Assembly); Assert.Equal("LhhP1C9gijpSKCslHHCvwdSIz298twx271n1l6xw", config.ApiKey); Assert.Equal("http://localhost:45000", config.ServerUrl); Assert.Single(config.Settings); Assert.Equal("configuration", config.Settings["testing"]); }
public static void SetUserAgent(this HttpWebRequest request, ExceptionlessConfiguration configuration) { if (_userAgentProperty.Value != null) { try { _userAgentProperty.Value.SetValue(request, configuration.UserAgent, null); return; } catch (Exception ex) { configuration.Resolver.GetLog().Error(ex, "Error occurred setting the user agent."); } } request.Headers[ExceptionlessHeaders.Client] = configuration.UserAgent; }
public DefaultEventQueue(ExceptionlessConfiguration config, IExceptionlessLog log, ISubmissionClient client, IFileStorage fileStorage, IJsonSerializer serializer, TimeSpan?processQueueInterval, TimeSpan?queueStartDelay) { _log = log; _config = config; _client = client; _storage = fileStorage; _serializer = serializer; if (processQueueInterval.HasValue) { _processQueueInterval = processQueueInterval.Value; } _queueTimer = new Timer(OnProcessQueue, null, queueStartDelay ?? TimeSpan.FromSeconds(10), _processQueueInterval); }
private Uri GetHeartbeatServiceEndPoint(ExceptionlessConfiguration config) { var builder = new UriBuilder(config.HeartbeatServerUrl); builder.Path += builder.Path.EndsWith("/") ? "api/v2" : "/api/v2"; // EnableSSL if (builder.Scheme == "https" && builder.Port == 80 && !builder.Host.Contains("local")) { builder.Port = 443; } return(builder.Uri); }
public static void ApplySavedServerSettings(ExceptionlessConfiguration config) { string configPath = GetConfigPath(config); var fileStorage = config.Resolver.GetFileStorage(); if (!fileStorage.Exists(configPath)) return; try { var serializer = config.Resolver.GetJsonSerializer(); var savedServerSettings = fileStorage.GetObject<SettingsDictionary>(configPath, serializer); config.Settings.Apply(savedServerSettings); } catch (Exception ex) { config.Resolver.GetLog().FormattedError(typeof(SettingsManager), ex, "Unable to read and apply saved server settings: {0}", ex.Message); } }
public void CanReadFromAttributes() { var config = new ExceptionlessConfiguration(DependencyResolver.CreateDefault()); Assert.Null(config.ApiKey); Assert.Equal("https://collector.exceptionless.com", config.ServerUrl); Assert.True(config.EnableSSL); Assert.Equal(0, config.Settings.Count); config.ReadFromAttributes(typeof(ConfigurationTests).Assembly); Assert.Equal("e3d51ea621464280bbcb79c11fd6483e", config.ApiKey); Assert.Equal("http://localhost:45000", config.ServerUrl); Assert.False(config.EnableSSL); Assert.Equal(1, config.Settings.Count); Assert.Equal("configuration", config.Settings["testing"]); }
public static Uri GetServiceEndPoint(this ExceptionlessConfiguration config) { var builder = new UriBuilder(config.ServerUrl); builder.Path += builder.Path.EndsWith("/") ? "api/v2/" : "/api/v2/"; // EnableSSL if (config.EnableSSL && builder.Port == 80 && !builder.Host.Contains("local")) { builder.Port = 443; builder.Scheme = "https"; } return(builder.Uri); }
private HttpWebRequest CreateHttpWebRequest(ExceptionlessConfiguration config, string endPoint) { var request = (HttpWebRequest)WebRequest.Create(String.Concat(config.GetServiceEndPoint(), endPoint)); request.AddAuthorizationHeader(config); request.SetUserAgent(config.UserAgent); request.AllowAutoRedirect = true; request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip | DecompressionMethods.None; try { request.UseDefaultCredentials = true; // if (Credentials != null) // request.Credentials = Credentials; } catch (Exception) {} return request; }
public static RequestInfo Collect(NancyContext context, ExceptionlessConfiguration config) { if (context == null) { return(null); } var info = new RequestInfo { HttpMethod = context.Request.Method }; if (config.IncludeIpAddress) { info.ClientIpAddress = context.Request.UserHostAddress; } if (!String.IsNullOrWhiteSpace(context.Request.Headers.UserAgent)) { info.UserAgent = context.Request.Headers.UserAgent; } if (context.Request.Url != null) { info.Host = context.Request.Url.HostName; info.IsSecure = context.Request.Url.IsSecure; info.Path = context.Request.Url.BasePath + context.Request.Url.Path; info.Port = context.Request.Url.Port.GetValueOrDefault(info.IsSecure ? 443 : 80); } if (!String.IsNullOrWhiteSpace(context.Request.Headers.Referrer)) { info.Referrer = context.Request.Headers.Referrer; } var exclusionsArray = config.DataExclusions as string[] ?? config.DataExclusions.ToArray(); if (config.IncludeCookies) { info.Cookies = context.Request.Cookies.ToDictionary(exclusionsArray); } if (config.IncludeQueryString && context.Request.Url != null && !String.IsNullOrWhiteSpace(context.Request.Url.Query)) { info.QueryString = HttpUtility.ParseQueryString(context.Request.Url.Query).ToDictionary(exclusionsArray); } return(info); }
public static RequestInfo Collect(HttpActionContext context, ExceptionlessConfiguration config) { if (context == null) { return(null); } var info = new RequestInfo { HttpMethod = context.Request.Method.Method }; if (config.IncludeIpAddress) { info.ClientIpAddress = context.Request.GetClientIpAddress(); } if (context.Request.Headers.UserAgent != null) { info.UserAgent = context.Request.Headers.UserAgent.ToString(); } if (context.Request.RequestUri != null) { info.Host = context.Request.RequestUri.Host; info.IsSecure = context.Request.RequestUri.Scheme == "https"; info.Path = String.IsNullOrEmpty(context.Request.RequestUri.LocalPath) ? "/" : context.Request.RequestUri.LocalPath; info.Port = context.Request.RequestUri.Port; } if (context.Request.Headers.Referrer != null) { info.Referrer = context.Request.Headers.Referrer.ToString(); } var exclusionList = config.DataExclusions as string[] ?? config.DataExclusions.ToArray(); if (config.IncludeCookies) { info.Cookies = context.Request.Headers.GetCookies().ToDictionary(exclusionList); } if (config.IncludeQueryString) { info.QueryString = context.Request.RequestUri.ParseQueryString().ToDictionary(exclusionList); } // TODO Collect form data. return(info); }
public void CanUpdateSettingsFromServer() { var config = new ExceptionlessConfiguration(DependencyResolver.Default) { ApiKey = "LhhP1C9gijpSKCslHHCvwdSIz298twx271n1l6xw", Settings = { ["LocalSetting"] = "1", ["LocalSettingToOverride"] = "1" } }; var submissionClient = new Mock <ISubmissionClient>(); submissionClient.Setup(m => m.PostEvents(It.IsAny <IEnumerable <Event> >(), config, It.IsAny <IJsonSerializer>())) .Callback(() => SettingsManager.CheckVersion(1, config)) .Returns(() => new SubmissionResponse(202, "Accepted")); submissionClient.Setup(m => m.GetSettings(config, 0, It.IsAny <IJsonSerializer>())) .Returns(() => new SettingsResponse(true, new SettingsDictionary { { "Test", "Test" }, { "LocalSettingToOverride", "2" } }, 1)); config.Resolver.Register <ISubmissionClient>(submissionClient.Object); var client = new ExceptionlessClient(config); Assert.Equal(2, client.Configuration.Settings.Count); Assert.False(client.Configuration.Settings.ContainsKey("Test")); Assert.Equal("1", client.Configuration.Settings["LocalSettingToOverride"]); client.SubmitEvent(new Event { Type = "Log", Message = "Test" }); client.ProcessQueue(); Assert.True(client.Configuration.Settings.ContainsKey("Test")); Assert.Equal("2", client.Configuration.Settings["LocalSettingToOverride"]); Assert.Equal(3, client.Configuration.Settings.Count); var storage = config.Resolver.GetFileStorage() as InMemoryObjectStorage; Assert.NotNull(storage); Assert.NotNull(config.GetQueueName()); Assert.True(storage.Exists(Path.Combine(config.GetQueueName(), "server-settings.json"))); config.Settings.Clear(); config.ApplySavedServerSettings(); Assert.True(client.Configuration.Settings.ContainsKey("Test")); Assert.Equal("2", client.Configuration.Settings["LocalSettingToOverride"]); Assert.Equal(2, client.Configuration.Settings.Count); }
public void CanReadFromAttributes() { var config = new ExceptionlessConfiguration(DependencyResolver.CreateDefault()); Assert.Null(config.ApiKey); Assert.Equal("https://collector.exceptionless.com", config.ServerUrl); Assert.True(config.EnableSSL); Assert.Equal(0, config.Settings.Count); config.ReadFromAttributes(typeof(ConfigurationTests).Assembly); Assert.Equal("e3d51ea621464280bbcb79c11fd6483e", config.ApiKey); Assert.Equal("http://localhost:45000", config.ServerUrl); Assert.False(config.EnableSSL); Assert.Equal(1, config.Settings.Count); Assert.Equal("configuration", config.Settings["testing"]); }
public ExceptionlessClient(ExceptionlessConfiguration configuration) { if (configuration == null) throw new ArgumentNullException("configuration"); Configuration = configuration; configuration.Resolver.Register(typeof(ExceptionlessConfiguration), () => Configuration); _log = new Lazy<IExceptionlessLog>(() => Configuration.Resolver.GetLog()); _queue = new Lazy<IEventQueue>(() => { // config can't be changed after the queue starts up. Configuration.LockConfig(); return Configuration.Resolver.GetEventQueue(); }); _submissionClient = new Lazy<ISubmissionClient>(() => Configuration.Resolver.GetSubmissionClient()); _lastReferenceIdManager = new Lazy<ILastReferenceIdManager>(() => Configuration.Resolver.GetLastReferenceIdManager()); }
public static void UpdateSettings(ExceptionlessConfiguration config) { var serializer = config.Resolver.GetJsonSerializer(); var client = config.Resolver.GetSubmissionClient(); var response = client.GetSettings(config, serializer); if (!response.Success) return; config.Settings.Apply(response.Settings); var persistedClientData = config.Resolver.Resolve<PersistedDictionary>(); persistedClientData[String.Concat(config.GetQueueName(), "-ServerConfigVersion")] = response.SettingsVersion.ToString(); var fileStorage = config.Resolver.GetFileStorage(); fileStorage.SaveObject(GetConfigPath(config), response.Settings, serializer); }
public static int GetVersion(ExceptionlessConfiguration config) { if (config == null) return 0; if (String.IsNullOrEmpty(config.ApiKey) || String.Equals(config.ApiKey, "API_KEY_HERE", StringComparison.OrdinalIgnoreCase)) { config.Resolver.GetLog().Error(typeof(SettingsManager), "Unable to get version: ApiKey is not set."); return 0; } try { var persistedClientData = config.Resolver.Resolve<PersistedDictionary>(); return persistedClientData.GetInt32(String.Concat(config.GetQueueName(), "-ServerConfigVersion"), 0); } catch (Exception ex) { config.Resolver.GetLog().Error(typeof(SettingsManager), ex, "Error occurred getting settings version."); return 0; } }
public static void AddDefaultPlugins(ExceptionlessConfiguration config) { config.AddPlugin<HandleAggregateExceptionsPlugin>(); config.AddPlugin<EventExclusionPlugin>(); config.AddPlugin<ConfigurationDefaultsPlugin>(); #if !PORTABLE && !NETSTANDARD1_2 config.AddPlugin<ErrorPlugin>(); #else config.AddPlugin<SimpleErrorPlugin>(); #endif config.AddPlugin<DuplicateCheckerPlugin>(); config.AddPlugin<EnvironmentInfoPlugin>(); #if !PORTABLE && !NETSTANDARD1_2 config.AddPlugin<VersionPlugin>(); #endif config.AddPlugin<SubmissionMethodPlugin>(); config.AddPlugin<CancelSessionsWithNoUserPlugin>(); }
protected virtual HttpWebRequest CreateHttpWebRequest(ExceptionlessConfiguration config, string endPoint) { var request = (HttpWebRequest)WebRequest.Create(String.Concat(config.GetServiceEndPoint(), endPoint)); request.AddAuthorizationHeader(config); request.SetUserAgent(config.UserAgent); request.AllowAutoRedirect = true; request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip | DecompressionMethods.None; try { request.UseDefaultCredentials = true; // if (Credentials != null) // request.Credentials = Credentials; } catch (Exception) {} return(request); }
public static void ApplySavedServerSettings(ExceptionlessConfiguration config) { if (config == null) { return; } if (String.IsNullOrEmpty(config.ApiKey) || String.Equals(config.ApiKey, "API_KEY_HERE", StringComparison.OrdinalIgnoreCase)) { config.Resolver.GetLog().Error(typeof(SettingsManager), "Unable to apply saved server settings: ApiKey is not set."); return; } var savedServerSettings = GetSavedServerSettings(config); config.Settings.Apply(savedServerSettings); }
private static SettingsDictionary GetSavedServerSettings(ExceptionlessConfiguration config) { string configPath = GetConfigPath(config); if (String.IsNullOrEmpty(configPath)) return new SettingsDictionary(); var fileStorage = config.Resolver.GetFileStorage(); if (!fileStorage.Exists(configPath)) return new SettingsDictionary(); try { return fileStorage.GetObject<SettingsDictionary>(configPath); } catch (Exception ex) { config.Resolver.GetLog().FormattedError(typeof(SettingsManager), ex, "Unable to read and apply saved server settings: {0}", ex.Message); } return new SettingsDictionary(); }
public static void CheckVersion(int version, ExceptionlessConfiguration config) { if (String.IsNullOrEmpty(config.ApiKey) || String.Equals(config.ApiKey, "API_KEY_HERE", StringComparison.OrdinalIgnoreCase)) { config.Resolver.GetLog().Error(typeof(SettingsManager), "Unable to check version: ApiKey is not set."); return; } var persistedClientData = config.Resolver.Resolve <PersistedDictionary>(); if (version <= persistedClientData.GetInt32(String.Concat(config.GetQueueName(), "-ServerConfigVersion"), -1)) { return; } UpdateSettings(config); }
public void SendHeartbeat(string sessionIdOrUserId, bool closeSession, ExceptionlessConfiguration config) { if (!config.IsValid) { return; } string url = String.Format("{0}/events/session/heartbeat?id={1}&close={2}", GetHeartbeatServiceEndPoint(config), sessionIdOrUserId, closeSession); try { _client.Value.AddAuthorizationHeader(config.ApiKey); _client.Value.GetAsync(url).ConfigureAwait(false).GetAwaiter().GetResult(); } catch (Exception ex) { var log = config.Resolver.GetLog(); log.Error(String.Concat("Error submitting heartbeat: ", ex.GetMessage())); } }
protected virtual HttpClient CreateHttpClient(ExceptionlessConfiguration config) { #if NET45 var handler = new WebRequestHandler { UseDefaultCredentials = true }; #else var handler = new HttpClientHandler { UseDefaultCredentials = true }; #endif var callback = config.ServerCertificateValidationCallback; if (callback != null) { #if NET45 handler.ServerCertificateValidationCallback = (s, c, ch, p) => Validate(s, c, ch, p, callback); #else handler.ServerCertificateCustomValidationCallback = (m, c, ch, p) => Validate(m, c, ch, p, callback); #endif } if (handler.SupportsAutomaticDecompression) { handler.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip | DecompressionMethods.None; } if (handler.SupportsRedirectConfiguration) { handler.AllowAutoRedirect = true; } if (handler.SupportsProxy && config.Proxy != null) { handler.Proxy = config.Proxy; } var client = new HttpClient(handler, true); client.DefaultRequestHeaders.ConnectionClose = true; client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); client.DefaultRequestHeaders.ExpectContinue = false; client.DefaultRequestHeaders.UserAgent.ParseAdd(config.UserAgent); return(client); }
public static void ApplySavedServerSettings(ExceptionlessConfiguration config) { string configPath = GetConfigPath(config); var fileStorage = config.Resolver.GetFileStorage(); if (!fileStorage.Exists(configPath)) { return; } try { var serializer = config.Resolver.GetJsonSerializer(); var savedServerSettings = fileStorage.GetObject <SettingsDictionary>(configPath, serializer); config.Settings.Apply(savedServerSettings); } catch (Exception ex) { config.Resolver.GetLog().FormattedError(typeof(SettingsManager), ex, "Unable to read and apply saved server settings: {0}", ex.Message); } }
public static void AddDefaultPlugins(ExceptionlessConfiguration config) { config.AddPlugin <HandleAggregateExceptionsPlugin>(); config.AddPlugin <EventExclusionPlugin>(); config.AddPlugin <ConfigurationDefaultsPlugin>(); #if !PORTABLE && !NETSTANDARD1_2 config.AddPlugin <ErrorPlugin>(); #else config.AddPlugin <SimpleErrorPlugin>(); #endif config.AddPlugin <DuplicateCheckerPlugin>(); config.AddPlugin <EnvironmentInfoPlugin>(); #if !PORTABLE && !NETSTANDARD1_2 config.AddPlugin <VersionPlugin>(); #endif config.AddPlugin <SubmissionMethodPlugin>(); config.AddPlugin <CancelSessionsWithNoUserPlugin>(); }
public void SubmitAsync() { using (WebApp.Start(Settings.Current.BaseURL, AppBuilder.Build)) { var events = new List <Event> { new Event { Message = "Testing" } }; var configuration = ExceptionlessConfiguration.CreateDefault(); var serializer = new DefaultJsonSerializer(); var client = new DefaultSubmissionClient(); var response = client.Submit(events, configuration, serializer); Assert.True(response.Success, response.Message); Assert.NotEqual(-1, response.SettingsVersion); Assert.Null(response.Message); } }
public SubmissionResponse Submit(IEnumerable <Event> events, ExceptionlessConfiguration configuration, IJsonSerializer serializer) { HttpWebRequest client = WebRequest.CreateHttp(String.Concat(configuration.GetServiceEndPoint(), "events")); client.SetUserAgent(configuration.UserAgent); client.AddAuthorizationHeader(configuration); var data = serializer.Serialize(events); var response = client.PostJsonAsync(data).Result; int settingsVersion; if (!Int32.TryParse(response.Headers[ExceptionlessHeaders.ConfigurationVersion], out settingsVersion)) { settingsVersion = -1; } return(new SubmissionResponse((int)response.StatusCode, settingsVersion, response.StatusCode == HttpStatusCode.Accepted ? null : response.GetResponseText())); }
public static void UpdateSettings(ExceptionlessConfiguration config, int?version = null) { if (config == null || !config.IsValid || !config.Enabled || _isUpdatingSettings) { return; } try { _isUpdatingSettings = true; if (!version.HasValue || version < 0) { version = GetVersion(config); } var serializer = config.Resolver.GetJsonSerializer(); var client = config.Resolver.GetSubmissionClient(); var response = client.GetSettings(config, version.Value, serializer); if (!response.Success || response.Settings == null) { return; } var savedServerSettings = GetSavedServerSettings(config); config.Settings.Apply(response.Settings); // TODO: Store snapshot of settings after reading from config and attributes and use that to revert to defaults. // Remove any existing server settings that are not in the new server settings. foreach (string key in savedServerSettings.Keys.Except(response.Settings.Keys)) { config.Settings.Remove(key); } var persistedClientData = config.Resolver.Resolve <PersistedDictionary>(); persistedClientData[String.Concat(config.GetQueueName(), "-ServerConfigVersion")] = response.SettingsVersion.ToString(); var fileStorage = config.Resolver.GetFileStorage(); fileStorage.SaveObject(GetConfigPath(config), response.Settings); } catch (Exception ex) { config.Resolver.GetLog().Error(typeof(SettingsManager), ex, "Error occurred updating settings."); } finally { _isUpdatingSettings = false; } }
public SubmissionResponse PostEvents(IEnumerable <Event> events, ExceptionlessConfiguration config, IJsonSerializer serializer) { var data = events.ToList(); data.ForEach(e => { if (e.Date == DateTimeOffset.MinValue) { e.Date = DateTimeOffset.Now; } if (String.IsNullOrEmpty(e.Type)) { e.Type = Event.KnownTypes.Log; } }); Events.AddRange(data); return(new SubmissionResponse(202, "Accepted")); }
public SubmissionResponse PostUserDescription(string referenceId, UserDescription description, ExceptionlessConfiguration config, IJsonSerializer serializer) { var data = serializer.Serialize(description); HttpWebResponse response; try { var request = CreateHttpWebRequest(config, String.Format("events/by-ref/{0}/user-description", referenceId)); response = request.PostJsonAsyncWithCompression(data).Result as HttpWebResponse; } catch (AggregateException aex) { var ex = aex.GetInnermostException() as WebException; if (ex != null) response = (HttpWebResponse)ex.Response; else return new SubmissionResponse(500, message: aex.GetMessage()); } catch (Exception ex) { return new SubmissionResponse(500, message: ex.Message); } return new SubmissionResponse((int)response.StatusCode, response.IsSuccessful() ? null : response.GetResponseText()); }
public SettingsResponse GetSettings(ExceptionlessConfiguration config, IJsonSerializer serializer) { HttpWebResponse response; try { var request = CreateHttpWebRequest(config, "projects/config"); response = request.GetJsonAsync().Result as HttpWebResponse; } catch (Exception ex) { var message = String.Concat("Unable to retrieve configuration settings. Exception: ", ex.GetMessage()); return new SettingsResponse(false, message: message); } if (response == null || response.StatusCode != HttpStatusCode.OK) return new SettingsResponse(false, message: String.Format("Unable to retrieve configuration settings: {0}", GetResponseMessage(response))); var json = response.GetResponseText(); if (String.IsNullOrWhiteSpace(json)) return new SettingsResponse(false, message: "Invalid configuration settings."); var settings = serializer.Deserialize<ClientConfiguration>(json); return new SettingsResponse(true, settings.Settings, settings.Version); }
public SubmissionResponse PostEvents(IEnumerable <Event> events, ExceptionlessConfiguration config, IJsonSerializer serializer) { if (!config.IsValid) { return(SubmissionResponse.InvalidClientConfig500); } string data = serializer.Serialize(events); string url = $"{GetServiceEndPoint(config)}/events"; HttpResponseMessage response; try { HttpContent content = new StringContent(data, Encoding.UTF8, "application/json"); // don't compress data smaller than 4kb if (data.Length > 1024 * 4) { content = new GzipContent(content); } _client.Value.AddAuthorizationHeader(config.ApiKey); response = _client.Value.PostAsync(url, content).ConfigureAwait(false).GetAwaiter().GetResult(); } catch (Exception ex) { return(new SubmissionResponse(500, exception: ex)); } if (Int32.TryParse(GetSettingsVersionHeader(response.Headers), out int settingsVersion)) { SettingsManager.CheckVersion(settingsVersion, config); } var message = GetResponseMessage(response); if ((int)response.StatusCode == 200 && "OK".Equals(message, StringComparison.OrdinalIgnoreCase)) { return(SubmissionResponse.Ok200); } return(new SubmissionResponse((int)response.StatusCode, message)); }
public static int GetVersion(ExceptionlessConfiguration config) { if (config == null) { return(0); } if (String.IsNullOrEmpty(config.ApiKey) || String.Equals(config.ApiKey, "API_KEY_HERE", StringComparison.OrdinalIgnoreCase)) { config.Resolver.GetLog().Error(typeof(SettingsManager), "Unable to get version: ApiKey is not set."); return(0); } try { var persistedClientData = config.Resolver.Resolve <PersistedDictionary>(); return(persistedClientData.GetInt32(String.Concat(config.GetQueueName(), "-ServerConfigVersion"), 0)); } catch (Exception ex) { config.Resolver.GetLog().Error(typeof(SettingsManager), ex, "Error occurred getting settings version."); return(0); } }
public SettingsResponse GetSettings(ExceptionlessConfiguration config, int version, IJsonSerializer serializer) { if (!config.IsValid) { return(new SettingsResponse(false, message: "Invalid client configuration settings.")); } string url = String.Format("{0}/projects/config?v={1}", GetConfigServiceEndPoint(config), version); HttpResponseMessage response; try { _client.Value.AddAuthorizationHeader(config.ApiKey); response = _client.Value.GetAsync(url).ConfigureAwait(false).GetAwaiter().GetResult(); } catch (Exception ex) { var message = String.Concat("Unable to retrieve configuration settings. Exception: ", ex.GetMessage()); return(new SettingsResponse(false, message: message)); } if (response != null && response.StatusCode == HttpStatusCode.NotModified) { return(new SettingsResponse(false, message: "Settings have not been modified.")); } if (response == null || response.StatusCode != HttpStatusCode.OK) { return(new SettingsResponse(false, message: String.Concat("Unable to retrieve configuration settings: ", GetResponseMessage(response)))); } var json = GetResponseText(response); if (String.IsNullOrWhiteSpace(json)) { return(new SettingsResponse(false, message: "Invalid configuration settings.")); } var settings = serializer.Deserialize <ClientConfiguration>(json); return(new SettingsResponse(true, settings.Settings, settings.Version)); }
public static void UpdateSettings(ExceptionlessConfiguration config) { if (String.IsNullOrEmpty(config.ApiKey) || String.Equals(config.ApiKey, "API_KEY_HERE", StringComparison.OrdinalIgnoreCase)) { config.Resolver.GetLog().Error(typeof(SettingsManager), "Unable to update settings: ApiKey is not set."); return; } var serializer = config.Resolver.GetJsonSerializer(); var client = config.Resolver.GetSubmissionClient(); var response = client.GetSettings(config, serializer); if (!response.Success || response.Settings == null) { return; } var savedServerSettings = GetSavedServerSettings(config); config.Settings.Apply(response.Settings); // TODO: Store snapshot of settings after reading from config and attributes and use that to revert to defaults. // Remove any existing server settings that are not in the new server settings. foreach (string key in savedServerSettings.Keys.Except(response.Settings.Keys)) { if (config.Settings.ContainsKey(key)) { config.Settings.Remove(key); } } var persistedClientData = config.Resolver.Resolve <PersistedDictionary>(); persistedClientData[String.Concat(config.GetQueueName(), "-ServerConfigVersion")] = response.SettingsVersion.ToString(); var fileStorage = config.Resolver.GetFileStorage(); fileStorage.SaveObject(GetConfigPath(config), response.Settings); }
public static void UpdateSettings(ExceptionlessConfiguration config) { var serializer = config.Resolver.GetJsonSerializer(); var client = config.Resolver.GetSubmissionClient(); var response = client.GetSettings(config, serializer); if (!response.Success) { return; } config.Settings.Apply(response.Settings); var persistedClientData = config.Resolver.Resolve <PersistedDictionary>(); persistedClientData[String.Concat(config.GetQueueName(), "-ServerConfigVersion")] = response.SettingsVersion.ToString(); var fileStorage = config.Resolver.GetFileStorage(); fileStorage.SaveObject(GetConfigPath(config), response.Settings, serializer); }
protected virtual HttpClient CreateHttpClient(ExceptionlessConfiguration config) { #if NET45 var handler = new WebRequestHandler { UseDefaultCredentials = true }; handler.ServerCertificateValidationCallback = delegate { return(true); }; #else var handler = new HttpClientHandler { UseDefaultCredentials = true }; #if !PORTABLE && !NETSTANDARD1_2 //handler.ServerCertificateCustomValidationCallback = delegate { return true; }; #endif #endif if (handler.SupportsAutomaticDecompression) { handler.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip | DecompressionMethods.None; } if (handler.SupportsRedirectConfiguration) { handler.AllowAutoRedirect = true; } if (handler.SupportsProxy && config.Proxy != null) { handler.Proxy = config.Proxy; } var client = new HttpClient(handler, true); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); client.DefaultRequestHeaders.ExpectContinue = false; client.DefaultRequestHeaders.UserAgent.ParseAdd(config.UserAgent); return(client); }
public SettingsResponse GetSettings(ExceptionlessConfiguration configuration, IJsonSerializer serializer) { HttpWebRequest client = WebRequest.CreateHttp(String.Concat(configuration.GetServiceEndPoint(), "projects/config")); client.AddAuthorizationHeader(configuration); var response = client.GetJsonAsync().Result; if (response == null || response.StatusCode != HttpStatusCode.OK) { return(new SettingsResponse(false, message: "Unable to retrieve configuration settings.")); } var json = response.GetResponseText(); if (String.IsNullOrWhiteSpace(json)) { return(new SettingsResponse(false, message: "Invalid configuration settings.")); } var settings = serializer.Deserialize <ClientConfiguration>(json); return(new SettingsResponse(true, settings.Settings, settings.Version)); }
private static SettingsDictionary GetSavedServerSettings(ExceptionlessConfiguration config) { string configPath = GetConfigPath(config); if (String.IsNullOrEmpty(configPath)) { return(new SettingsDictionary()); } var fileStorage = config.Resolver.GetFileStorage(); if (!fileStorage.Exists(configPath)) { return(new SettingsDictionary()); } try { return(fileStorage.GetObject <SettingsDictionary>(configPath)); } catch (Exception ex) { config.Resolver.GetLog().FormattedError(typeof(SettingsManager), ex, "Unable to read and apply saved server settings: {0}", ex.Message); } return(new SettingsDictionary()); }
public SubmissionResponse PostEvents(IEnumerable <Event> events, ExceptionlessConfiguration config, IJsonSerializer serializer) { if (!config.IsValid) { return(new SubmissionResponse(500, message: "Invalid client configuration settings")); } string data = serializer.Serialize(events); string url = String.Format("{0}/events", GetServiceEndPoint(config)); HttpResponseMessage response; try { HttpContent content = new StringContent(data, Encoding.UTF8, "application/json"); // don't compress data smaller than 4kb if (data.Length > 1024 * 4) { content = new GzipContent(content); } _client.Value.AddAuthorizationHeader(config.ApiKey); response = _client.Value.PostAsync(url, content).ConfigureAwait(false).GetAwaiter().GetResult(); } catch (Exception ex) { return(new SubmissionResponse(500, message: ex.Message)); } int settingsVersion; if (Int32.TryParse(GetSettingsVersionHeader(response.Headers), out settingsVersion)) { SettingsManager.CheckVersion(settingsVersion, config); } return(new SubmissionResponse((int)response.StatusCode, GetResponseMessage(response))); }