using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Threading;
using System.IO;
namespace RaptorDB
{
internal interface ILog
{
void Debug(object msg, params object[] objs);
void Error(object msg, params object[] objs);
void Info(object msg, params object[] objs);
void Warn(object msg, params object[] objs);
void Fatal(object msg, params object[] objs);
}
internal class FileLogger
{
public static readonly FileLogger Instance = new FileLogger();
private FileLogger()
{
}
private Queue _que = new Queue();
private StreamWriter _output;
private string _filename;
private int _sizeLimit = 0;
private long _lastSize = 0;
private DateTime _lastFileDate;
private bool _showMethodName = false;
private string _FilePath = "";
System.Timers.Timer _saveTimer;
public bool ShowMethodNames
{
get { return _showMethodName; }
}
public void Init(string filename, int sizelimitKB, bool showmethodnames)
{
_que = new Queue();
_showMethodName = showmethodnames;
_sizeLimit = sizelimitKB;
_filename = filename;
// handle folder names as well -> create dir etc.
_FilePath = Path.GetDirectoryName(filename);
if (_FilePath != "")
{
_FilePath = Directory.CreateDirectory(_FilePath).FullName;
if (_FilePath.EndsWith(Path.DirectorySeparatorChar.ToString()) == false)
_FilePath += Path.DirectorySeparatorChar.ToString();
}
_output = new StreamWriter(filename, true);
FileInfo fi = new FileInfo(filename);
_lastSize = fi.Length;
_lastFileDate = fi.LastWriteTime;
_saveTimer = new System.Timers.Timer(500);
_saveTimer.Elapsed += new System.Timers.ElapsedEventHandler(_saveTimer_Elapsed);
_saveTimer.Enabled = true;
_saveTimer.AutoReset = true;
}
void _saveTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
WriteData();
}
public void ShutDown()
{
WriteData();
if (_output != null)
{
_output.Flush();
_output.Close();
_output = null;
}
}
//object _writelock = new object();
private void WriteData()
{
if (_output == null)
return;
lock (_que)
{
while (_que.Count > 0)
{
object o = _que.Dequeue();
if (_output != null && o != null)
{
if (_sizeLimit > 0)
{
// implement size limited logs
// implement rolling logs
#region [ rolling size limit ]
_lastSize += ("" + o).Length;
if (_lastSize > _sizeLimit * 1000)
{
_output.Flush();
_output.Close();
int count = 1;
while (File.Exists(_FilePath + Path.GetFileNameWithoutExtension(_filename) + "." + count.ToString("0000")))
count++;
File.Move(_filename,
_FilePath +
Path.GetFileNameWithoutExtension(_filename) +
"." + count.ToString("0000"));
_output = new StreamWriter(_filename, true);
_lastSize = 0;
}
#endregion
}
if (DateTime.Now.Subtract(_lastFileDate).Days > 0)
{
// implement date logs
#region [ rolling dates ]
_output.Flush();
_output.Close();
int count = 1;
while (File.Exists(_FilePath + Path.GetFileNameWithoutExtension(_filename) + "." + count.ToString("0000")))
{
File.Move(_FilePath + Path.GetFileNameWithoutExtension(_filename) + "." + count.ToString("0000"),
_FilePath +
Path.GetFileNameWithoutExtension(_filename) +
"." + count.ToString("0000") +
"." + _lastFileDate.ToString("yyyy-MM-dd"));
count++;
}
File.Move(_filename,
_FilePath +
Path.GetFileNameWithoutExtension(_filename) +
"." + count.ToString("0000") +
"." + _lastFileDate.ToString("yyyy-MM-dd"));
_output = new StreamWriter(_filename, true);
_lastFileDate = DateTime.Now;
_lastSize = 0;
#endregion
}
_output.Write(o);
}
}
if (_output != null)
_output.Flush();
}
}
private string FormatLog(string log, string type, string meth, string msg, object[] objs)
{
StringBuilder sb = new StringBuilder();
sb.Append(DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"));
sb.Append("|");
sb.Append(log);
sb.Append("|");
sb.Append(Thread.CurrentThread.ManagedThreadId.ToString());
sb.Append("|");
sb.Append(type);
sb.Append("|");
sb.Append(meth);
sb.Append("| ");
sb.AppendLine(msg);
if (objs != null)
foreach (object o in objs)
sb.AppendLine("" + o);
return sb.ToString();
}
public void Log(string logtype, string type, string meth, string msg, params object[] objs)
{
lock (_que)
_que.Enqueue(FormatLog(logtype, type, meth, msg, objs));
}
}
internal class logger : ILog
{
public logger(Type type)
{
typename = type.Namespace + "." + type.Name;
}
private string typename = "";
private void log(string logtype, string msg, params object[] objs)
{
string meth = "";
if (FileLogger.Instance.ShowMethodNames)
{
System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace(2);
System.Diagnostics.StackFrame sf = st.GetFrame(0);
meth = sf.GetMethod().Name;
}
FileLogger.Instance.Log(logtype, typename, meth, msg, objs);
}
#region ILog Members
public void Debug(object msg, params object[] objs)
{
log("DEBUG", "" + msg, objs);
}
public void Error(object msg, params object[] objs)
{
log("ERROR", "" + msg, objs);
}
public void Info(object msg, params object[] objs)
{
log("INFO", "" + msg, objs);
}
public void Warn(object msg, params object[] objs)
{
log("WARN", "" + msg, objs);
}
public void Fatal(object msg, params object[] objs)
{
log("FATAL", "" + msg, objs);
}
#endregion
}
internal static class LogManager
{
public static ILog GetLogger(Type obj)
{
return new logger(obj);
}
public static void Configure(string filename, int sizelimitKB, bool showmethodnames)
{
FileLogger.Instance.Init(filename, sizelimitKB, showmethodnames);
}
public static void Shutdown()
{
FileLogger.Instance.ShutDown();
}
}
}