Beispiel #1
0
        /// <summary>
        /// Tries the posting.
        /// </summary>
        /// <param name="payloadRecord">The payload record.</param>
        /// <returns>RollbarResponse.</returns>
        private RollbarResponse TryPosting(PayloadRecord payloadRecord)
        {
            //Payload payload = JsonConvert.DeserializeObject<Payload>(payloadRecord.PayloadJson);
            //IRollbarConfig config = payload.Data.Notifier.Configuration;
            IRollbarConfig config        = JsonConvert.DeserializeObject <RollbarConfig>(payloadRecord.ConfigJson);
            RollbarClient  rollbarClient = new RollbarClient(config);

            try
            {
                RollbarResponse response =
                    rollbarClient.PostAsJson(config.EndPoint, config.AccessToken, payloadRecord.PayloadJson);
                return(response);
            }
            catch (System.Exception ex)
            {
                this.OnRollbarEvent(
                    new CommunicationErrorEventArgs(null, payloadRecord.PayloadJson, ex, 0)
                    );

                RollbarErrorUtility.Report(
                    null,
                    payloadRecord,
                    InternalRollbarError.PersistentPayloadRecordRepostError,
                    "While trying to report a stored payload...",
                    ex,
                    null
                    );

                return(null);
            }
        }
        /// <summary>
        /// Builds the payload record.
        /// </summary>
        /// <param name="payloadBundle">The payload bundle.</param>
        /// <param name="payloadQueue">The payload queue.</param>
        /// <returns>PayloadRecord.</returns>
        private IPayloadRecord BuildPayloadRecord(PayloadBundle payloadBundle, PayloadQueue payloadQueue)
        {
            try
            {
                if (payloadBundle.Ignorable ||
                    payloadBundle.GetPayload() == null ||
                    !payloadQueue.Client.EnsureHttpContentToSend(payloadBundle)
                    )
                {
                    return(null);
                }

                Task <string> task = payloadBundle.AsHttpContentToSend.ReadAsStringAsync();
                task.Wait();

                return(_storeRepository.CreatePayloadRecord(payloadBundle.GetPayload(), task.Result));
            }
            catch (System.Exception ex)
            {
                RollbarErrorUtility.Report(
                    payloadQueue.Logger,
                    payloadBundle.GetPayload(),
                    InternalRollbarError.PersistentPayloadRecordError,
                    "While attempting to build persistent payload record...",
                    ex,
                    null
                    );
                return(null);
            }
        }
Beispiel #3
0
        /// <summary>
        /// Builds the payload record.
        /// </summary>
        /// <param name="payloadBundle">The payload bundle.</param>
        /// <param name="payloadQueue">The payload queue.</param>
        /// <returns>PayloadRecord.</returns>
        private PayloadRecord BuildPayloadRecord(PayloadBundle payloadBundle, PayloadQueue payloadQueue)
        {
            try
            {
                if (payloadBundle.Ignorable ||
                    payloadBundle.GetPayload() == null ||
                    !payloadQueue.Client.EnsureHttpContentToSend(payloadBundle)
                    )
                {
                    return(null);
                }

                Task <string> task = payloadBundle.AsHttpContentToSend.ReadAsStringAsync();
                task.Wait();
                return(new PayloadRecord()
                {
                    Timestamp = payloadBundle.GetPayload().TimeStamp,
                    ConfigJson = JsonUtil.SerializeAsJsonString(payloadBundle.GetPayload().Data.Notifier.Configuration),
                    PayloadJson = task.Result,
                });
            }
            catch (System.Exception ex)
            {
                RollbarErrorUtility.Report(
                    payloadQueue.Logger,
                    payloadBundle.GetPayload(),
                    InternalRollbarError.PersistentPayloadRecordError,
                    "While attempting to build persistent payload record...",
                    ex,
                    null
                    );
                return(null);
            }
        }
Beispiel #4
0
        /// <summary>
        /// Truncates the payload.
        /// </summary>
        /// <param name="payloadBundle">The payload bundle.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        private bool TruncatePayload(PayloadBundle payloadBundle)
        {
            if (this._payloadTruncationStrategy == null)
            {
                return(true); // as far as truncation is concerned - everything is good...
            }

            Payload payload = payloadBundle.GetPayload();

            if (this._payloadTruncationStrategy.Truncate(payload) > this._payloadTruncationStrategy.MaxPayloadSizeInBytes)
            {
                var exception = new ArgumentOutOfRangeException(
                    paramName: nameof(payload),
                    message: $"Payload size exceeds {this._payloadTruncationStrategy.MaxPayloadSizeInBytes} bytes limit!"
                    );

                RollbarErrorUtility.Report(
                    this._rollbarLogger,
                    payload,
                    InternalRollbarError.PayloadTruncationError,
                    "While truncating a payload...",
                    exception,
                    payloadBundle
                    );

                return(false);
            }

            return(true);
        }
