/// <summary>
        /// Gets new session breadcrumbs.
        /// </summary>
        /// <returns>   The breadcrumbs. </returns>
        private static Breadcrumbs SessionStart(string name, int maxCount)
        {
            Breadcrumbs answer = null;

            try {
                // Breadcrumbs answer has previous_session == the previous current_session
                // and new current_session == empty but for new session_start breadcrumb .
                string path = Path.Combine(StorageHelper.CrittercismPath(), name + ".js");
                if (StorageHelper.FileExists(path))
                {
                    answer = StorageHelper.Load(path, typeof(Breadcrumbs)) as Breadcrumbs;
                }
                if (answer == null)
                {
                    answer = new Breadcrumbs(name, maxCount);
                }
                answer.previous_session = answer.current_session;
                answer.current_session  = new List <Breadcrumb>();
                if (name == "UserBreadcrumbs")
                {
                    Dictionary <string, Object> data = new Dictionary <string, Object>();
                    data["text"]  = "session_start";
                    data["level"] = (int)BreadcrumbTextType.Normal;
                    answer.current_session.Add(new Breadcrumb(BreadcrumbType.Text, data));
                }
            } catch (Exception ie) {
                Crittercism.LogInternalException(ie);
            };
            return(answer);
        }
Пример #2
0
        // SendRequest
#if WINDOWS_PHONE_APP
        private bool SendRequest(MessageReport messageReport)
        {
            //Debug.WriteLine("SendRequest: " + messageReport.GetType().Name);
            bool sendCompleted = false;

            Debug.WriteLine("SendRequest: ENTER");
            try {
                HttpWebRequest request = messageReport.WebRequest();
                if (request != null)
                {
                    string        postBody   = messageReport.PostBody();
                    Task <Stream> writerTask = request.GetRequestStreamAsync();
                    using (Stream stream = writerTask.Result) {
                        SendRequestWritePostBody(stream, postBody);
                    }
                    Task <WebResponse> responseTask = request.GetResponseAsync();
                    using (HttpWebResponse response = (HttpWebResponse)responseTask.Result) {
                        sendCompleted = DidReceiveResult(messageReport, response);
                    }
                }
            } catch (Exception ie) {
                Crittercism.LogInternalException(ie);
            }
            Debug.WriteLine("SendRequest: EXIT ---> " + sendCompleted);
            return(sendCompleted);
        }
