private bool DoWithReconnect(ref LogEntriesConnection connection, byte[] token, string entry, out Exception error)
        {
            var success = false;

            error = null;
            try
            {
                if (!connection.IsIdleForTooLong)
                {
                    LogEntryWriter.Write(token, entry, connection);
                    success = true;
                }
            }
            catch (Exception ex)
            {
                error = ex;
            }

            if (!success)
            {
                Reconnect(ref connection);
            }

            return(success);
        }
        internal static void Write(byte[] token, string entry, LogEntriesConnection connection)
        {
            Array.Copy(token, 0, _buffer, 0, token.Length);

            var buffered = token.Length;
            var readed   = 0;

            while (readed != entry.Length)
            {
                ReplaceAndBufferChars(entry, readed, _charBuffer, out int used, out int formatted);
                readed += used;

                var completed      = false;
                var totalCharsUsed = 0;
                var bytesUsed      = 0;

                while (!completed)
                {
                    _encoding.Convert(
                        chars: _charBuffer,
                        charIndex: totalCharsUsed,
                        charCount: formatted - totalCharsUsed,
                        bytes: _buffer,
                        byteIndex: buffered,
                        byteCount: _buffer.Length - buffered,
                        flush: formatted == totalCharsUsed,
                        charsUsed: out int charsUsed,
                        bytesUsed: out bytesUsed,
                        completed: out completed);

                    buffered       += bytesUsed;
                    totalCharsUsed += charsUsed;

                    if (completed && readed == entry.Length)
                    {
                        if (buffered < _buffer.Length)
                        {
                            _buffer[buffered++] = _newLineByte;
                        }
                        else // data fits the end of the buffer so in order to
                        {    // send the end line delimitator \n it is needed to
                             // clean the buffer. This may occur very little times.
                            connection.Send(_buffer, buffered);
                            _buffer[0] = _newLineByte;
                            buffered   = 1;
                        }
                    }

                    connection.Send(_buffer, buffered);
                    buffered = 0;
                }
            }
        }
 private void Reconnect(ref LogEntriesConnection connection)
 {
     connection?.Dispose();
     connection = null;
     while (connection == null && _closed == 0)
     {
         try
         {
             connection = new LogEntriesConnection();
         }
         catch (Exception ex) // Unable to connect to Logentries.
         {
             Trace.WriteLine($"Connection failed: {ex.Message}.");
             Thread.Sleep(LogEntriesSettings.PauseBetweenReconnections);
         }
     }
 }
        private void MasterConsumeAndSendEvents()
        {
            LogEntriesConnection connection = null;

            try
            {
                Reconnect(ref connection);
                foreach (var datas in _queue.GetConsumingEnumerable())
                {
                    DoWithRetry(ref connection, datas.Item1, datas.Item2);
                    UpscaleIfNeeded();
                }
            }
            finally
            {
                connection?.Dispose();
            }
        }
        private void DoWithRetry(ref LogEntriesConnection connection, byte[] token, string entry)
        {
            var retry = 0;
            var error = (Exception)null;

            while (!DoWithReconnect(ref connection, token, entry, out error))
            {
                retry++;
                if (retry >= LogEntriesSettings.MaxRetries)
                {
                    // At least try to signal that the component was unable to save
                    // the entry. In case it is because this component fault, the error
                    // would be recorded somewhere.
                    error = error ?? new Exception("No error provided");
                    DoWithReconnect(ref connection, token, $"[NLog.Contrib.Targets.LogEntries] Entry Dropped because: ({error.GetType().Name}): {error.Message} \n {error.StackTrace}", out error);
                    return;
                }
            }
        }
        private void ConsumeAndSendEvents()
        {
            LogEntriesConnection connection = null;

            try
            {
                Reconnect(ref connection);
                foreach (var datas in _queue.GetConsumingEnumerable())
                {
                    DoWithRetry(ref connection, datas.Item1, datas.Item2);
                    Trace.Write(".");
                    if (!ContinueConsuming())
                    {
                        Interlocked.Decrement(ref _additionalThreadCount);
                        Trace.WriteLine($"Removed thread. Current count {_additionalThreadCount}. State {(_closed== 1?"closed":"running")}. Queue {_queue.Count}.");
                        return;
                    }
                }
            }
            finally
            {
                connection?.Dispose();
            }
        }