示例#1
0
        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);
            }
        }
示例#2
0
        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);
        }
示例#4
0
        /// <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
            }
        }
示例#5
0
        /// <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);
        }
示例#6
0
        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));
            }
        }
示例#7
0
 private static void RemoveUnhandledExceptionHandlers()
 {
     if (_exceptionHandlersSet)
     {
         _exceptionHandlersSet = false;
         RaygunLogger.Debug("Removing exception handlers");
         AppDomain.CurrentDomain.UnhandledException -= CurrentDomain_UnhandledException;
         TaskScheduler.UnobservedTaskException      -= TaskScheduler_UnobservedTaskException;
     }
 }
示例#8
0
 private static void SetUnhandledExceptionHandlers()
 {
     if (!_exceptionHandlersSet)
     {
         _exceptionHandlersSet = true;
         RaygunLogger.Debug("Adding exception handlers");
         AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
         TaskScheduler.UnobservedTaskException      += TaskScheduler_UnobservedTaskException;
     }
 }
示例#9
0
        /// <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);
        }
示例#10
0
 /// <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");
     }
 }
示例#11
0
 /// <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");
     }
 }
示例#12
0
 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}");
         }
     }
 }
示例#13
0
        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);
                }
            }
        }
示例#14
0
        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);
            }
        }