Пример #3
0
        private bool SendRequest(MessageReport messageReport)
        {
            ////////////////////////////////////////////////////////////////
            // NOTE: sendCompleted is reported as "true" if we get back
            // an HTTP status code from the platform web server.  It is
            // independent of whether or not the HTTP status code is an
            // HTTP status code we like.  Therefore, a 500 internal server
            // error WILL count as sendCompleted == "true" .  OTOH, if
            // there is no network connectivity at all (e.g. airplane mode
            // or out of network coverage), there is no HTTP status code,
            // only some WebException .  We will report "false" in that case
            // and schedule a future retry.
            ////////////////////////////////////////////////////////////////
            //Debug.WriteLine("SendRequest: " + messageReport.GetType().Name);
            bool sendCompleted = true;

            Debug.WriteLine("SendRequest: ENTER");
            try {
                HttpWebRequest request = messageReport.WebRequest();
                if (request != null)
                {
                    string           postBody   = messageReport.PostBody();
                    ManualResetEvent resetEvent = new ManualResetEvent(false);
                    request.BeginGetRequestStream(
                        (result) => {
                        //Debug.WriteLine("SendRequest: BeginGetRequestStream");
                        try {
                            using (Stream stream = request.EndGetRequestStream(result)) {
                                SendRequestWritePostBody(stream, postBody);
                            }
                            request.BeginGetResponse(
                                (asyncResponse) => {
                                sendCompleted = DidReceiveResult(messageReport, request, asyncResponse);
                                resetEvent.Set();
                            }, null);
                        } catch {
                            resetEvent.Set();
                        }
                    }, null);
                    {
#if DEBUG
                        Stopwatch stopWatch = new Stopwatch();
                        stopWatch.Start();
#endif
                        resetEvent.WaitOne();
#if DEBUG
                        stopWatch.Stop();
                        Debug.WriteLine("SendRequest: TOTAL SECONDS == " + stopWatch.Elapsed.TotalSeconds);
#endif
                    }
                }
            } catch (Exception ie) {
                Crittercism.LogInternalException(ie);
            }
            Debug.WriteLine("SendRequest: EXIT ---> " + sendCompleted);
            return(sendCompleted);
        }
        /// <summary>
        /// Saves to disk.
        /// </summary>
        /// <param name="Data"> The data. </param>
        /// <returns>   true if it succeeds, false if it fails. </returns>
        internal static bool Save(object data)
        {
            bool answer = false;

            try {
                string path = Path.Combine(CrittercismPath(), data.GetType().Name + ".js");
                answer = Save(data, path);
            } catch (Exception ie) {
                Crittercism.LogInternalException(ie);
            };
            return(answer);
        }
        /// <summary>
        /// Loads from disk.
        /// </summary>
        /// <param name="dataType"> Type of the data. </param>
        /// <returns>   true if it succeeds, false if it fails. </returns>
        internal static object Load(Type dataType)
        {
            object data = null;

            try {
                string path = Path.Combine(CrittercismPath(), dataType.Name + ".js");
                data = Load(path, dataType);
            } catch (Exception ie) {
                Crittercism.LogInternalException(ie);
            };
            return(data);
        }
        internal static MessageReport LoadMessage(string name)
        {
            // name is wrt MessagesPath "Crittercism\Messages", e.g "Crash_<guid>"
            // path is Crittercism\Messages\name
            MessageReport messageReport = null;

            try {
                string   path      = Path.Combine(MessagesPath, name);
                string[] nameSplit = name.Split('_');
                switch (nameSplit[0])
                {
                case "AppLoad":
                    messageReport = (AppLoad)StorageHelper.Load(path, typeof(AppLoad));
                    break;

                case "APMReport":
                    messageReport = (APMReport)StorageHelper.Load(path, typeof(APMReport));
                    break;

                case "HandledException":
                    messageReport = (HandledException)StorageHelper.Load(path, typeof(HandledException));
                    break;

                case "CrashReport":
                    messageReport = (CrashReport)StorageHelper.Load(path, typeof(CrashReport));
                    break;

                case "MetadataReport":
                    messageReport = (MetadataReport)StorageHelper.Load(path, typeof(MetadataReport));
                    break;

                default:
                    // Skip this file.
                    break;
                }
                if (messageReport == null)
                {
                    // Possibly file is still being written.  Skip file for
                    // now by returning null .
                }
                else
                {
                    messageReport.Name         = name;
                    messageReport.CreationTime = StorageHelper.GetCreationTime(path);
                    messageReport.Saved        = true;
                }
            } catch (Exception ie) {
                Crittercism.LogInternalException(ie);
            }
            return(messageReport);
        }
Пример #7
0
 internal void DidReceiveResponseShared(MessageReport messageReport, HttpWebResponse response)
 {
     try {
         //Debug.WriteLine("DidReceiveResponseShared: response.StatusCode == " + (int)response.StatusCode);
         if ((((long)response.StatusCode) / 100) == 2)
         {
             // 2xx Success
             using (StreamReader reader = (new StreamReader(response.GetResponseStream()))) {
                 string responseText = reader.ReadToEnd();
                 messageReport.DidReceiveResponse(responseText);
             }
         }
     } catch (Exception ie) {
         Crittercism.LogInternalException(ie);
     }
 }
        /// <summary>
        /// Save JSON serializable data object to disk.
        /// </summary>
        /// <param name="Data"> The data. </param>
        /// <returns>   true if it succeeds, false if it fails. </returns>
        internal static bool Save(object data, string path)
        {
            bool answer = false;

            try {
                Debug.WriteLine("Save: " + Path.Combine(StoragePath(), path));
                string dataString = JsonConvert.SerializeObject(data);
                Debug.WriteLine("JSON:");
                Debug.WriteLine(dataString);
                SaveString(path, dataString);
                answer = true;
            } catch (Exception ie) {
                Crittercism.LogInternalException(ie);
            };
            return(answer);
        }
        /// <summary>
        /// Saves to disk.
        /// </summary>
        /// <returns>   true if it succeeds, false if it fails. </returns>
        private bool Save()
        {
            bool answer = false;

            try {
                lock (this) {
                    if (!saved)
                    {
                        answer = StorageHelper.Save(this);
                        saved  = true;
                    }
                }
            } catch (Exception ie) {
                Crittercism.LogInternalException(ie);
            }
            return(answer);
        }
 private void AddBreadcrumb(BreadcrumbType breadcrumbType, Object data)
 {
     try {
         lock (this) {
             current_session.Add(new Breadcrumb(breadcrumbType, data));
             if (current_session.Count > maxCount)
             {
                 // Remove the oldest breadcrumb after the "session_start".
                 // Only userBreadcrumbs will contain a "session_start".
                 current_session.RemoveAt((this == userBreadcrumbs) ? 1 : 0);
             }
             saved = false;
         };
     } catch (Exception ie) {
         Crittercism.LogInternalException(ie);
         // explicit nop
     }
 }