Beispiel #5
0
        /// <summary>
        /// Serializes the payload as json string.
        /// </summary>
        /// <param name="payloadBundle">The payload bundle.</param>
        /// <returns>System.String.</returns>
        private string SerializePayloadAsJsonString(PayloadBundle payloadBundle)
        {
            Payload payload = payloadBundle.GetPayload();

            string jsonData;

            try
            {
                jsonData = JsonConvert.SerializeObject(payload);
            }
            catch (System.Exception exception)
            {
                RollbarErrorUtility.Report(
                    this._rollbarLogger,
                    payload,
                    InternalRollbarError.PayloadSerializationError,
                    "While serializing a payload...",
                    exception,
                    payloadBundle
                    );

                return(null);
            }

            return(jsonData);
        }
        /// <summary>
        /// Persists the specified payload queue.
        /// </summary>
        /// <param name="payloadQueue">The payload queue.</param>
        private void Persist(PayloadQueue payloadQueue)
        {
            var items = payloadQueue.GetItemsToPersist();

            if (items == null || items.Length == 0)
            {
                return;
            }

            string endPoint    = payloadQueue.Logger.Config.EndPoint;
            string accessToken = payloadQueue.AccessTokenQueuesMetadata.AccessToken;

            Destination destination = this._storeContext.Destinations.SingleOrDefault(d =>
                                                                                      d.Endpoint == endPoint &&
                                                                                      d.AccessToken == accessToken
                                                                                      );

            if (destination == null)
            {
                destination = new Destination()
                {
                    Endpoint = endPoint, AccessToken = accessToken,
                };
                this._storeContext.Destinations.Add(destination);
            }

            foreach (var item in items)
            {
                PayloadRecord payloadRecord = this.BuildPayloadRecord(item, payloadQueue);
                if (payloadRecord != null)
                {
                    destination.PayloadRecords.Add(payloadRecord);
                }
            }

            try
            {
                this._storeContext.SaveChanges();
            }
            catch (System.Exception ex)
            {
                RollbarErrorUtility.Report(
                    payloadQueue.Logger,
                    items.Select(i => i.GetPayload()),
                    InternalRollbarError.PersistentStoreContextError,
                    "While attempting to save persistent store context...",
                    ex,
                    null
                    );
            }

            foreach (var item in items)
            {
                item.Signal?.Release();
            }
        }
Beispiel #7
0
        /// <summary>
        /// Ensures the HTTP content to send.
        /// </summary>
        /// <param name="payloadBundle">The payload bundle.</param>
        /// <returns><c>true</c> if succeeds, <c>false</c> otherwise.</returns>
        public bool EnsureHttpContentToSend(PayloadBundle payloadBundle)
        {
            if (payloadBundle.AsHttpContentToSend != null)
            {
                return(true);
            }

            Payload payload = payloadBundle.GetPayload();

            Assumption.AssertNotNull(payload, nameof(payload));

            if (!TruncatePayload(payloadBundle))
            {
                return(false);
            }

            if (!ScrubHttpMessages(payloadBundle))
            {
                return(false);
            }

            string jsonData = SerializePayloadAsJsonString(payloadBundle);

            if (string.IsNullOrWhiteSpace(jsonData))
            {
                return(false);
            }

            try
            {
                jsonData = ScrubPayload(jsonData);
            }
            catch (System.Exception exception)
            {
                RollbarErrorUtility.Report(
                    this._rollbarLogger,
                    payload,
                    InternalRollbarError.PayloadScrubbingError,
                    "While scrubbing a payload...",
                    exception,
                    payloadBundle
                    );

                return(false);
            }

            payloadBundle.AsHttpContentToSend =
                new StringContent(jsonData, Encoding.UTF8, "application/json"); //CONTENT-TYPE header

            Assumption.AssertNotNull(payloadBundle.AsHttpContentToSend, nameof(payloadBundle.AsHttpContentToSend));
            Assumption.AssertTrue(string.Equals(payload.AccessToken, this._rollbarLogger.Config.AccessToken), nameof(payload.AccessToken));

            return(true);
        }
Beispiel #8
0
 private void CheckConnectivityStatus(object state)
 {
     try
     {
         DoCheckConnectivityStatus();
     }
     catch (Exception ex)
     {
         RollbarErrorUtility.Report(null, null, InternalRollbarError.ConnectivityMonitorError, null, ex, null);
     }
 }
Beispiel #9
0
        /// <summary>
        /// Keeps the processing all queues.
        /// </summary>
        /// <param name="data">The data.</param>
        private void KeepProcessingAllQueues(object data)
        {
            CancellationToken cancellationToken = (CancellationToken)data;

            while (!cancellationToken.IsCancellationRequested)
            {
                try
                {
                    lock (this._syncLock)
                    {
                        ProcessAllQueuesOnce();
                    }

                    ProcessPersistentStoreOnce();
                }
#pragma warning disable CS0168 // Variable is declared but never used
                catch (System.Threading.ThreadAbortException tae)
                {
                    return;
                }
                catch (System.Exception ex)
                {
                    RollbarErrorUtility.Report(
                        null,
                        null,
                        InternalRollbarError.QueueControllerError,
                        "While KeepProcessingAllQueues()...",
                        ex,
                        null
                        );

                    //TODO: do we want to direct the exception
                    //      to some kind of Rollbar notifier maintenance "access token"?
                }
#pragma warning restore CS0168 // Variable is declared but never used

                if (cancellationToken.IsCancellationRequested)
                {
                    break;
                }

                Thread.Sleep(this._sleepInterval);
            }

            CompleteProcessing();
        }
        /// <summary>
        /// Persists the specified payload queue.
        /// </summary>
        /// <param name="payloadQueue">The payload queue.</param>
        private void Persist(PayloadQueue payloadQueue)
        {
            if (!payloadQueue.Logger.Config.EnableLocalPayloadStore)
            {
                return;
            }

            var items = payloadQueue.GetItemsToPersist();

            if (items == null || items.Length == 0)
            {
                return;
            }

            string endPoint    = payloadQueue.Logger.Config.EndPoint;
            string accessToken = payloadQueue.AccessTokenQueuesMetadata.AccessToken;

            var payloads = new List <IPayloadRecord>();

            foreach (var item in items)
            {
                payloads.Add(this.BuildPayloadRecord(item, payloadQueue));
            }

            try
            {
                this._storeRepository.SavePayloads(endPoint, accessToken, payloads);
            }
            catch (System.Exception ex)
            {
                RollbarErrorUtility.Report(
                    payloadQueue.Logger,
                    items.Select(i => i.GetPayload()),
                    InternalRollbarError.PersistentStoreContextError,
                    "While attempting to save persistent store context...",
                    ex,
                    null
                    );
            }

            foreach (var item in items)
            {
                item.Signal?.Release();
            }
        }
        /// <summary>
        /// Enqueues the specified data object.
        /// </summary>
        /// <param name="dataObject">The data object.</param>
        /// <param name="level">The level.</param>
        /// <param name="custom">The custom.</param>
        /// <param name="timeout">The timeout.</param>
        /// <param name="signal">The signal.</param>
        /// <returns>ILogger.</returns>
        internal ILogger Enqueue(
            object dataObject,
            ErrorLevel level,
            IDictionary <string, object> custom,
            TimeSpan?timeout     = null,
            SemaphoreSlim signal = null
            )
        {
            // here is the last chance to decide if we need to actually send this payload
            // based on the current config settings:
            if (string.IsNullOrWhiteSpace(this._config.AccessToken) ||
                this._config.Enabled == false ||
                (this._config.LogLevel.HasValue && level < this._config.LogLevel.Value)
                )
            {
                // nice shortcut:
                return(this);
            }

            PayloadBundle payloadBundle;

            try
            {
                payloadBundle = CreatePayloadBundle(dataObject, level, custom, timeout, signal);
            }
            catch (System.Exception exception)
            {
                RollbarErrorUtility.Report(this, dataObject, InternalRollbarError.BundlingError, null, exception);
                return(this);
            }

            try
            {
                this._payloadQueue.Enqueue(payloadBundle);
            }
            catch (System.Exception exception)
            {
                RollbarErrorUtility.Report(this, dataObject, InternalRollbarError.EnqueuingError, null, exception);
            }

            return(this);
        }
Beispiel #12
0
        /// <summary>
        /// Gets the first transmittabl bundle.
        /// </summary>
        /// <param name="queue">The queue.</param>
        /// <returns>PayloadBundle.</returns>
        private PayloadBundle GetFirstTransmittableBundle(PayloadQueue queue)
        {
            PayloadBundle payloadBundle = null;

            bool ignorableBundle = false;

            do
            {
                payloadBundle = queue.Peek();
                if (payloadBundle == null)
                {
                    return(null); // the queue is already empty, nothing to process...
                }

                try
                {
                    ignorableBundle = (payloadBundle.Ignorable || payloadBundle.GetPayload() == null);
                }
                catch (System.Exception ex)
                {
                    RollbarErrorUtility.Report(
                        null,
                        payloadBundle,
                        InternalRollbarError.DequeuingError,
                        "While attempting to dequeue a payload bundle...",
                        ex,
                        payloadBundle
                        );
                    ignorableBundle = true; // since something is not kosher about this bundle/payload, it is wise to ignore one...
                }

                if (ignorableBundle)
                {
                    queue.Dequeue(); //throw away the ignorable...
                    this.OnRollbarEvent(
                        new PayloadDropEventArgs(queue.Logger, null, PayloadDropEventArgs.DropReason.IgnorablePayload)
                        );
                }
            }while (ignorableBundle);

            return(payloadBundle);
        }
Beispiel #13
0
        /// <summary>
        /// Checks the connectivity status.
        /// </summary>
        /// <param name="state">The state.</param>
        private void CheckConnectivityStatus(object state)
        {
            try
            {
                DoCheckConnectivityStatus();
            }
#pragma warning disable CA1031 // Do not catch general exception types
            catch (Exception ex)
            {
                RollbarErrorUtility.Report(
                    null,
                    null,
                    InternalRollbarError.ConnectivityMonitorError,
                    null,
                    ex,
                    null
                    );
            }
#pragma warning restore CA1031 // Do not catch general exception types
        }
        /// <summary>
        /// Posts as json.
        /// </summary>
        /// <param name="accessToken">The access token.</param>
        /// <param name="jsonContent">Content of the json.</param>
        /// <returns>RollbarResponse.</returns>
        public RollbarResponse PostAsJson(string accessToken, string jsonContent)
        {
            Assumption.AssertNotNullOrWhiteSpace(accessToken, nameof(accessToken));
            Assumption.AssertNotNullOrWhiteSpace(jsonContent, nameof(jsonContent));

            // first, let's run quick Internet availability check
            // to minimize potential timeout of the following JSON POST call:
            if (!ConnectivityMonitor.Instance.IsConnectivityOn)
            {
                throw new HttpRequestException("Preliminary ConnectivityMonitor detected offline status!");
            }

            using (CancellationTokenSource cancellationTokenSource = new CancellationTokenSource())
            {
                var task = this.PostAsJsonAsync(accessToken, jsonContent, cancellationTokenSource.Token);

                try
                {
                    if (!task.Wait(this._expectedPostToApiTimeout))
                    {
                        cancellationTokenSource.Cancel(true);
                    }
                    return(task.Result);
                }
                catch (System.Exception ex)
                {
                    RollbarErrorUtility.Report(
                        null,
                        jsonContent,
                        InternalRollbarError.PayloadPostError,
                        "While PostAsJson((string destinationUri, string accessToken, string jsonContent)...",
                        ex,
                        null
                        );
                    return(null);
                }
            }
        }
Beispiel #15
0
        /// <summary>
        /// Processes the specified queue.
        /// </summary>
        /// <param name="queue">The queue.</param>
        /// <param name="response">The response.</param>
        /// <returns>PayloadBundle.</returns>
        private PayloadBundle Process(PayloadQueue queue, out RollbarResponse response)
        {
            response = null;

            PayloadBundle payloadBundle;
            Payload       payload = null;

            bool ignorableBundle = false;

            do
            {
                payloadBundle = queue.Peek();
                if (payloadBundle == null)
                {
                    return(null); // the queue is already empty, nothing to process...
                }

                try
                {
                    ignorableBundle = (payloadBundle.Ignorable || payloadBundle.GetPayload() == null);
                }
                catch (System.Exception ex)
                {
                    RollbarErrorUtility.Report(
                        null,
                        payloadBundle,
                        InternalRollbarError.DequeuingError,
                        "While attempting to dequeue a payload bundle...",
                        ex,
                        payloadBundle
                        );
                    ignorableBundle = true; // since something is not kosher about this bundle/payload, it is wise to ignore one...
                }

                if (ignorableBundle)
                {
                    queue.Dequeue(); //throw away the ignorable...
                    this.OnRollbarEvent(
                        new PayloadDropEventArgs(queue.Logger, null, PayloadDropEventArgs.DropReason.IgnorablePayload)
                        );
                }
                else
                {
                    payload = payloadBundle.GetPayload();
                }
            }while (ignorableBundle);

            if (payloadBundle == null || payload == null) // one more sanity check before proceeding further...
            {
                return(null);
            }

            if (queue.Logger?.Config != null && !queue.Logger.Config.Transmit)
            {
                response = new RollbarResponse();
                this.OnRollbarEvent(
                    new TransmissionOmittedEventArgs(queue.Logger, payload)
                    );
                return(payloadBundle);
            }

            int retries = this._totalRetries;

            while (retries > 0)
            {
                try
                {
                    response = queue.Client.PostAsJson(payloadBundle);
                }
                catch (WebException ex)
                {
                    retries--;
                    this.OnRollbarEvent(
                        new CommunicationErrorEventArgs(queue.Logger, payload, ex, retries)
                        );
                    payloadBundle.Register(ex);
                    Thread.Sleep(this._sleepInterval); // wait a bit before we retry it...
                    continue;
                }
                catch (ArgumentNullException ex)
                {
                    retries = 0;
                    this.OnRollbarEvent(
                        new CommunicationErrorEventArgs(queue.Logger, payload, ex, retries)
                        );
                    payloadBundle.Register(ex);
                    continue;
                }
                catch (System.Exception ex)
                {
                    retries = 0;
                    this.OnRollbarEvent(
                        new CommunicationErrorEventArgs(queue.Logger, payload, ex, retries)
                        );
                    payloadBundle.Register(ex);
                    continue;
                }
                retries = 0;
            }

            if (response != null)
            {
                this.OnRollbarEvent(
                    new CommunicationEventArgs(queue.Logger, payload, response)
                    );
            }
            else
            {
                queue.Dequeue(); //we tried our best...
                payloadBundle.Register(new RollbarException(InternalRollbarError.DequeuingError, "Payload dropped!"));
            }

            return(payloadBundle);
        }
        /// <summary>
        /// Processes the specified queue.
        /// </summary>
        /// <param name="queue">The queue.</param>
        /// <param name="response">The response.</param>
        /// <returns>PayloadBundle.</returns>
        private PayloadBundle Process(PayloadQueue queue, out RollbarResponse response)
        {
            response = null;

            PayloadBundle payloadBundle;
            Payload       payload = null;

            bool ignorableBundle = false;

            do
            {
                payloadBundle = queue.Peek();
                if (payloadBundle == null)
                {
                    return(null); // the queue is already empty, nothing to process...
                }

                try
                {
                    ignorableBundle = (payloadBundle.Ignorable || payloadBundle.GetPayload() == null);
                }
                catch (System.Exception ex)
                {
                    RollbarErrorUtility.Report(
                        null,
                        payloadBundle,
                        InternalRollbarError.DequeuingError,
                        "While attempting to dequeue a payload bundle...",
                        ex
                        );
                    ignorableBundle = true; // since something is not kosher about this bundle/payload, it is wise to ignore one...
                }

                if (ignorableBundle)
                {
                    queue.Dequeue(); //throw away the ignorable...
                }
                else
                {
                    payload = payloadBundle.GetPayload();
                }
            }while (ignorableBundle);

            if (payloadBundle == null || payload == null) // one more sanity check before proceeding further...
            {
                return(null);
            }

            int retries = this._totalRetries;

            while (retries > 0)
            {
                try
                {
                    response = queue.Client.PostAsJson(payloadBundle);
                }
                catch (WebException ex)
                {
                    retries--;
                    this.OnRollbarEvent(
                        new CommunicationErrorEventArgs(queue.Logger, payload, ex, retries)
                        );
                    continue;
                }
                catch (ArgumentNullException ex)
                {
                    retries = 0;
                    this.OnRollbarEvent(
                        new CommunicationErrorEventArgs(queue.Logger, payload, ex, retries)
                        );
                    continue;
                }
                catch (System.Exception ex)
                {
                    retries = 0;
                    this.OnRollbarEvent(
                        new CommunicationErrorEventArgs(queue.Logger, payload, ex, retries)
                        );
                    continue;
                }
                retries = 0;
            }

            if (response != null)
            {
                this.OnRollbarEvent(
                    new CommunicationEventArgs(queue.Logger, payload, response)
                    );
            }

            return(payloadBundle);
        }
        /// <summary>
        /// Gets the payload.
        /// </summary>
        /// <returns>Payload.</returns>
        public Payload GetPayload()
        {
            if (this._payload == null)
            {
                Data data = this.GetPayloadData();
                if (data != null)
                {
                    data.Level = this._level;
                    //update the data timestamp from the data creation timestamp to the passed
                    //object-to-log capture timestamp:
                    data.Timestamp = DateTimeUtil.ConvertToUnixTimestampInSeconds(this._timeStamp);

                    this._payload = new Payload(this._rollbarLogger.Config.AccessToken, data);

                    try // payload check-ignore:
                    {
                        if (this._rollbarLogger.Config.CheckIgnore != null &&
                            this._rollbarLogger.Config.CheckIgnore.Invoke(this._payload)
                            )
                        {
                            this._ignorable = true;
                            return(this._payload);     //shortcut...
                        }
                    }
                    catch (System.Exception exception)
                    {
                        RollbarErrorUtility.Report(
                            this._rollbarLogger,
                            this._payload,
                            InternalRollbarError.PayloadCheckIgnoreError,
                            "While check-ignoring a payload...",
                            exception
                            );
                    }
                    this._ignorable = false;

                    try // payload transformation:
                    {
                        this._rollbarLogger.Config.Transform?.Invoke(this._payload);
                    }
                    catch (System.Exception exception)
                    {
                        RollbarErrorUtility.Report(
                            this._rollbarLogger,
                            this._payload,
                            InternalRollbarError.PayloadTransformError,
                            "While transforming a payload...",
                            exception
                            );
                    }

                    try // payload truncation:
                    {
                        this._rollbarLogger.Config.Truncate?.Invoke(this._payload);
                    }
                    catch (System.Exception exception)
                    {
                        RollbarErrorUtility.Report(
                            this._rollbarLogger,
                            this._payload,
                            InternalRollbarError.PayloadTruncationError,
                            "While truncating a payload...",
                            exception
                            );
                    }

                    try
                    {
                        this._payload.Validate();
                    }
                    catch (System.Exception exception)
                    {
                        RollbarErrorUtility.Report(
                            this._rollbarLogger,
                            this._payload,
                            InternalRollbarError.PayloadValidationError,
                            "While validating a payload...",
                            exception
                            );
                    }
                }
            }
            return(this._payload);
        }
        /// <summary>
        /// Enqueues the data.
        /// </summary>
        /// <param name="dataObject">The data object.</param>
        /// <param name="level">The level.</param>
        /// <param name="custom">The custom.</param>
        /// <param name="timeout">The timeout.</param>
        /// <param name="signal">The signal.</param>
        /// <returns>PayloadBundle.</returns>
        internal PayloadBundle?EnqueueData(
            object dataObject,
            ErrorLevel level,
            IDictionary <string, object?>?custom,
            TimeSpan?timeout     = null,
            SemaphoreSlim?signal = null
            )
        {
            // here is the last chance to decide if we need to actually send this payload
            // based on the current config settings and rate-limit conditions:
            if (string.IsNullOrWhiteSpace(this._config.RollbarDestinationOptions.AccessToken) ||
                !this._config.RollbarDeveloperOptions.Enabled ||
                (level < this._config.RollbarDeveloperOptions.LogLevel)
                )
            {
                // nice shortcut:
                return(null);
            }

            if (this._config.RollbarDeveloperOptions.RethrowExceptionsAfterReporting)
            {
                System.Exception?exception = dataObject as System.Exception;
                if (exception == null &&
                    dataObject is Data data &&
                    data.Body != null
                    )
                {
                    exception = data.Body.OriginalException;
                }

                if (exception != null)
                {
                    try
                    {
                        // Here we need to create another logger instance with similar config but configured not to re-throw.
                        // This would prevent infinite recursive calls (in case if we used this instance or any re-throwing instance).
                        // Because we will be re-throwing the exception after reporting, let's report it fully-synchronously.
                        // This logic is on a heavy side. But, fortunately, RethrowExceptionsAfterReporting is intended to be
                        // a development time option:
                        var config = new RollbarLoggerConfig();
                        config.Reconfigure(this._config);
                        config.RollbarDeveloperOptions.RethrowExceptionsAfterReporting = false;
                        using var rollbar = RollbarFactory.CreateNew(config);
                        rollbar.AsBlockingLogger(TimeSpan.FromSeconds(1)).Log(level, dataObject, custom);
                    }
#pragma warning disable CA1031 // Do not catch general exception types
                    catch
                    {
                        // In case there was a TimeoutException (or any un-expected exception),
                        // there is nothing we can do here.
                        // We tried our best...
                    }
#pragma warning restore CA1031 // Do not catch general exception types
                    finally
                    {
                        if (exception is AggregateException aggregateException)
                        {
                            exception = aggregateException.Flatten();
                        }
                        ExceptionDispatchInfo.Capture(exception).Throw();
                    }

                    return(null);
                }
            }


            PayloadBundle?payloadBundle = null;
            try
            {
                payloadBundle = CreatePayloadBundle(dataObject, level, custom, timeout, signal);
            }
#pragma warning disable CA1031 // Do not catch general exception types
            catch (System.Exception exception)
            {
                RollbarErrorUtility.Report(
                    this,
                    dataObject,
                    InternalRollbarError.BundlingError,
                    null,
                    exception,
                    payloadBundle
                    );
                return(null);
            }
#pragma warning restore CA1031 // Do not catch general exception types

            try
            {
                _ = this._rollbarClient.PostAsJsonAsync(payloadBundle);
            }
#pragma warning disable CA1031 // Do not catch general exception types
            catch (System.Exception exception)
            {
                RollbarErrorUtility.Report(
                    this,
                    dataObject,
                    InternalRollbarError.EnqueuingError,
                    null,
                    exception,
                    payloadBundle
                    );
            }
#pragma warning restore CA1031 // Do not catch general exception types

            return(payloadBundle);
        }
Beispiel #19
0
        /// <summary>
        /// Enqueues the data.
        /// </summary>
        /// <param name="dataObject">The data object.</param>
        /// <param name="level">The level.</param>
        /// <param name="custom">The custom.</param>
        /// <param name="timeout">The timeout.</param>
        /// <param name="signal">The signal.</param>
        /// <returns>PayloadBundle.</returns>
        internal PayloadBundle EnqueueData(
            object dataObject,
            ErrorLevel level,
            IDictionary <string, object> custom,
            TimeSpan?timeout     = null,
            SemaphoreSlim signal = null
            )
        {
            // here is the last chance to decide if we need to actually send this payload
            // based on the current config settings and rate-limit conditions:
            if (string.IsNullOrWhiteSpace(this._config.AccessToken) ||
                this._config.Enabled == false ||
                (this._config.LogLevel.HasValue && level < this._config.LogLevel.Value) ||
                ((this._payloadQueue.AccessTokenQueuesMetadata != null) && this._payloadQueue.AccessTokenQueuesMetadata.IsTransmissionSuspended)
                )
            {
                // nice shortcut:
                return(null);
            }

            if (this._config.RethrowExceptionsAfterReporting)
            {
                System.Exception exception = dataObject as System.Exception;
                if (exception == null)
                {
                    if (dataObject is Data data && data.Body != null)
                    {
                        exception = data.Body.OriginalException;
                    }
                }

                if (exception != null)
                {
                    try
                    {
                        // Here we need to create another logger instance with similar config but configured not to re-throw.
                        // This would prevent infinite recursive calls (in case if we used this instance or any re-throwing instance).
                        // Because we will be re-throwing the exception after reporting, let's report it fully-synchronously.
                        // This logic is on a heavy side. But, fortunately, RethrowExceptionsAfterReporting is intended to be
                        // a development time option:
                        var config = new RollbarConfig();
                        config.Reconfigure(this._config);
                        config.RethrowExceptionsAfterReporting = false;
                        using (var rollbar = RollbarFactory.CreateNew(config))
                        {
                            rollbar.AsBlockingLogger(TimeSpan.FromSeconds(1)).Log(level, dataObject, custom);
                        }
                    }
                    catch
                    {
                        // In case there was a TimeoutException (or any un-expected exception),
                        // there is nothing we can do here.
                        // We tried our best...
                    }
                    finally
                    {
                        if (exception is AggregateException aggregateException)
                        {
                            exception = aggregateException.Flatten();
                            ExceptionDispatchInfo.Capture(
                                exception.InnerException).Throw();
                        }
                        else
                        {
                            ExceptionDispatchInfo.Capture(exception).Throw();
                        }
                    }

                    return(null);
                }
            }


            PayloadBundle payloadBundle = null;

            try
            {
                payloadBundle = CreatePayloadBundle(dataObject, level, custom, timeout, signal);
            }
            catch (System.Exception exception)
            {
                RollbarErrorUtility.Report(
                    this,
                    dataObject,
                    InternalRollbarError.BundlingError,
                    null,
                    exception,
                    payloadBundle
                    );
                return(null);
            }

            try
            {
                this._payloadQueue.Enqueue(payloadBundle);
            }
            catch (System.Exception exception)
            {
                RollbarErrorUtility.Report(
                    this,
                    dataObject,
                    InternalRollbarError.EnqueuingError,
                    null,
                    exception,
                    payloadBundle
                    );
            }

            return(payloadBundle);
        }
Beispiel #20
0
        /// <summary>
        /// post as json as an asynchronous operation.
        /// </summary>
        /// <param name="payloadBundle">The payload bundle.</param>
        /// <returns>Task&lt;RollbarResponse&gt;.</returns>
        public async Task <RollbarResponse> PostAsJsonAsync(PayloadBundle payloadBundle)
        {
            Assumption.AssertNotNull(payloadBundle, nameof(payloadBundle));

            Payload payload = payloadBundle.GetPayload();

            Assumption.AssertNotNull(payload, nameof(payload));

            if (payloadBundle.AsHttpContentToSend == null)
            {
                if (this._payloadTruncationStrategy.Truncate(payload) > this._payloadTruncationStrategy.MaxPayloadSizeInBytes)
                {
                    var exception = new ArgumentOutOfRangeException(
                        paramName: nameof(payload),
                        message: $"Payload size exceeds {this._payloadTruncationStrategy.MaxPayloadSizeInBytes} bytes limit!"
                        );

                    RollbarErrorUtility.Report(
                        this._rollbarLogger,
                        payload,
                        InternalRollbarError.PayloadTruncationError,
                        "While truncating a payload...",
                        exception,
                        payloadBundle
                        );
                }

                string jsonData = null;
                try
                {
                    jsonData = JsonConvert.SerializeObject(payload);
                }
                catch (System.Exception exception)
                {
                    RollbarErrorUtility.Report(
                        this._rollbarLogger,
                        payload,
                        InternalRollbarError.PayloadSerializationError,
                        "While serializing a payload...",
                        exception,
                        payloadBundle
                        );

                    return(null);
                }

                try
                {
                    jsonData = ScrubPayload(jsonData, this._rollbarLogger.Config.GetFieldsToScrub());
                }
                catch (System.Exception exception)
                {
                    RollbarErrorUtility.Report(
                        this._rollbarLogger,
                        payload,
                        InternalRollbarError.PayloadScrubbingError,
                        "While scrubbing a payload...",
                        exception,
                        payloadBundle
                        );

                    return(null);
                }

                payloadBundle.AsHttpContentToSend =
                    new StringContent(jsonData, Encoding.UTF8, "application/json"); //CONTENT-TYPE header
            }

            Assumption.AssertNotNull(payloadBundle.AsHttpContentToSend, nameof(payloadBundle.AsHttpContentToSend));
            Assumption.AssertTrue(string.Equals(payload.AccessToken, this._rollbarLogger.Config.AccessToken), nameof(payload.AccessToken));

            HttpRequestMessage request           = new HttpRequestMessage(HttpMethod.Post, this._payloadPostUri);
            const string       accessTokenHeader = "X-Rollbar-Access-Token";

            request.Headers.Add(accessTokenHeader, this._rollbarLogger.Config.AccessToken);
            request.Content = payloadBundle.AsHttpContentToSend;

            var postResponse = await this._httpClient.SendAsync(request);

            RollbarResponse response = null;

            if (postResponse.IsSuccessStatusCode)
            {
                string reply =
                    await postResponse.Content.ReadAsStringAsync();

                response =
                    JsonConvert.DeserializeObject <RollbarResponse>(reply);
                response.RollbarRateLimit =
                    new RollbarRateLimit(postResponse.Headers);
                response.HttpDetails =
                    $"Response: {postResponse}"
                    + Environment.NewLine
                    + $"Request: {postResponse.RequestMessage}"
                    + Environment.NewLine
                ;
            }
            else
            {
                postResponse.EnsureSuccessStatusCode();
            }

            return(response);
        }