void AppendLine(StreamBufferWriter writer)
 {
     if (writer.TryGetForNewLine(out var buffer, out var index))
     {
         if (crlf)
         {
             buffer[index]     = newLine1;
             buffer[index + 1] = newLine2;
             writer.Advance(2);
         }
         else
         {
             buffer[index] = newLine1;
             writer.Advance(1);
         }
     }
     else
     {
         var span = writer.GetSpan(newLine.Length);
         newLine.CopyTo(span);
     }
 }
        async Task WriteLoop()
        {
            var writer = new StreamBufferWriter(stream);
            var reader = channel.Reader;

            try
            {
                while (await reader.WaitToReadAsync().ConfigureAwait(false))
                {
                    LogInfo info = default;
                    try
                    {
                        while (reader.TryRead(out var value))
                        {
                            info = value.LogInfo;

                            if (options.EnableStructuredLogging)
                            {
                                var jsonWriter = options.GetThreadStaticUtf8JsonWriter(writer);
                                try
                                {
                                    jsonWriter.WriteStartObject();

                                    value.FormatUtf8(writer, options, jsonWriter);
                                    value.Return();

                                    jsonWriter.WriteEndObject();
                                    jsonWriter.Flush();
                                }
                                finally
                                {
                                    jsonWriter.Reset();
                                }
                            }
                            else
                            {
                                value.FormatUtf8(writer, options, null);
                                value.Return();
                            }

                            AppendLine(writer);
                        }
                        info = default;
                        writer.Flush(); // flush before wait.
                    }
                    catch (Exception ex)
                    {
                        try
                        {
                            if (options.InternalErrorLogger != null)
                            {
                                options.InternalErrorLogger(info, ex);
                            }
                            else
                            {
                                Console.WriteLine(ex);
                            }
                        }
                        catch { }
                    }
                }
            }
            catch (OperationCanceledException)
            {
            }
            finally
            {
                try
                {
                    writer.Flush();
                }
                catch { }
            }
        }
        async Task WriteLoop()
        {
            var writer = new StreamBufferWriter(stream);
            var reader = channel.Reader;
            var sw     = Stopwatch.StartNew();

            try
            {
                while (await reader.WaitToReadAsync().ConfigureAwait(false))
                {
                    LogInfo info = default;
                    try
                    {
                        while (reader.TryRead(out var value))
                        {
                            info = value.LogInfo;

                            if (options.EnableStructuredLogging)
                            {
                                var jsonWriter = options.GetThreadStaticUtf8JsonWriter(writer);
                                try
                                {
                                    jsonWriter.WriteStartObject();

                                    value.FormatUtf8(writer, options, jsonWriter);
                                    value.Return();

                                    jsonWriter.WriteEndObject();
                                    jsonWriter.Flush();
                                }
                                finally
                                {
                                    jsonWriter.Reset();
                                }
                            }
                            else
                            {
                                value.FormatUtf8(writer, options, null);
                                value.Return();
                            }

                            AppendLine(writer);
                        }
                        info = default;

                        if (options.FlushRate != null && !cancellationTokenSource.IsCancellationRequested)
                        {
                            sw.Stop();
                            var sleepTime = options.FlushRate.Value - sw.Elapsed;
                            if (sleepTime > TimeSpan.Zero)
                            {
                                try
                                {
                                    await Task.Delay(sleepTime, cancellationTokenSource.Token).ConfigureAwait(false);
                                }
                                catch (OperationCanceledException)
                                {
                                }
                            }
                        }
                        writer.Flush(); // flush before wait.

                        sw.Reset();
                        sw.Start();
                    }
                    catch (Exception ex)
                    {
                        try
                        {
                            if (options.InternalErrorLogger != null)
                            {
                                options.InternalErrorLogger(info, ex);
                            }
                            else
                            {
                                Console.WriteLine(ex);
                            }
                        }
                        catch { }
                    }
                }
            }
            catch (OperationCanceledException)
            {
            }
            finally
            {
                try
                {
                    writer.Flush();
                }
                catch { }
            }
        }