/// <summary> /// Initializes a new instance of the <see cref="SumoLogicSink"/> class. /// </summary> /// <param name="log">The log service.</param> /// <param name="httpMessageHandler">HTTP message handler.</param> /// <param name="connection">Connection configuration.</param> /// <param name="source">Event source describer.</param> /// <param name="formatter">Text formatter.</param> public SumoLogicSink( ILog log, HttpMessageHandler httpMessageHandler, SumoLogicConnection connection, SumoLogicSource source, ITextFormatter formatter) { if (connection is null) { throw new ArgumentNullException(nameof(connection)); } if (source is null) { throw new ArgumentNullException(nameof(source)); } _formatter = formatter ?? throw new ArgumentNullException(nameof(formatter)); _log = log ?? new DummyLog(); _messageSender = MessageSenderFactory.CreateMessageSender(_log, httpMessageHandler, connection); _messageQueue = MessageQueueFactory.CreateMessageQueue(_log, connection); SumoLogicMessageSenderBufferFlushingTask flushBufferTask = FlushBufferTaskFactory.CreateFlushBufferTask( _log, _messageSender, _messageQueue, connection, source); _flushBufferTimer = new Timer( _ => flushBufferTask.Run(), null, TimeSpan.FromMilliseconds(0), connection.FlushingAccuracy); }
/// <summary> /// Initializes a new instance of the <see cref="SumoLogicMessageSenderTest"/> class. /// </summary> public SumoLogicMessageSenderTest() { this.messagesHandler = new MockHttpMessageHandler(); this.sumoLogicMessageSender = new SumoLogicMessageSender(this.messagesHandler, null); this.sumoLogicMessageSender.Url = new Uri("http://www.fakeadress.com"); this.sumoLogicMessageSender.RetryInterval = TimeSpan.FromSeconds(30); }
/// <summary> /// Initializes a new instance of the <see cref="SumoLogicSink"/> class. /// </summary> /// <param name="log">The log service.</param> /// <param name="httpMessageHandler">HTTP message handler.</param> /// <param name="connection">Connection configuration.</param> /// <param name="source">Event source describer.</param> /// <param name="formatter">Text formatter.</param> public SumoLogicSink( ILog log, HttpMessageHandler httpMessageHandler, SumoLogicConnection connection, SumoLogicSource source, ITextFormatter formatter) { if (connection is null) { throw new ArgumentNullException(nameof(connection)); } this.source = source ?? throw new ArgumentNullException(nameof(source)); this.formatter = formatter ?? throw new ArgumentNullException(nameof(formatter)); this.logService = log ?? new DummyLog(); this.messageSender = new SumoLogicMessageSender(httpMessageHandler, this.logService) { Url = connection.Uri, ClientName = connection.ClientName, ConnectionTimeout = connection.ConnectionTimeout, RetryInterval = connection.RetryInterval, }; }
/// <summary> /// Initialize the target based on the options set /// </summary> /// <remarks> /// This is part of the nLog is called when the Configurations of the LogManager are set. /// If any of the configuration properties are modified then you must set anew the Configuration of the LogManager. /// </remarks> protected override void InitializeTarget() { if (this.UseConsoleLog) { this.ActivateConsoleLog(); } if (this.LogLog.IsDebugEnabled) { this.LogLog.Debug("Activating options"); } // Initialize the messages queue if (this.messagesQueue == null) { this.messagesQueue = new BufferWithFifoEviction <string>(this.MaxQueueSizeBytes, new StringLengthCostAssigner(), this.LogLog); } else { this.messagesQueue.Capacity = this.MaxQueueSizeBytes; } // Initialize the sender if (this.SumoLogicMessageSender == null) { this.SumoLogicMessageSender = new SumoLogicMessageSender(this.HttpMessageHandler, this.LogLog); } this.SumoLogicMessageSender.RetryInterval = TimeSpan.FromMilliseconds(this.RetryInterval); this.SumoLogicMessageSender.ConnectionTimeout = TimeSpan.FromMilliseconds(this.ConnectionTimeout); this.SumoLogicMessageSender.Url = string.IsNullOrEmpty(this.Url) ? null : new Uri(this.Url); // Initialize flusher if (this.flushBufferTimer != null) { this.flushBufferTimer.Stop(); this.flushBufferTimer.Dispose(); } // Ensure any existing buffer is flushed if (this.flushBufferTask != null) { this.flushBufferTask.FlushAndSend(); } this.flushBufferTask = new SumoLogicMessageSenderBufferFlushingTask( this.messagesQueue, this.SumoLogicMessageSender, TimeSpan.FromMilliseconds(this.MaxFlushInterval), this.MessagesPerRequest, this.SourceName, this.LogLog); this.flushBufferTimer = new Timer(TimeSpan.FromMilliseconds(this.FlushingAccuracy).TotalMilliseconds); this.flushBufferTimer.Elapsed += (s, e) => this.flushBufferTask.Run(); this.flushBufferTimer.Start(); }
/// <summary> /// Is called when the target is closed. /// </summary> /// /// <remarks> /// Releases any resources allocated within the target such as file handles, network connections, etc. /// </remarks> protected override void CloseTarget() { base.CloseTarget(); if (this.SumoLogicMessageSender != null) { this.SumoLogicMessageSender.Dispose(); this.SumoLogicMessageSender = null; } }
/// <summary> /// Initialize the appender based on the options set /// </summary> /// <remarks> /// This is part of the log4net.Core.IOptionHandler delayed object activation scheme. The ActivateOptions() method must be called /// on this object after the configuration properties have been set. Until ActivateOptions() is called this object is in an undefined /// state and must not be used. If any of the configuration properties are modified then ActivateOptions() must be called again. /// </remarks> public override void ActivateOptions() { if (this.UseConsoleLog) { this.ActivateConsoleLog(); } if (this.LogLog.IsDebugEnabled) { this.LogLog.Debug("Activating options"); } // Initialize the messages queue if (this.messagesQueue == null) { this.messagesQueue = new BufferWithFifoEviction <string>(this.MaxQueueSizeBytes, new StringLengthCostAssigner(), this.LogLog); } else { this.messagesQueue.Capacity = this.MaxQueueSizeBytes; } // Initialize the sender if (this.SumoLogicMessageSender == null) { this.SumoLogicMessageSender = new SumoLogicMessageSender(this.HttpMessageHandler, this.LogLog, "sumo-log4net-buffered-sender"); } this.SumoLogicMessageSender.RetryInterval = TimeSpan.FromMilliseconds(this.RetryInterval); this.SumoLogicMessageSender.ConnectionTimeout = TimeSpan.FromMilliseconds(this.ConnectionTimeout); this.SumoLogicMessageSender.Url = string.IsNullOrEmpty(this.Url) ? null : new Uri(this.Url); // Initialize flusher if (this.flushBufferTimer != null) { this.flushBufferTimer.Dispose(); } this.flushBufferTask = new SumoLogicMessageSenderBufferFlushingTask( this.messagesQueue, this.SumoLogicMessageSender, TimeSpan.FromMilliseconds(this.MaxFlushInterval), this.MessagesPerRequest, this.SourceName, this.SourceCategory, this.SourceHost, this.LogLog); // this.flushBufferTimer = new Timer( // _ => flushBufferTask.Run(), // No task await to avoid unhandled exception // null, // TimeSpan.FromMilliseconds(0), // TimeSpan.FromMilliseconds(this.FlushingAccuracy)); this.flushBufferWorker = Task.Factory.StartNew(FlushBufferAction, CancellationToken.None, TaskCreationOptions.LongRunning | TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); }
/// <summary> /// Initialize the appender based on the options set /// </summary> /// <remarks> /// This is part of the log4net.Core.IOptionHandler delayed object activation scheme. The ActivateOptions() method must be called /// on this object after the configuration properties have been set. Until ActivateOptions() is called this object is in an undefined /// state and must not be used. If any of the configuration properties are modified then ActivateOptions() must be called again. /// </remarks> public override void ActivateOptions() { if (this.UseConsoleLog) { this.ActivateConsoleLog(); } if (this.LogLog.IsDebugEnabled) { this.LogLog.Debug("Activating options"); } // Initialize the messages queue if (this.messagesQueue == null) { this.messagesQueue = new BufferWithFifoEviction <string>(this.MaxQueueSizeBytes, new StringLengthCostAssigner(), this.LogLog); } else { this.messagesQueue.Capacity = this.MaxQueueSizeBytes; } // Initialize the sender if (this.SumoLogicMessageSender == null) { this.SumoLogicMessageSender = new SumoLogicMessageSender(this.HttpMessageHandler, this.LogLog, "sumo-log4net-buffered-sender"); } this.SumoLogicMessageSender.RetryInterval = TimeSpan.FromMilliseconds(this.RetryInterval); this.SumoLogicMessageSender.ConnectionTimeout = TimeSpan.FromMilliseconds(this.ConnectionTimeout); this.SumoLogicMessageSender.Url = string.IsNullOrEmpty(this.Url) ? null : new Uri(this.Url); // Initialize flusher if (this.flushBufferTimer != null) { this.flushBufferTimer.Dispose(); } this.flushBufferTask = new SumoLogicMessageSenderBufferFlushingTask( this.messagesQueue, this.SumoLogicMessageSender, TimeSpan.FromMilliseconds(this.MaxFlushInterval), this.MessagesPerRequest, this.SourceName, this.SourceCategory, this.SourceHost, this.LogLog); this.flushBufferTimer = new Timer( async _ => await flushBufferTask.Run().ConfigureAwait(false), null, TimeSpan.FromMilliseconds(0), TimeSpan.FromMilliseconds(this.FlushingAccuracy)); }
private void InitSender(LoggerOptions options) { DebuggingLogger?.Debug("InitSender"); sumoLogicMessageSender = new SumoLogicMessageSender(options.HttpMessageHandler, DebuggingLogger, "asp.net-core-logger") { Url = new Uri(options.Uri), ConnectionTimeout = options.ConnectionTimeout, RetryInterval = options.RetryInterval }; DebuggingLogger?.Debug("InitSender::Completed"); }
/// <summary> /// Initializes a new instance of the <see cref="BufferedSumoLogicSink"/> class. /// </summary> /// <param name="log">The log service.</param> /// <param name="httpMessageHandler">HTTP message handler.</param> /// <param name="connection">Connection configuration.</param> /// <param name="source">Event source describer.</param> /// <param name="formatter">Text formatter.</param> public BufferedSumoLogicSink( ILog log, HttpMessageHandler httpMessageHandler, SumoLogicConnection connection, SumoLogicSource source, ITextFormatter formatter) { if (connection is null) { throw new ArgumentNullException(nameof(connection)); } if (source is null) { throw new ArgumentNullException(nameof(source)); } this.formatter = formatter ?? throw new ArgumentNullException(nameof(formatter)); this.logService = log ?? new DummyLog(); this.messageSender = new SumoLogicMessageSender(httpMessageHandler, this.logService) { Url = connection.Uri, ClientName = connection.ClientName, ConnectionTimeout = connection.ConnectionTimeout, RetryInterval = connection.RetryInterval, }; this.messageQueue = new BufferWithFifoEviction <string>( connection.MaxQueueSizeBytes, new StringLengthCostAssigner(), this.logService); this.flushBufferTask = new SumoLogicMessageSenderBufferFlushingTask( this.messageQueue, this.messageSender, connection.MaxFlushInterval, connection.MessagesPerRequest, source.SourceName, source.SourceCategory, source.SourceHost, this.logService); this.flushBufferTimer = new Timer( _ => flushBufferTask.Run(), // No task await to avoid unhandled exception null, TimeSpan.FromMilliseconds(0), connection.FlushingAccuracy); }
/// <summary> /// Is called when the appender is closed. Derived classes should override this method if resources need to be released. /// </summary> /// <remarks> /// Releases any resources allocated within the appender such as file handles, network connections, etc. /// It is a programming error to append to a closed appender. /// </remarks> protected override void OnClose() { try { this.flushBufferTimer?.Dispose(); this.flushBufferTimer = null; Flush(5000); this.SumoLogicMessageSender?.Dispose(); this.SumoLogicMessageSender = null; } catch (Exception ex) { this.LogLog.Warn($"Appender closed with error. {ex.GetType()}: {ex.Message}"); } }
public static SumoLogicMessageSenderBufferFlushingTask CreateFlushBufferTask( ILog log, SumoLogicMessageSender messageSender, BufferWithEviction <string> messageQueue, SumoLogicConnection connection, SumoLogicSource source) => new SumoLogicMessageSenderBufferFlushingTask( messageQueue, messageSender, connection.MaxFlushInterval, connection.MessagesPerRequest, source.SourceName, source.SourceCategory, source.SourceHost, log);
/// <summary> /// Is called when the appender is closed. Derived classes should override this method if resources need to be released. /// </summary> /// <remarks> /// Releases any resources allocated within the appender such as file handles, network connections, etc. /// It is a programming error to append to a closed appender. /// </remarks> protected override void OnClose() { base.OnClose(); if (this.SumoLogicMessageSender != null) { this.SumoLogicMessageSender.Dispose(); this.SumoLogicMessageSender = null; } if (this.flushBufferTimer != null) { this.flushBufferTimer.Dispose(); this.flushBufferTimer = null; } }
/// <summary> /// Initializes a new instance of the <see cref="SumoLogicUnbufferedSink"/> class. /// </summary> /// <param name="log">The log service.</param> /// <param name="httpMessageHandler">HTTP message handler.</param> /// <param name="connection">Connection configuration.</param> /// <param name="source">Event source describer.</param> /// <param name="formatter">Text formatter.</param> public SumoLogicUnbufferedSink( ILog log, HttpMessageHandler httpMessageHandler, SumoLogicConnection connection, SumoLogicSource source, ITextFormatter formatter) { if (connection is null) { throw new ArgumentNullException(nameof(connection)); } _source = source ?? throw new ArgumentNullException(nameof(source)); _formatter = formatter ?? throw new ArgumentNullException(nameof(formatter)); _log = log ?? new DummyLog(); _messageSender = MessageSenderFactory.CreateMessageSender(_log, httpMessageHandler, connection); }
/// <summary> /// Initialize the appender based on the options set /// </summary> /// <remarks> /// This is part of the log4net.Core.IOptionHandler delayed object activation scheme. The ActivateOptions() method must be called /// on this object after the configuration properties have been set. Until ActivateOptions() is called this object is in an undefined /// state and must not be used. If any of the configuration properties are modified then ActivateOptions() must be called again. /// </remarks> public override void ActivateOptions() { if (this.UseConsoleLog) { this.ActivateConsoleLog(); } if (this.LogLog.IsDebugEnabled) { this.LogLog.Debug("Activating options"); } // Initialize the sender if (this.SumoLogicMessageSender == null) { this.SumoLogicMessageSender = new SumoLogicMessageSender(this.HttpMessageHandler, this.LogLog); } this.SumoLogicMessageSender.ConnectionTimeout = TimeSpan.FromMilliseconds(this.ConnectionTimeout); this.SumoLogicMessageSender.Url = new Uri(this.Url); }
/// <summary> /// Initialize the target based on the options set /// </summary> /// <remarks> /// This is part of the NLog is called when the Configurations of the LogManager are set. /// If any of the configuration properties are modified then you must set anew the Configuration of the LogManager. /// </remarks> protected override void InitializeTarget() { if (this.UseConsoleLog) { this.ActivateConsoleLog(); } if (this.LogLog.IsDebugEnabled) { this.LogLog.Debug("Activating options"); } // Initialize the sender if (this.SumoLogicMessageSender == null) { this.SumoLogicMessageSender = new SumoLogicMessageSender(this.HttpMessageHandler, this.LogLog, "sumo-nlog-sender"); } var url = _urlLayout?.Render(LogEventInfo.CreateNullEvent()) ?? string.Empty; this.SumoLogicMessageSender.ConnectionTimeout = TimeSpan.FromMilliseconds(this.ConnectionTimeout); this.SumoLogicMessageSender.Url = string.IsNullOrEmpty(url) ? null : new Uri(url); }
/// <summary> /// Initialize the target based on the options set /// </summary> /// <remarks> /// This is part of the nLog is called when the Configurations of the LogManager are set. /// If any of the configuration properties are modified then you must set anew the Configuration of the LogManager. /// </remarks> protected override void InitializeTarget() { if (this.UseConsoleLog) { this.ActivateConsoleLog(); } if (this.LogLog.IsDebugEnabled) { this.LogLog.Debug("Activating options"); } // Initialize the messages queue if (this.messagesQueue == null) { this.messagesQueue = new BufferWithFifoEviction <string>(this.MaxQueueSizeBytes, new StringLengthCostAssigner(), this.LogLog); } else { this.messagesQueue.Capacity = this.MaxQueueSizeBytes; } // Initialize the sender if (this.SumoLogicMessageSender == null) { this.SumoLogicMessageSender = new SumoLogicMessageSender(this.HttpMessageHandler, this.LogLog, "sumo-nlog-buffered-sender"); } var url = _urlLayout?.Render(LogEventInfo.CreateNullEvent()) ?? string.Empty; var sourceName = _sourceLayout?.Render(LogEventInfo.CreateNullEvent()) ?? string.Empty; var sourceCategory = _categoryLayout?.Render(LogEventInfo.CreateNullEvent()) ?? string.Empty; var sourceHost = _hostLayout?.Render(LogEventInfo.CreateNullEvent()) ?? string.Empty; this.SumoLogicMessageSender.RetryInterval = TimeSpan.FromMilliseconds(this.RetryInterval); this.SumoLogicMessageSender.ConnectionTimeout = TimeSpan.FromMilliseconds(this.ConnectionTimeout); this.SumoLogicMessageSender.Url = string.IsNullOrEmpty(url) ? null : new Uri(url); // Initialize flusher if (this.flushBufferTimer != null) { this.flushBufferTimer.Dispose(); } // Ensure any existing buffer is flushed if (this.flushBufferTask != null) { // this is NOT present in the log4net code. one-time blocking operation. try { this.flushBufferTask.FlushAndSend().GetAwaiter().GetResult(); } catch (Exception ex) { this.LogLog.Warn($"Buffered target failed to flush pending logevents. {ex.GetType()}: {ex.Message}"); } } this.flushBufferTask = new SumoLogicMessageSenderBufferFlushingTask( this.messagesQueue, this.SumoLogicMessageSender, TimeSpan.FromMilliseconds(this.MaxFlushInterval), this.MessagesPerRequest, sourceName, sourceCategory, sourceHost, this.LogLog); this.flushBufferTimer = new Timer( _ => flushBufferTask.Run(), // No task await to avoid unhandled exception null, TimeSpan.FromMilliseconds(0), TimeSpan.FromMilliseconds(this.FlushingAccuracy)); }