Пример #11
0
 private void ReadStep()
 {
     Debug.WriteLine("ReadStep: ENTER");
     try {
         int retry = 0;
         while (Crittercism.initialized &&
                (Crittercism.MessageQueue != null) &&
                (Crittercism.MessageQueue.Count > 0) &&
                (NetworkInterface.GetIsNetworkAvailable()) &&
                (retry < 3))
         {
             if (SendMessage())
             {
                 retry = 0;
             }
             else
             {
                 // TODO: Use System.Timers.Timer to generate an event
                 // 5 minutes from now, wait for it, then proceed.
                 retry++;
                 Debug.WriteLine("ReadStep: retry == " + retry);
             }
         }
         ;
         if (Crittercism.initialized)
         {
             // Opportune time to save Crittercism state.  Unable to make the MessageQueue
             // shorter either because SendMessage failed or MessageQueue has gone empty.
             // The readerThread will be going into a do nothing wait state after this.
             // (If Crittercism.initialized==false, we are shut down or shutting down, and
             // we must not call Crittercism.Save since this can lead to DEADLOCK.
             // Crittercism.Shutdown may have lock on Crittercism.lockObject, and is waiting
             // for our readerThread to exit.  Crittercism.Save would try to acquire
             // Crittercism.lockObject, but can't.)
             Crittercism.Save();
         }
         ;
     } catch (Exception ie) {
         Crittercism.LogInternalException(ie);
     }
     Debug.WriteLine("ReadStep: EXIT");
 }
Пример #12
0
        private bool SendMessage()
        {
            //Debug.WriteLine("SendMessage: ENTER");
            bool sendCompleted = false;

            try {
                if ((Crittercism.MessageQueue != null) && (Crittercism.MessageQueue.Count > 0))
                {
                    if ((Crittercism.TestNetwork != null) || NetworkInterface.GetIsNetworkAvailable())
                    {
                        MessageReport messageReport = Crittercism.MessageQueue.Peek();
                        Debug.WriteLine("SendMessage: " + messageReport.GetType().Name);
                        Crittercism.MessageQueue.Dequeue();
                        messageReport.Delete();
                        try {
                            if (Crittercism.TestNetwork != null)
                            {
                                // This case used by UnitTest .
                                sendCompleted = Crittercism.TestNetwork.SendRequest(messageReport);
                            }
                            else
                            {
                                sendCompleted = SendRequest(messageReport);
                            }
                        } catch (Exception ie) {
                            Crittercism.LogInternalException(ie);
                        }
                        if (!sendCompleted)
                        {
                            Crittercism.MessageQueue.Enqueue(messageReport);
                        }
                    }
                }
                ;
            } catch (Exception ie) {
                Crittercism.LogInternalException(ie);
            }
            //Debug.WriteLine("SendMessage: EXIT ---> "+sendCompleted);
            return(sendCompleted);
        }
