/logger.cs Secret
Created
May 11, 2017 14:32
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading; | |
using System.Threading.Tasks; | |
using WriteToFileMultiThreaded; | |
namespace WriteToFileMultiThreaded | |
{ | |
using System; | |
using System.Collections.Generic; | |
using System.Configuration; | |
using System.IO; | |
/// <summary> | |
/// A Logging class implementing the Singleton pattern and an internal Queue to be flushed perdiodically | |
/// </summary> | |
public class LogWriter | |
{ | |
private static LogWriter instance; | |
private static Queue<Log> logQueue; | |
private static string logDir = ""; | |
private static string logFile = "WorkflowLog.txt"; | |
private static int maxLogAge = int.Parse("5184000"); | |
private static int queueSize = int.Parse("20"); | |
private static DateTime LastFlushed = DateTime.Now; | |
/// <summary> | |
/// Private constructor to prevent instance creation | |
/// </summary> | |
private LogWriter() { } | |
/// <summary> | |
/// An LogWriter instance that exposes a single instance | |
/// </summary> | |
public static LogWriter Instance | |
{ | |
get | |
{ | |
// If the instance is null then create one and init the Queue | |
if (instance == null) | |
{ | |
instance = new LogWriter(); | |
logQueue = new Queue<Log>(); | |
} | |
return instance; | |
} | |
} | |
/// <summary> | |
/// The single instance method that writes to the log file | |
/// </summary> | |
/// <param name="message">The message to write to the log</param> | |
public void WriteToLog(string message) | |
{ | |
// Lock the queue while writing to prevent contention for the log file | |
lock (logQueue) | |
{ | |
// Create the entry and push to the Queue | |
Log logEntry = new Log(message); | |
logQueue.Enqueue(logEntry); | |
// If we have reached the Queue Size then flush the Queue | |
if (logQueue.Count >= queueSize || DoPeriodicFlush()) | |
{ | |
FlushLog(); | |
} | |
} | |
} | |
private bool DoPeriodicFlush() | |
{ | |
TimeSpan logAge = DateTime.Now - LastFlushed; | |
if (logAge.TotalSeconds >= maxLogAge) | |
{ | |
LastFlushed = DateTime.Now; | |
return true; | |
} | |
else | |
{ | |
return false; | |
} | |
} | |
/// <summary> | |
/// Flushes the Queue to the physical log file | |
/// </summary> | |
private void FlushLog() | |
{ | |
while (logQueue.Count > 0) | |
{ | |
Log entry = logQueue.Dequeue(); | |
string logPath = logDir + entry.LogDate + "_" + logFile; | |
// This could be optimised to prevent opening and closing the file for each write | |
using (FileStream fs = File.Open(logPath, FileMode.Append, FileAccess.Write)) | |
{ | |
using (StreamWriter log = new StreamWriter(fs)) | |
{ | |
log.WriteLine(string.Format("{0}\t{1}", entry.LogTime, entry.Message)); | |
} | |
} | |
} | |
} | |
} | |
/// <summary> | |
/// A Log class to store the message and the Date and Time the log entry was created | |
/// </summary> | |
public class Log | |
{ | |
public string Message { get; set; } | |
public string LogTime { get; set; } | |
public string LogDate { get; set; } | |
public Log(string message) | |
{ | |
Message = message; | |
LogDate = DateTime.Now.ToString("yyyy-MM-dd"); | |
LogTime = DateTime.Now.ToString("hh:mm:ss.fff tt"); | |
} | |
} | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
for (int i = 0; i < 20; i++) | |
{ | |
string threadName = "Thread " + Convert.ToString(i + 1); | |
Thread t = new Thread(() => ThreadData(threadName)); | |
t.Start(); | |
} | |
} | |
static void ThreadData(string threadName) | |
{ | |
LogWriter writer = LogWriter.Instance; | |
for (int i = 0; i < 1000; i++) | |
{ | |
writer.WriteToLog(threadName + " Writing" + Environment.NewLine); | |
//System.IO.File.AppendAllText("test.txt", "Thread One Writing Line " + i + Environment.NewLine); | |
} | |
} | |
static void ThreadTwo() | |
{ | |
LogWriter writer = LogWriter.Instance; | |
for (int i = 0; i < 1000; i++) | |
{ | |
writer.WriteToLog("Thread Two Writing Line " + i + Environment.NewLine); | |
//System.IO.File.AppendAllText("test.txt", "Thread Two Writing Line " + i); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment