/// <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); } }
/// <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); } }
/// <summary> /// Initializes a new instance of the <see cref="RollbarLogger" /> class. /// </summary> /// <param name="isSingleton">if set to <c>true</c> [is singleton].</param> /// <param name="rollbarConfig">The rollbar configuration.</param> internal RollbarLogger(bool isSingleton, IRollbarConfig rollbarConfig) { if (!TelemetryCollector.Instance.IsAutocollecting) { TelemetryCollector.Instance.StartAutocollection(); } this.IsSingleton = isSingleton; if (rollbarConfig != null) { ValidateConfiguration(rollbarConfig); this._config = new RollbarConfig(this).Reconfigure(rollbarConfig); } else { this._config = new RollbarConfig(this); } // let's figure out where to keep the local payloads store: StoreContext.RollbarStoreDbFullName = ((RollbarConfig)this._config).GetLocalPayloadStoreFullPathName(); // let's init proper Rollbar client: var rollbarClient = new RollbarClient(this); // let's init the corresponding queue and register it: this._payloadQueue = new PayloadQueue(this, rollbarClient); RollbarQueueController.Instance.Register(this._payloadQueue); }
/// <summary> /// Handles the Reconfigured event of the Config control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> private void Config_Reconfigured(object sender, EventArgs e) { RollbarConfig config = (RollbarConfig)sender; Assumption.AssertNotNull(config, nameof(config)); string newStorePath = config.GetLocalPayloadStoreFullPathName(); if (this._useLocalPayloadStore && string.Compare(newStorePath, StoreContext.RollbarStoreDbFullName, false) != 0) { this.Stop(true); StoreContext.RollbarStoreDbFullName = newStorePath; this.Start(); } lock (this._syncLock) { this.ReevaluateUseOfLocalPayloadStore(); PayloadQueue queue = config.Logger.Queue; Assumption.AssertNotNull(queue, nameof(queue)); //refresh indexing: this.DropIndexByToken(queue); this.IndexByToken(queue); Debug.WriteLine(this.GetType().Name + ": Re-indexed a reconfigured queue. Total queues count: " + this._allQueues.Count + "."); } }
private void ObeyPayloadTimeout(Payload payload, PayloadQueue queue) { if (payload.TimeoutAt.HasValue && (DateTime.Now.Add(this._sleepInterval) >= payload.TimeoutAt.Value)) { queue.Dequeue(); } }
/// <summary> /// Initializes a new instance of the <see cref="RollbarLogger"/> class. /// </summary> /// <param name="isSingleton">if set to <c>true</c> [is singleton].</param> /// <param name="rollbarConfig">The rollbar configuration.</param> internal RollbarLogger(bool isSingleton, IRollbarConfig rollbarConfig) { if (!TelemetryCollector.Instance.IsAutocollecting) { TelemetryCollector.Instance.StartAutocollection(); } this.IsSingleton = isSingleton; if (rollbarConfig != null) { this._config = rollbarConfig; } else { this._config = new RollbarConfig(this); } var rollbarClient = new RollbarClient( this._config , RollbarQueueController.Instance.ProvideHttpClient( this._config.ProxyAddress, this._config.ProxyUsername, this._config.ProxyPassword ) ); this._payloadQueue = new PayloadQueue(this, rollbarClient); RollbarQueueController.Instance.Register(this._payloadQueue); }
internal RollbarLogger(bool isSingleton) { try { this._nativeTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext(); } #pragma warning disable CS0168 // Variable is declared but never used catch (InvalidOperationException ex) #pragma warning restore CS0168 // Variable is declared but never used { // it could be a valid case in some environments: this._nativeTaskScheduler = null; } if (!TelemetryCollector.Instance.IsAutocollecting) { TelemetryCollector.Instance.StartAutocollection(); } this.IsSingleton = isSingleton; this._config = new RollbarConfig(this); var rollbarClient = new RollbarClient( this._config , RollbarQueueController.Instance.ProvideHttpClient(this._config.ProxyAddress, this._config.ProxyUsername, this._config.ProxyPassword) ); this._payloadQueue = new PayloadQueue(this, rollbarClient); RollbarQueueController.Instance.Register(this._payloadQueue); }
/// <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(); } }
/// <summary> /// Drops the index by token. /// </summary> /// <param name="queue">The queue.</param> private void DropIndexByToken(PayloadQueue queue) { foreach (var tokenMetadata in this._queuesByAccessToken.Values) { if (tokenMetadata.Unregister(queue)) { break; } } }
private Payload Process(PayloadQueue queue, out RollbarResponse response) { response = null; Payload payload = queue.Peek(); if (payload == null) { return(null); } int retries = 3; while (retries > 0) { try { response = queue.Client.PostAsJson(payload); } 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(payload); }
private void DropIndexByToken(PayloadQueue queue) { foreach (var tokenMetadata in this._queuesByAccessToken.Values) { if (tokenMetadata.Queues.Contains(queue)) { tokenMetadata.Queues.Remove(queue); break; } } }
/// <summary> /// Registers the specified queue. /// </summary> /// <param name="queue">The queue.</param> internal void Register(PayloadQueue queue) { lock (this._syncLock) { Assumption.AssertTrue(!this._allQueues.Contains(queue), nameof(queue)); this._allQueues.Add(queue); this.IndexByToken(queue); queue.Logger.Config.Reconfigured += Config_Reconfigured; Debug.WriteLine(this.GetType().Name + ": Registered a queue. Total queues count: " + this._allQueues.Count + "."); } }
/// <summary> /// Registers the specified queue. /// </summary> /// <param name="queue">The queue.</param> internal void Register(PayloadQueue queue) { lock (this._syncLock) { Assumption.AssertTrue(!this._allQueues.Contains(queue), nameof(queue)); this._allQueues.Add(queue); this.IndexByToken(queue); ((RollbarConfig)queue.Logger.Config).Reconfigured += Config_Reconfigured; // The following debug line causes stack overflow when RollbarTraceListener is activated: Debug.WriteLineIf(RollbarTraceListener.InstanceCount == 0, this.GetType().Name + ": Registered a queue. Total queues count: " + this._allQueues.Count + "."); } }
/// <summary> /// Registers the specified queue. /// </summary> /// <param name="queue">The queue.</param> /// <returns><c>true</c> if the queue was actually reqistered during this call, <c>false</c> if the queue was already registered prior to this call.</returns> public bool Register(PayloadQueue queue) { lock (this._queuesSyncLock) { if (this._queues.Add(queue)) { queue.AccessTokenQueuesMetadata = this; return(true); } else { return(false); } } }
/// <summary> /// Unregisters the specified queue. /// </summary> /// <param name="queue">The queue.</param> /// <returns><c>true</c> if the queue was actually unregistered, <c>false</c> if the queue was not even registered in the first place.</returns> public bool Unregister(PayloadQueue queue) { lock (this._queuesSyncLock) { if (this._queues.Remove(queue)) { queue.AccessTokenQueuesMetadata = null; return(true); } else { return(false); } } }
/// <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 = GetFirstTransmittableBundle(queue); Payload payload = payloadBundle?.GetPayload(); if (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); } try { response = queue.Client.PostAsJson(payloadBundle); } catch (System.Exception ex) { this.OnRollbarEvent( new CommunicationErrorEventArgs(queue.Logger, payload, ex, 0) ); payloadBundle.Register(ex); throw; } 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); }
private void Config_Reconfigured(object sender, EventArgs e) { lock (this._syncLock) { RollbarConfig config = (RollbarConfig)sender; Assumption.AssertNotNull(config, nameof(config)); PayloadQueue queue = config.Logger.Queue; Assumption.AssertNotNull(queue, nameof(queue)); //refresh indexing: this.DropIndexByToken(queue); this.IndexByToken(queue); Debug.WriteLine(this.GetType().Name + ": Re-indexed a reconfigured queue. Total queues count: " + this._allQueues.Count + "."); } }
/// <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(); } }
private void IndexByToken(PayloadQueue queue) { string queueToken = queue.Logger.Config.AccessToken; if (queueToken == null) { //this is a valid case for the RollbarLogger singleton instance, //when the instance is created but not configured yet... return; } if (!this._queuesByAccessToken.TryGetValue(queueToken, out AccessTokenQueuesMetadata tokenMetadata)) { tokenMetadata = new AccessTokenQueuesMetadata(queueToken); this._queuesByAccessToken.Add(queueToken, tokenMetadata); } tokenMetadata.Queues.Add(queue); }
internal RollbarLogger(bool isSingleton) { try { this._nativeTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext(); } #pragma warning disable CS0168 // Variable is declared but never used catch (InvalidOperationException ex) #pragma warning restore CS0168 // Variable is declared but never used { // it could be a valid case in some environments: this._nativeTaskScheduler = null; } this.IsSingleton = isSingleton; this._config = new RollbarConfig(this); this._payloadQueue = new PayloadQueue(this); RollbarQueueController.Instance.Register(this._payloadQueue); }
/// <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); }
/// <summary> /// Initializes a new instance of the <see cref="RollbarLogger" /> class. /// </summary> /// <param name="isSingleton">if set to <c>true</c> [is singleton].</param> /// <param name="rollbarConfig">The rollbar configuration.</param> internal RollbarLogger(bool isSingleton, IRollbarConfig rollbarConfig) { if (!TelemetryCollector.Instance.IsAutocollecting) { TelemetryCollector.Instance.StartAutocollection(); } this.IsSingleton = isSingleton; if (rollbarConfig != null) { this._config = new RollbarConfig(this).Reconfigure(rollbarConfig); } else { this._config = new RollbarConfig(this); } var rollbarClient = new RollbarClient(this); this._payloadQueue = new PayloadQueue(this, rollbarClient); RollbarQueueController.Instance.Register(this._payloadQueue); }
/// <summary> /// Registers the specified queue. /// </summary> /// <param name="queue">The queue.</param> internal void Register(PayloadQueue queue) { lock (this._syncLock) { Assumption.AssertTrue(!this._allQueues.Contains(queue), nameof(queue)); this._allQueues.Add(queue); this.IndexByToken(queue); this._useLocalPayloadStore |= queue.Logger.Config.EnableLocalPayloadStore; if (this._useLocalPayloadStore && this._storeContext == null) { Debug.WriteLine(this.GetType().Name + ": Initializing StoreContext from: " + nameof(this.Register) + "..."); this._storeContext = new StoreContext(); this._storeContext.MakeSureDatabaseExistsAndReady(); Debug.WriteLine(this.GetType().Name + ": Initialized StoreContext from: " + nameof(this.Register) + "."); } ((RollbarConfig)queue.Logger.Config).Reconfigured += Config_Reconfigured; // The following debug line causes stack overflow when RollbarTraceListener is activated: Debug.WriteLineIf(RollbarTraceListener.InstanceCount == 0, this.GetType().Name + ": Registered a queue. Total queues count: " + this._allQueues.Count + "."); } }
/// <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); }
private PayloadBundle Process(PayloadQueue queue, out RollbarResponse response) { response = null; PayloadBundle payloadBundle = queue.Peek(); while (payloadBundle != null && (payloadBundle.Ignorable || payloadBundle.GetPayload() == null)) { queue.Dequeue(); //throw away the useless one... payloadBundle = queue.Peek(); //try next... } if (payloadBundle == null) { return(null); //no bundles to process... } Payload payload = payloadBundle.GetPayload(); if (payload == null) { 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> /// 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); }