public void RemoveFile(string filePath) { // Validate the file path. if (string.IsNullOrEmpty(filePath)) { RaygunLogger.Debug("Failed to remove file - Invalid file path"); return; } // Check a file exists at this path. if (!File.Exists(filePath)) { RaygunLogger.Debug("Failed to remove file - File does not exist"); return; } try { File.Delete(filePath); } catch (Exception e) { RaygunLogger.Error("Failed to remove file - Due to error: " + e.Message); } }
private void SendAllStoredCrashReports() { if (!HasInternetConnection) { RaygunLogger.Debug("Not sending stored crash reports due to no internet connection"); return; } // Get all stored crash reports. var reports = _fileManager.GetAllStoredCrashReports(); RaygunLogger.Debug(string.Format("Attempting to send {0} stored crash report(s)", reports.Count)); // Quick escape if there's no crash reports. if (reports.Count == 0) { return; } // Run on another thread. Task.Run(async() => { // Use a single HttpClient for all requests. using (var client = new HttpClient()) { foreach (var report in reports) { try { RaygunLogger.Verbose("Sending JSON -------------------------------"); RaygunLogger.Verbose(report.Data); RaygunLogger.Verbose("--------------------------------------------"); // Create the request contnet. HttpContent content = new StringContent(report.Data, System.Text.Encoding.UTF8, "application/json"); // Add API key to headers. content.Headers.Add("X-ApiKey", _apiKey); // Perform the request. var response = await client.PostAsync(RaygunSettings.Settings.ApiEndpoint, content); // Check the response. var statusCode = (int)response.StatusCode; RaygunLogger.LogResponseStatusCode(statusCode); // Remove the stored crash report if it was sent successfully. if (statusCode == (int)RaygunResponseStatusCode.Accepted) { _fileManager.RemoveFile(report.Path); // We can delete the file from disk now. } } catch (Exception e) { RaygunLogger.Error("Failed to send stored crash report due to error: " + e.Message); } } } }); }
public IRaygunMessageBuilder SetVersion(string version) { if (String.IsNullOrWhiteSpace(version)) { try { Context context = RaygunClient.Context; PackageManager manager = context.PackageManager; PackageInfo info = manager.GetPackageInfo(context.PackageName, 0); version = info.VersionCode + " / " + info.VersionName; } catch (Exception ex) { RaygunLogger.Debug(string.Format("Error retrieving package version {0}", ex.Message)); } } if (String.IsNullOrWhiteSpace(version)) { version = "Not supplied"; } _raygunMessage.Details.Version = version; return(this); }
/// <summary> /// Initializes a new instance of the <see cref="RaygunClient" /> class. /// </summary> /// <param name="apiKey">The API key.</param> public RaygunClient(string apiKey) { _apiKey = apiKey; _fileManager = new RaygunFileManager(); _fileManager.Intialise(); MaxReportsStoredOnDevice = RaygunFileManager.MAX_STORED_REPORTS_UPPER_LIMIT; // Setting default user information. var anonUser = GetAnonymousUserInfo(); _userInfo = anonUser; _user = anonUser.Identifier; _wrapperExceptions.Add(typeof(TargetInvocationException)); _wrapperExceptions.Add(typeof(System.AggregateException)); SendingMessage += RaygunClient_SendingMessage; try { var clientVersion = new AssemblyName(GetType().Assembly.FullName).Version.ToString(); RaygunLogger.Debug(string.Format("Configuring Raygun ({0})", clientVersion)); } catch { // Ignore } }
/// <summary> /// Causes Raygun to automatically send session and view events for Raygun Pulse. /// </summary> /// <param name="mainActivity">The main/entry activity of the Android app.</param> /// <returns>The RaygunClient to chain other methods.</returns> public RaygunClient AttachPulse(Activity mainActivity) { RaygunLogger.Debug("Enabling Real User Monitoring"); Pulse.Attach(this, mainActivity); return(this); }
private void SendCore(PulseEventBatch batch) { try { EnsurePulseSessionStarted(); string version = GetVersion(); string os = "Android"; string osVersion = Android.OS.Build.VERSION.Release; string platform = string.Format("{0} {1}", Android.OS.Build.Manufacturer, Android.OS.Build.Model); RaygunPulseMessage message = new RaygunPulseMessage(); RaygunLogger.Debug("BatchSize: " + batch.PendingEventCount); RaygunPulseDataMessage[] eventMessages = new RaygunPulseDataMessage[batch.PendingEventCount]; int index = 0; foreach (PendingEvent pendingEvent in batch.PendingEvents) { RaygunPulseDataMessage dataMessage = new RaygunPulseDataMessage(); dataMessage.SessionId = pendingEvent.SessionId; dataMessage.Timestamp = pendingEvent.Timestamp; dataMessage.Version = version; dataMessage.OS = os; dataMessage.OSVersion = osVersion; dataMessage.Platform = platform; dataMessage.Type = "mobile_event_timing"; dataMessage.User = batch.UserInfo; string type = pendingEvent.EventType == RaygunPulseEventType.ViewLoaded ? "p" : "n"; RaygunPulseData data = new RaygunPulseData() { Name = pendingEvent.Name, Timing = new RaygunPulseTimingMessage() { Type = type, Duration = pendingEvent.Duration } }; RaygunPulseData[] dataArray = { data }; string dataStr = SimpleJson.SerializeObject(dataArray); dataMessage.Data = dataStr; eventMessages[index] = dataMessage; index++; } message.EventData = eventMessages; Send(message); } catch (Exception e) { RaygunLogger.Error(string.Format("Error sending pulse event batch to Raygun: {0}", e.Message)); } }
private static void RemoveUnhandledExceptionHandlers() { if (_exceptionHandlersSet) { _exceptionHandlersSet = false; RaygunLogger.Debug("Removing exception handlers"); AppDomain.CurrentDomain.UnhandledException -= CurrentDomain_UnhandledException; TaskScheduler.UnobservedTaskException -= TaskScheduler_UnobservedTaskException; } }
private static void SetUnhandledExceptionHandlers() { if (!_exceptionHandlersSet) { _exceptionHandlersSet = true; RaygunLogger.Debug("Adding exception handlers"); AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException; } }
/// <summary> /// Causes Raygun to listen to and send all unhandled exceptions and unobserved task exceptions. /// </summary> /// <returns>The RaygunClient to chain other methods.</returns> public RaygunClient AttachCrashReporting() { RaygunLogger.Debug("Enabling Crash Reporting"); RaygunClient.DetachCrashReporting(); SetUnhandledExceptionHandlers(); return(this); }
/// <summary> /// Asynchronously transmits a message to Raygun.io. /// </summary> /// <param name="exception">The exception to deliver.</param> /// <param name="tags">A list of strings associated with the message.</param> /// <param name="userCustomData">A key-value collection of custom data that will be added to the payload.</param> public void SendInBackground(Exception exception, IList <string> tags, IDictionary userCustomData) { if (CanSend(exception)) { ThreadPool.QueueUserWorkItem(c => StripAndSend(exception, tags, userCustomData, 0)); FlagAsSent(exception); } else { RaygunLogger.Debug("Not sending exception in background"); } }
/// <summary> /// Transmits an exception to Raygun.io synchronously specifying a list of string tags associated /// with the message for identification, as well as sending a key-value collection of custom data. /// This uses the version number of the originating assembly. /// </summary> /// <param name="exception">The exception to deliver.</param> /// <param name="tags">A list of strings associated with the message.</param> /// <param name="userCustomData">A key-value collection of custom data that will be added to the payload.</param> public void Send(Exception exception, IList <string> tags, IDictionary userCustomData) { if (CanSend(exception)) { StripAndSend(exception, tags, userCustomData, SynchronousTimeout); FlagAsSent(exception); } else { RaygunLogger.Debug("Not sending exception"); } }
protected void FlagAsSent(Exception exception) { if (exception != null && exception.Data != null) { try { Type[] genericTypes = exception.Data.GetType().GetGenericArguments(); if (genericTypes.Length == 0 || genericTypes[0].IsAssignableFrom(typeof(string))) { exception.Data[SentKey] = true; } } catch (Exception ex) { RaygunLogger.Debug($"Failed to flag exception as sent: {ex.Message}"); } } }
private void Send(RaygunMessage raygunMessage, int timeout) { if (!ValidateApiKey()) { RaygunLogger.Error("Failed to send due to invalid API key"); return; } bool canSend = OnSendingMessage(raygunMessage); if (!canSend) { RaygunLogger.Debug("Sending message cancelled"); return; } // No internet then we store the report. if (!HasInternetConnection) { var path = _fileManager.SaveCrashReport(raygunMessage, MaxReportsStoredOnDevice); if (!string.IsNullOrEmpty(path)) { RaygunLogger.Debug("Saved crash report to: " + path); } return; } try { // Create the json data. var jsonData = SimpleJson.SerializeObject(raygunMessage); var statusCode = SendMessage(jsonData, timeout); RaygunLogger.LogResponseStatusCode(statusCode); // Save the message if the application is currently being rate limited or there was a timeout. if (statusCode == (int)RaygunResponseStatusCode.RateLimited || statusCode == (int)RaygunResponseStatusCode.RequestTimeout || statusCode == (int)RaygunResponseStatusCode.GatewayTimeout) { var path = _fileManager.SaveCrashReport(raygunMessage, MaxReportsStoredOnDevice); if (!string.IsNullOrEmpty(path)) { RaygunLogger.Debug("Saved crash report to: " + path); } } } catch (Exception e) { RaygunLogger.Error(string.Format("Failed to send message due to error {0}: {1}", e.GetType().Name, e.Message)); var path = _fileManager.SaveCrashReport(raygunMessage, MaxReportsStoredOnDevice); if (!string.IsNullOrEmpty(path)) { RaygunLogger.Debug("Saved crash report to: " + path); } } }
private void SendAllStoredCrashReports() { if (!HasInternetConnection) { RaygunLogger.Debug("Not sending stored crash reports due to no internet connection"); return; } // Get all stored crash reports. var reports = _fileManager.GetAllStoredCrashReports(); RaygunLogger.Info(string.Format("Attempting to send {0} stored crash report(s)", reports.Count)); // Quick escape if there's no crash reports. if (reports.Count == 0) { return; } try { Task.Run(async() => { // Use a single HttpClient for all requests. using (var client = new HttpClient()) { foreach (var report in reports) { await SendStoredReportAsync(client, report); } } }).ContinueWith(t => { if (t != null && t.IsFaulted) { RaygunLogger.Error("Fault occurred when sending stored reports - clearing stored reports"); try { // If there was an issue then clear the stored reports. _fileManager.RemoveFiles(reports); } catch (Exception e) { RaygunLogger.Error("Failed to remove stored report due to error: " + e.Message); } } if (t != null && t.Exception != null) { // Consume all errors as we dont want them being sent. t.Exception.Handle((e) => { RaygunLogger.Error("Error occurred while sending stored reports: " + e.Message); return(true); // Handled }); } }); } catch (Exception e) { RaygunLogger.Error("Failed to send stored reports due to error: " + e.Message); } }