Skip to content

Instantly share code, notes, and snippets.

@pedroinfo
Created December 12, 2025 13:56
Show Gist options
  • Select an option

  • Save pedroinfo/aac98d5291d25c1367dddf4804c0fd1e to your computer and use it in GitHub Desktop.

Select an option

Save pedroinfo/aac98d5291d25c1367dddf4804c0fd1e to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Concurrent;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
/// <summary>
/// Thread-safe logger for web APIs with buffered writing and daily rotation.
/// The file is only opened during flush, allowing safe moves at the end of the day.
/// </summary>
public class ApiBufferedLogger : IDisposable
{
private readonly string _folder;
private readonly ConcurrentQueue<string> _queue = new();
private readonly Timer _flushTimer;
private readonly object _flushLock = new();
public ApiBufferedLogger(string folder, int flushIntervalMs = 1000)
{
_folder = folder ?? throw new ArgumentNullException(nameof(folder));
Directory.CreateDirectory(_folder);
// Timer triggers flush periodically
_flushTimer = new Timer(_ => Flush(), null, flushIntervalMs, flushIntervalMs);
}
/// <summary>
/// Adds a log message to the buffer (thread-safe)
/// </summary>
public void Log(string message)
{
if (message == null) return;
_queue.Enqueue($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} - {message}");
}
/// <summary>
/// Flushes buffered logs to disk (thread-safe)
/// </summary>
public void Flush()
{
// Ensure only one flush at a time
lock (_flushLock)
{
if (_queue.IsEmpty) return;
var sb = new StringBuilder();
while (_queue.TryDequeue(out var line))
{
sb.AppendLine(line);
}
string filePath = Path.Combine(_folder, $"log-{DateTime.Now:yyyy-MM-dd}.txt");
File.AppendAllText(filePath, sb.ToString(), Encoding.UTF8);
}
}
/// <summary>
/// Dispose flush timer and flush remaining logs
/// </summary>
public void Dispose()
{
_flushTimer?.Dispose();
Flush();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment