public void Minimal_notice_generates_valid_XML() { var notice = new AirbrakeNotice(); notice.ApiKey = "123456"; notice.Error = new AirbrakeError { Class = "TestError", Message = "something blew up", Backtrace = new[] { new AirbrakeTraceLine ("unknown.cs", 0) { Method = "unknown"} } }; notice.Notifier = new AirbrakeNotifier { Name = "hopsharp", Version = "2.0", Url = "http://github.com/krobertson/hopsharp" }; notice.ServerEnvironment = new AirbrakeServerEnvironment("staging") { ProjectRoot = "/test", }; var serializer = new CleanXmlSerializer<AirbrakeNotice>(); string xml = serializer.ToXml(notice); AirbrakeValidator.ValidateSchema(xml); }
/// <summary> /// Sends the specified notice to Airbrake. /// </summary> /// <param name="notice">The notice.</param> public void Send(AirbrakeNotice notice) { InternalLogger.Debug("{0}.Send({1})", GetType(), notice); try { // If no API key, get it from the appSettings if (String.IsNullOrEmpty(notice.ApiKey)) { // If none is set, just return... throwing an exception is pointless, since one was already thrown! if (String.IsNullOrEmpty(ConfigurationManager.AppSettings["Airbrake.ApiKey"])) { InternalLogger.Fatal("No 'Airbrake.ApiKey' found. Please define one in AppSettings."); return; } notice.ApiKey = this.builder.Configuration.ApiKey; } // Create the web request var request = WebRequest.Create(this.configuration.ServerUri) as HttpWebRequest; if (request == null) { InternalLogger.Fatal("Couldn't create a request to '{0}'.", this.configuration.ServerUri); return; } // Set the basic headers request.ContentType = "text/xml"; request.Accept = "text/xml"; request.KeepAlive = false; // It is important to set the method late... .NET quirk, it will interfere with headers set after request.Method = "POST"; InternalLogger.Debug("Sending Airbrake notice to {0} with key {1}, env: {2}", this.configuration.ServerUri, this.configuration.ApiKey, this.configuration.EnvironmentName); // Go populate the body SetRequestBody(request, notice); // Begin the request, yay async request.BeginGetResponse(RequestCallback, request); } catch (Exception ex) { InternalLogger.Fatal("An error occurred while trying to send to Airbrake: {0}", ex.Message); } }
public void Maximal_notice_generates_valid_XML() { var error = Activator.CreateInstance<AirbrakeError>(); error.Class = "TestError"; error.Message = "something blew up"; error.Backtrace = new[] { new AirbrakeTraceLine("unknown.cs", 0) { Method = "unknown" } }; var notice = new AirbrakeNotice { ApiKey = "123456", Error = error, Request = new AirbrakeRequest(new Uri("http://example.com/"), GetType().FullName) { Action = "Maximal_notice_generates_valid_XML", Component = "MyApp.HomeController", CgiData = new[] { new AirbrakeVar("REQUEST_METHOD", "POST"), }, Params = new[] { new AirbrakeVar("Form.Key1", "Form.Value1"), }, Session = new[] { new AirbrakeVar("UserId", "1"), }, Url = "http://example.com/myapp", }, Notifier = new AirbrakeNotifier { Name = "sharpbrake", Version = "2.2", Url = "http://github.com/asbjornu/SharpBrake", }, ServerEnvironment = new AirbrakeServerEnvironment("staging") { ProjectRoot = "/test", }, }; var serializer = new CleanXmlSerializer<AirbrakeNotice>(); string xml = serializer.ToXml(notice); AirbrakeValidator.ValidateSchema(xml); }
public void LogEvent_WithExecption_CallsClient() { var client = A.Fake<ISharpbrakeClient>(); Exception ex = new ApplicationException("something bad happened"); // using activator to avoid the obsolete tag on the constructor. AirbrakeError error = Activator.CreateInstance<AirbrakeError>(); AirbrakeNotice notice = new AirbrakeNotice() { Error = error }; A.CallTo(() => client.BuildNotice(ex)).Returns(notice); AirBrakeTarget target = new AirBrakeTarget(client); NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target); logger.InfoException("kaboom", ex); A.CallTo(() => client.Send(notice)).MustHaveHappened(); }
private void AddContextualInformation(AirbrakeNotice notice, MethodBase catchingMethod, Dictionary<string, string> info = null) { var component = String.Empty; var action = String.Empty; if ((notice.Error != null) && (notice.Error.Backtrace != null) && notice.Error.Backtrace.Any()) { // TODO: We should perhaps check whether the topmost back trace is in fact a Controller+Action by performing some sort of heuristic (searching for "Controller" etc.). @asbjornu var backtrace = notice.Error.Backtrace.First(); action = backtrace.Method; component = backtrace.File; } else if (catchingMethod != null) { action = catchingMethod.Name; if (catchingMethod.DeclaringType != null) component = catchingMethod.DeclaringType.FullName; } var request = new AirbrakeRequest("http://example.com/", component) { Action = action }; var cgiData = new List<AirbrakeVar> { new AirbrakeVar("Environment.MachineName", Environment.MachineName), new AirbrakeVar("Environment.OSversion", Environment.OSVersion), new AirbrakeVar("Environment.Version", Environment.Version) }; var parameters = new List<AirbrakeVar>(); var session = new List<AirbrakeVar>(); var httpContext = HttpContext.Current; if (httpContext != null) { var httpRequest = httpContext.Request; request.Url = httpRequest.Url.ToString(); cgiData.AddRange(BuildVars(httpRequest.Headers)); cgiData.AddRange(BuildVars(httpRequest.Cookies)); parameters.AddRange(BuildVars(httpRequest.Params)); session.AddRange(BuildVars(httpContext.Session)); if (httpContext.User != null) cgiData.Add(new AirbrakeVar("User.Identity.Name", httpContext.User.Identity.Name)); var browser = httpRequest.Browser; if (browser != null) { cgiData.Add(new AirbrakeVar("Browser.Browser", browser.Browser)); cgiData.Add(new AirbrakeVar("Browser.ClrVersion", browser.ClrVersion)); cgiData.Add(new AirbrakeVar("Browser.Cookies", browser.Cookies)); cgiData.Add(new AirbrakeVar("Browser.Crawler", browser.Crawler)); cgiData.Add(new AirbrakeVar("Browser.EcmaScriptVersion", browser.EcmaScriptVersion)); cgiData.Add(new AirbrakeVar("Browser.JavaApplets", browser.JavaApplets)); cgiData.Add(new AirbrakeVar("Browser.MajorVersion", browser.MajorVersion)); cgiData.Add(new AirbrakeVar("Browser.MinorVersion", browser.MinorVersion)); cgiData.Add(new AirbrakeVar("Browser.Platform", browser.Platform)); cgiData.Add(new AirbrakeVar("Browser.W3CDomVersion", browser.W3CDomVersion)); } } if (info != null) { foreach (var item in info) { if (item.Key.ToLower().StartsWith("environment")) { cgiData.Add(new AirbrakeVar(item.Key, item.Value)); } else if (item.Key.ToLower().StartsWith("session")) { session.Add(new AirbrakeVar(item.Key, item.Value)); } else { parameters.Add(new AirbrakeVar(item.Key, item.Value)); } } } request.CgiData = cgiData.ToArray(); request.Params = parameters.Any() ? parameters.ToArray() : null; request.Session = session.Any() ? session.ToArray() : null; notice.Request = request; }
private void AddContextualInformation(AirbrakeNotice notice, MethodBase catchingMethod) { var component = String.Empty; var action = String.Empty; if ((notice.Error != null) && (notice.Error.Backtrace != null) && notice.Error.Backtrace.Any()) { // TODO: We should perhaps check whether the topmost back trace is in fact a Controller+Action by performing some sort of heuristic (searching for "Controller" etc.). @asbjornu var backtrace = notice.Error.Backtrace.First(); action = backtrace.Method; component = backtrace.File; } else if (catchingMethod != null) { action = catchingMethod.Name; if (catchingMethod.DeclaringType != null) component = catchingMethod.DeclaringType.FullName; } var request = new AirbrakeRequest("http://example.com/", component) { Action = action }; var cgiData = new List<AirbrakeVar> { new AirbrakeVar("Environment.MachineName", Environment.MachineName), new AirbrakeVar("Environment.OSversion", Environment.OSVersion), new AirbrakeVar("Environment.Version", Environment.Version) }; var parameters = new List<AirbrakeVar>(); var session = new List<AirbrakeVar>(); request.CgiData = cgiData.ToArray(); request.Params = parameters.Any() ? parameters.ToArray() : null; request.Session = session.Any() ? session.ToArray() : null; notice.Request = request; }
private static void AddInfoFromHttpContext(AirbrakeNotice notice, MethodBase catchingMethod) { HttpContext httpContext = HttpContext.Current; if (httpContext == null) return; HttpRequest request = httpContext.Request; string component = String.Empty; string action = String.Empty; if (catchingMethod != null) { action = catchingMethod.Name; if (catchingMethod.DeclaringType != null) component = catchingMethod.DeclaringType.FullName; } notice.Request = new AirbrakeRequest(request.Url, component) { Action = action, CgiData = BuildVars(request.Headers).ToArray(), Params = BuildVars(request.Params).ToArray(), Session = BuildVars(httpContext.Session).ToArray(), }; }
/// <summary> /// Creates a <see cref="AirbrakeNotice"/> from the the specified error. /// </summary> /// <param name="error">The error.</param> /// <param name="info"> Additional info to send to Airbrake.</param> /// <returns></returns> public AirbrakeNotice Notice(AirbrakeError error, Dictionary<string, string> info = null) { this.log.Debug(f => f("{0}.Notice({1})", GetType(), error)); var notice = new AirbrakeNotice { ApiKey = Configuration.ApiKey, Error = error, Notifier = Notifier, ServerEnvironment = ServerEnvironment, }; MethodBase catchingMethod = (error != null) ? error.CatchingMethod : null; AddContextualInformation(notice, catchingMethod, info); return notice; }
public void Minimal_notice_with_request_generates_valid_XML() { var error = Activator.CreateInstance<AirbrakeError>(); error.Class = "TestError"; error.Message = "something blew up"; error.Backtrace = new[] { new AirbrakeTraceLine("unknown.cs", 0) { Method = "unknown" } }; var notice = new AirbrakeNotice { ApiKey = "123456", Error = error, Request = new AirbrakeRequest(new Uri("http://example.com/"), GetType().FullName) { Session = new AirbrakeVar[0] }, Notifier = new AirbrakeNotifier { Name = "sharpbrake", Version = "2.2", Url = "http://github.com/asbjornu/SharpBrake" }, ServerEnvironment = new AirbrakeServerEnvironment("staging") { ProjectRoot = "/test", }, }; var serializer = new CleanXmlSerializer<AirbrakeNotice>(); string xml = serializer.ToXml(notice); AirbrakeValidator.ValidateSchema(xml); }
/// <summary> /// Creates a <see cref="AirbrakeNotice"/> from the the specified error. /// </summary> /// <param name="error">The error.</param> /// <returns></returns> public AirbrakeNotice Notice(AirbrakeError error) { this.log.Debug(f => f("{0}.Notice({1})", GetType(), error)); var notice = new AirbrakeNotice { ApiKey = Configuration.ApiKey, Error = error, Notifier = Notifier, ServerEnvironment = ServerEnvironment, }; MethodBase catchingMethod = (error != null) ? error.CatchingMethod : null; AddInfoFromHttpContext(notice, catchingMethod); return notice; }
/// <summary> /// Creates a <see cref="AirbrakeNotice"/> from the the specified error. /// </summary> /// <param name="error">The error.</param> /// <returns></returns> public AirbrakeNotice BuildNotice(AirbrakeError error) { _log.Debug(f => f("{0}.Notice({1})", GetType(), error)); var notice = new AirbrakeNotice { ApiKey = Configuration.ApiKey, Error = error, Notifier = Notifier, ServerEnvironment = ServerEnvironment, }; MethodBase catchingMethod = error != null ? error.CatchingMethod : null; AddContextualInformation(notice, catchingMethod); return notice; }
public void Notice_missing_error_fails_validation() { var notice = new AirbrakeNotice { ApiKey = "123456", Request = new AirbrakeRequest(new Uri("http://example.com/"), GetType().FullName) { Action = "Maximal_notice_generates_valid_XML", }, Notifier = new AirbrakeNotifier { Name = "sharpbrake", Version = "2.2", Url = "http://github.com/asbjornu/SharpBrake" }, ServerEnvironment = new AirbrakeServerEnvironment("staging") { ProjectRoot = "/test", }, }; var serializer = new CleanXmlSerializer<AirbrakeNotice>(); string xml = serializer.ToXml(notice); TestDelegate throwing = () => AirbrakeValidator.ValidateSchema(xml); XmlSchemaValidationException exception = Assert.Throws<XmlSchemaValidationException>(throwing); Console.WriteLine(exception); Assert.That(exception.Message, Is.StringContaining("notice")); Assert.That(exception.Message, Is.StringContaining("error")); Assert.That(exception.LineNumber, Is.EqualTo(18)); Assert.That(exception.LinePosition, Is.EqualTo(3)); }
private void SetRequestBody(WebRequest request, AirbrakeNotice notice) { var serializer = new CleanXmlSerializer<AirbrakeNotice>(); string xml = serializer.ToXml(notice); //this.log.Debug(f => f("Sending the following to '{0}':\n{1}", request.RequestUri, xml)); byte[] payload = Encoding.UTF8.GetBytes(xml); request.ContentLength = payload.Length; using (Stream stream = request.GetRequestStream()) { stream.Write(payload, 0, payload.Length); } }
/// <summary> /// Creates a <see cref="AirbrakeNotice"/> from the the specified exception. /// </summary> /// <param name="exception">The exception.</param> /// <returns> /// A <see cref="AirbrakeNotice"/>, created from the the specified exception. /// </returns> public AirbrakeNotice Notice(Exception exception) { if (exception == null) throw new ArgumentNullException("exception"); this.log.Debug(f => f("{0}.Notice({1})", GetType(), exception.GetType()), exception); var notice = new AirbrakeNotice { ApiKey = Configuration.ApiKey, Error = ErrorFromException(exception), Notifier = Notifier, ServerEnvironment = ServerEnvironment, }; return notice; }
/// <summary> /// Creates a <see cref="AirbrakeNotice"/> from the the specified error. /// </summary> /// <param name="error">The error.</param> /// <returns></returns> public AirbrakeNotice Notice(AirbrakeError error) { this.log.Debug(f => f("{0}.Notice({1})", GetType(), error)); var notice = new AirbrakeNotice { ApiKey = Configuration.ApiKey, Error = error, Notifier = Notifier, ServerEnvironment = ServerEnvironment, }; if (HttpContext.Current != null) { Assembly assembly = Assembly.GetExecutingAssembly(); notice.Request = new AirbrakeRequest(HttpContext.Current.Request.Url, assembly.CodeBase) { Params = BuildParams().ToArray(), Session = BuildSession().ToArray(), CgiData = BuildCgiData().ToArray(), }; } return notice; }
public void MinimalNoticeGeneratesValidXml() { var error = new AirbrakeError { Class = "TestError", Message = "something blew up", Backtrace = new[] { new AirbrakeTraceLine("unknown.cs", 0) { Method = "unknown" } } }; var notice = new AirbrakeNotice { ApiKey = "123456", Error = error, Notifier = new AirbrakeNotifier { Name = "sharpbrake", Version = "2.2.2.0", Url = "https://github.com/airbrake/SharpBrake" }, ServerEnvironment = new AirbrakeServerEnvironment("staging") { ProjectRoot = "/test", }, }; var serializer = new CleanXmlSerializer<AirbrakeNotice>(); var xml = serializer.ToXml(notice); AirbrakeValidator.ValidateSchema(xml); }
public void NoticeMissingErrorFailsValidation() { var notice = new AirbrakeNotice { ApiKey = "123456", Request = new AirbrakeRequest(new Uri("http://example.com/"), GetType().FullName) { Action = "NoticeMissingErrorFailsValidation", }, Notifier = new AirbrakeNotifier { Name = "sharpbrake", Version = "2.2.2.0", Url = "https://github.com/airbrake/SharpBrake" }, ServerEnvironment = new AirbrakeServerEnvironment("staging") { ProjectRoot = "/test", }, }; var serializer = new CleanXmlSerializer<AirbrakeNotice>(); var xml = serializer.ToXml(notice); TestDelegate throwing = () => AirbrakeValidator.ValidateSchema(xml); var exception = Assert.Throws<XmlSchemaValidationException>(throwing); Console.WriteLine(exception); Assert.That(exception.Message, Is.StringContaining("notice")); Assert.That(exception.Message, Is.StringContaining("error")); }
public void Send(AirbrakeNotice notice) { this.Client.Send(notice); }
/// <summary> /// Creates a <see cref="AirbrakeNotice"/> from the the specified error. /// </summary> /// <param name="error">The error.</param> /// <param name="extraParams">extra data for adding the params in airbrake notice </param> /// <returns></returns> public AirbrakeNotice Notice(AirbrakeError error, IEnumerable<KeyValuePair<string, string>> extraParams = null) { this.log.Debug(f => f("{0}.Notice({1})", GetType(), error)); var notice = new AirbrakeNotice { ApiKey = Configuration.ApiKey, Error = error, Notifier = Notifier, ServerEnvironment = ServerEnvironment, }; MethodBase catchingMethod = (error != null) ? error.CatchingMethod : null; AddContextualInformation(notice, catchingMethod, extraParams); return notice; }