Пример #13
0
 internal void ReadQueue()
 {
     Debug.WriteLine("ReadQueue: ENTER");
     try {
         while (Crittercism.initialized)
         {
             ReadStep();
             Debug.WriteLine("ReadQueue: SLEEP");
             // wake up again 300000 milliseconds == 5 minute timeout from now
             // even without prompting.  Useful if last SendMessage failed and
             // it seems time to try again despite no new messages have poured
             // into the MessageQueue which would have "Set" the readerEvent.
             const int READQUEUE_MILLISECONDS_TIMEOUT = 300000;
             Crittercism.readerEvent.WaitOne(READQUEUE_MILLISECONDS_TIMEOUT);
             Debug.WriteLine("ReadQueue: WAKE");
         }
         ;
     } catch (Exception ie) {
         Crittercism.LogInternalException(ie);
     }
     Debug.WriteLine("ReadQueue: EXIT");
 }
        /// <summary>
        /// Deletes the message from disk.
        /// </summary>
        /// <returns>   true if it succeeds, false if it fails. </returns>
        internal bool Delete()
        {
            bool answer = false;

            try {
                lock (this) {
                    if (Saved)
                    {
                        string path = Path.Combine(MessagesPath, this.Name);
                        if (StorageHelper.FileExists(path))
                        {
                            StorageHelper.DeleteFile(path);
                            Saved = false;
                        }
                    }
                    answer = true;
                }
            } catch (Exception ie) {
                Crittercism.LogInternalException(ie);
            };
            return(answer);
        }
        internal static bool FolderExists(string path)
        {
            //Debug.WriteLine("FolderExists: "+path);
            bool answer = false;

#if NETFX_CORE
            try {
                StorageFolder folder = TryGetFolder(path);
                if (folder != null)
                {
                    //Debug.WriteLine("FolderExists: answer=true");
                    answer = true;
                }
            } catch (Exception ie) {
                Crittercism.LogInternalException(ie);
            }
#else
            answer = GetStore().DirectoryExists(path);
#endif
            //Debug.WriteLine("FolderExists --> "+answer);
            return(answer);
        }
        /// <summary>
        /// Saves the message to disk.
        /// </summary>
        /// <returns>   true if it succeeds, false if it fails. </returns>
        public bool Save()
        {
            // On-disk serialization in JSON alone isn't C# type-preserving.
            // So, this.GetType().Name+"_" is prefixed to file Name .
            bool answer = false;

            try {
                lock (this) {
                    if (!Saved)
                    {
                        Name = this.GetType().Name + "_" + Guid.NewGuid().ToString() + ".js";
                        string path = Path.Combine(MessagesPath, Name);
                        StorageHelper.Save(this, path);
                        Saved  = true;
                        answer = true;
                    }
                }
            } catch (Exception ie) {
                Crittercism.LogInternalException(ie);
            };
            return(answer);
        }
        /// <summary>
        /// Load JSON deserializable data object from IsolatedStorageFile path.
        /// </summary>
        /// <param name="dataType"> Type of the data. </param>
        /// <returns>   true if it succeeds, false if it fails. </returns>
        internal static object Load(string path, Type dataType)
        {
            object data = null;

            try {
                Debug.WriteLine("Load: " + Path.Combine(StoragePath(), path));
                if (FileExists(path))
                {
                    string dataString = LoadString(path);
                    if (dataString == null)
                    {
                        // Unable to read file.  Maybe something is still writing
                        // it?  Return null in this case.  Will try again later.
                    }
                    else
                    {
                        try {
                            data = JsonConvert.DeserializeObject(dataString, dataType);
                        } catch (Exception) {
                            Debug.WriteLine("Load: Unable to parse " + path);
                            // Try to DeleteFile anything we can't parse.  It might be
                            // a partly written file terminated by an earlier crash.
                            try {
                                StorageHelper.DeleteFile(path);
                            } catch (Exception) {
                            }
                        }
                    }
                }
                else
                {
                    Debug.WriteLine("Load: File doesn't exist " + path);
                }
            } catch (Exception ie) {
                Crittercism.LogInternalException(ie);
            }
            return(data);
        }
Пример #18
0
 ////////////////////////////////////////////////////////////////
 //    EXAMPLE APM "config" EXTRACTED FROM PLATFORM AppLoad RESPONSE JSON
 // {"net":{"enabled":true,
 //         "persist":false,
 //         "interval":10}}
 // See example in AppLoad.cs for context.
 ////////////////////////////////////////////////////////////////
 internal static void SettingsChange()
 {
     try {
         if (Crittercism.Settings != null)
         {
             // Both "apm" and "config" should be non-null since other
             // code already sanity checked Crittercism.Settings, but checking
             // again doesn't hurt anything.
             JObject apm = Crittercism.Settings["apm"] as JObject;
             if (apm != null)
             {
                 JObject config = apm["net"] as JObject;
                 if (config != null)
                 {
                     if (config["enabled"] != null)
                     {
                         bool enabled = (bool)((JValue)(config["enabled"])).Value;
                         if (enabled)
                         {
                             // NOTE: Platform sends "interval" in seconds, but method Enable wants
                             // that time converted to milliseconds.
                             int interval = (int)(Convert.ToDouble(((JValue)(config["interval"])).Value) * TimeUtils.MSEC_PER_SEC);
                             Enable(interval);
                         }
                         else
                         {
                             Disable();
                         }
                     }
                 }
             }
         }
     } catch (Exception ie) {
         Crittercism.LogInternalException(ie);
     }
 }