#region LogThis v1.3.1
/*
* 28th July 2005
* 1.3.1 - By Ashutosh Nilkanth (www.nilkanth.com)
* - Added file rollover feature (new method RolloevrLogFile)
* - Fixed log filename bug (had an extra underscore, when period is unspecified)
*
*
* 6/15/2003
* This software is provided 'as-is', without any express or implied warranty.
* In no event will the author(s) be held liable for any damages arising from
* the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not
* be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
*
* Web: http://sourceforge.net/projects/logthis/
*
* Copyright © 2003 Dave Lewis [logthis@tpsd.com]
*
*/
#endregion
using System;
using System.IO;
using System.Collections;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Globalization;
namespace LogThis
{
///
/// Notes to any developer who uses this class:
/// The elogprofile enum is the only part of this
/// class that will require modification for your
/// particular applications use.
/// The LogThis logger class supports log profiles
/// allowing multiple logging strategies when desired.
/// One example:
/// A primary log file for customer consumption and
/// then a second log file for when you need to do
/// debugging. Some developers prefer to have debugging
/// information go to a second file for any number of
/// reasons. In that case you would add some other enum
/// value to the elogprofile enum. You would have any
/// normal logging use the primary log profile and any debugging
/// logging use the other profile.
/// This is just a simple example. You can have any number of
/// logging profiles based on your requirements just by adding
/// them. See the tutorial on using multiple profiles for more
/// information.
///
public enum elogprofile
{
primary = 1
,system
}
public enum eloglevel
{
error=1
,warn
,info
,verbose
}
public enum elogwhere
{
eventlog
,file
,eventlog_and_file
}
public enum elogprefix
{
none
,dt
,loglevel
,dt_loglevel
}
public enum elogheaderlevel
{
Level_1
,Level_2
,Level_3
}
public enum elogperiod
{
none
,day
,week
,month
}
public enum elognameformat
{
name_date
,date_name
}
public enum elogquotaformat
{
no_restriction
,kbytes
,rows
}
public class Log
{
/*
* Some methods are overloaded, allowing the caller to specify the log profile.
* None of the properties support the caller specifying the log profile.
* In the case of properties, it is necessary to set Log.Profile to a valid
* log profile and then address the properties.
* Properties:
* LogLevel:
* LogWhere:
* LogName:
* Profile: This property contains the currently chosen log profile.
*
* DefaultToPrimaryProfile:
* True: When true and when the log profile isn't explicitly specified
* then the primary log profile will be implied.
* Note: The value of True is only supported when just a single
* log profile exists. Creating additional log profiles will
* automatically set this to false. A value of True makes it
* simplier to work with when using a single log profile because
* all methods and properties default to the primary profile.
* False: The profile to be used will be the most recently
* chosen one that was set using Log.Profile = elogprofile.YourProfile
*
*/
private static ListDictionary m_Logs;
private static LogMethods m_LogMethods;
private static elogprofile m_logprofile;
private static bool m_DefaultToPrimaryProfile = true;
public static void LogThis(string logtext,eloglevel loglevel)
{
if (m_DefaultToPrimaryProfile)
{
LogThis(elogprofile.primary,logtext,loglevel);
}
else //log to current profile
{
m_LogMethods.LogThis(logtext,loglevel);
}
}
public static void LogThis(elogprofile logprofile, string logtext,eloglevel loglevel)
{
((LogMethods)m_Logs[Convert.ToString(logprofile)]).LogThis(logtext,loglevel);
}
public static void LogThis(elogprofile logprofile, string logtext,eloglevel loglevel, elogprefix logprefix)
{
((LogMethods)m_Logs[Convert.ToString(logprofile)]).LogThis(logtext,loglevel,logprefix);
}
public static void LogThis(string logtext,eloglevel loglevel, elogprefix logprefix)
{
if (m_DefaultToPrimaryProfile)
{
LogThis(elogprofile.primary,logtext,loglevel,logprefix);
}
else //log to current profile
{
m_LogMethods.LogThis(logtext,loglevel, logprefix);
}
}
public static elogprofile Profile
{
get
{
return m_logprofile;
}
set
{
m_logprofile = (elogprofile)value;
m_LogMethods = (LogMethods)m_Logs[Convert.ToString(m_logprofile)];
}
}
public static bool DefaultToPrimaryProfile
{
get
{
return m_DefaultToPrimaryProfile;
}
}
public static eloglevel LogLevel
{
get
{
if (m_DefaultToPrimaryProfile)
{
return ((LogMethods)m_Logs[Convert.ToString(elogprofile.primary)]).LogLevel;
}
else //default to current
{
return m_LogMethods.LogLevel;
}
}
set
{
if (m_DefaultToPrimaryProfile)
{
((LogMethods)m_Logs[Convert.ToString(elogprofile.primary)]).LogLevel = (eloglevel)value;
}
else //default to current
{
m_LogMethods.LogLevel = (eloglevel)value;
}
}
}
public static elogwhere LogWhere
{
get
{
if (m_DefaultToPrimaryProfile)
{
return ((LogMethods)m_Logs[Convert.ToString(elogprofile.primary)]).LogWhere;
}
else //default to current
{
return m_LogMethods.LogWhere;
}
}
set
{
if (m_DefaultToPrimaryProfile)
{
((LogMethods)m_Logs[Convert.ToString(elogprofile.primary)]).LogWhere = (elogwhere)value;
}
else //default to current
{
m_LogMethods.LogWhere = value;
}
}
}
public static string LogName
{
get
{
if (m_DefaultToPrimaryProfile)
{
return ((LogMethods)m_Logs[Convert.ToString(elogprofile.primary)]).LogName;
}
else //default to current
{
return m_LogMethods.LogName;
}
}
set
{
if (m_DefaultToPrimaryProfile)
{
((LogMethods)m_Logs[Convert.ToString(elogprofile.primary)]).LogName = value;
}
else //default to current
{
m_LogMethods.LogName = value;
}
}
}
public static string LogPath
{
get
{
if (m_DefaultToPrimaryProfile)
{
return ((LogMethods)m_Logs[Convert.ToString(elogprofile.primary)]).LogPath;
}
else //default to current
{
return m_LogMethods.LogPath;
}
}
set
{
if (m_DefaultToPrimaryProfile)
{
((LogMethods)m_Logs[Convert.ToString(elogprofile.primary)]).LogPath = value;
}
else //default to current
{
m_LogMethods.LogPath = value;
}
}
}
public static string ProcessName
{
get
{
if (m_DefaultToPrimaryProfile)
{
return ((LogMethods)m_Logs[Convert.ToString(elogprofile.primary)]).ProcessName;
}
else //default to current
{
return m_LogMethods.ProcessName;
}
}
set
{
if (m_DefaultToPrimaryProfile)
{
((LogMethods)m_Logs[Convert.ToString(elogprofile.primary)]).ProcessName = value;
}
else //default to current
{
m_LogMethods.ProcessName = value;
}
}
}
public static elogperiod LogPeriod
{
get
{
if (m_DefaultToPrimaryProfile)
{
return ((LogMethods)m_Logs[Convert.ToString(elogprofile.primary)]).LogPeriod;
}
else //default to current
{
return m_LogMethods.LogPeriod;
}
}
set
{
if (m_DefaultToPrimaryProfile)
{
((LogMethods)m_Logs[Convert.ToString(elogprofile.primary)]).LogPeriod = (elogperiod)value;
}
else //default to current
{
m_LogMethods.LogPeriod = value;
}
}
}
public static elognameformat LogNameFormat
{
get
{
if (m_DefaultToPrimaryProfile)
{
return ((LogMethods)m_Logs[Convert.ToString(elogprofile.primary)]).LogNameFormat;
}
else //default to current
{
return m_LogMethods.LogNameFormat;
}
}
set
{
if (m_DefaultToPrimaryProfile)
{
((LogMethods)m_Logs[Convert.ToString(elogprofile.primary)]).LogNameFormat = (elognameformat)value;
}
else //default to current
{
m_LogMethods.LogNameFormat = (elognameformat)value;
}
}
}
public static elogquotaformat LogQuotaFormat
{
get
{
if (m_DefaultToPrimaryProfile)
{
return ((LogMethods)m_Logs[Convert.ToString(elogprofile.primary)]).LogQuotaFormat;
}
else //default to current
{
return m_LogMethods.LogQuotaFormat;
}
}
set
{
if (m_DefaultToPrimaryProfile)
{
((LogMethods)m_Logs[Convert.ToString(elogprofile.primary)]).LogQuotaFormat = (elogquotaformat)value;
}
else //default to current
{
m_LogMethods.LogQuotaFormat = (elogquotaformat)value;
}
}
}
public static elogprefix LogPrefix
{
get
{
if (m_DefaultToPrimaryProfile)
{
return ((LogMethods)m_Logs[Convert.ToString(elogprofile.primary)]).LogPrefix;
}
else //default to current
{
return m_LogMethods.LogPrefix;
}
}
set
{
if (m_DefaultToPrimaryProfile)
{
((LogMethods)m_Logs[Convert.ToString(elogprofile.primary)]).LogPrefix = (elogprefix)value;
}
else //default to current
{
m_LogMethods.LogPrefix = (elogprefix)value;
}
}
}
public static int LogSizeMax
{
get
{
if (m_DefaultToPrimaryProfile)
{
return ((LogMethods)m_Logs[Convert.ToString(elogprofile.primary)]).LogSizeMax;
}
else //default to current
{
return m_LogMethods.LogSizeMax;
}
}
set
{
if (m_DefaultToPrimaryProfile)
{
((LogMethods)m_Logs[Convert.ToString(elogprofile.primary)]).LogSizeMax = value;
}
else //default to current
{
m_LogMethods.LogSizeMax = value;
}
}
}
public static void SetLogPath()
{
if (m_DefaultToPrimaryProfile)
{
SetLogPath(elogprofile.primary);
}
else //default to current
{
m_LogMethods.SetLogPath();
}
}
public static void SetLogPath(elogprofile logprofile)
{
((LogMethods)m_Logs[Convert.ToString(logprofile)]).SetLogPath();
}
public static void LogReset()
{
if (m_DefaultToPrimaryProfile)
{
LogReset(elogprofile.primary);
}
else //default to current
{
m_LogMethods.LogReset();
}
}
public static void LogReset(elogprofile logprofile)
{
((LogMethods)m_Logs[Convert.ToString(logprofile)]).LogReset();
}
public static void LogHeader(string sText, elogheaderlevel logheaderlevel)
{
if (m_DefaultToPrimaryProfile)
{
LogHeader(elogprofile.primary, sText, logheaderlevel);
}
else
{
LogHeader(m_logprofile, sText, logheaderlevel);
}
}
public static void LogHeader(elogprofile logprofile, string sText,elogheaderlevel logheaderlevel)
{
string sHeader = "";
DateTime dt = DateTime.Now;
switch(logheaderlevel)
{
case elogheaderlevel.Level_1:
sHeader = "======(" + System.AppDomain.CurrentDomain.FriendlyName + ") ==== " + sText + "============ Date:" + dt.ToString("yyyyMMdd") + " Time:" + dt.ToString("hh:mm:ss") ;
break;
case elogheaderlevel.Level_2:
sHeader = "------" + sText + " ============ Time:" + dt.ToString("hh:mm:ss") ;
break;
case elogheaderlevel.Level_3:
sHeader = "---" + sText + " --- Time:" + dt.ToString("hh:mm:ss") ;
break;
}
LogThis(sHeader, eloglevel.info, elogprefix.none);
}
public static LogMethods GetProfile(elogprofile logprofile)
{
return (LogMethods) m_Logs[Convert.ToString(logprofile)];
}
public void Init()
{
Init(elogprofile.primary);
}
public void Init(elogprofile logprofile)
{
if (m_Logs == null)
{
m_Logs = new ListDictionary();
}
if (m_Logs.Contains(Convert.ToString(logprofile))) { return; }
m_LogMethods = new LogMethods();
m_Logs.Add(Convert.ToString(logprofile),m_LogMethods);
Profile = logprofile;
if (m_Logs.Count > 1 | logprofile != elogprofile.primary)
{
//Once there are more than just the primary log profile then the properties
//can no longer default to just the primary profile.
m_DefaultToPrimaryProfile = false;
}
}
}
public class LogMethods
{
private eloglevel m_loglevel = eloglevel.error;
private elogwhere m_logwhere = elogwhere.eventlog;
private elogperiod m_logperiod = elogperiod.none;
private elognameformat m_lognameformat = elognameformat.name_date;
private string m_ProcessName=System.AppDomain.CurrentDomain.FriendlyName;
private string m_logfilename=System.AppDomain.CurrentDomain.FriendlyName;
private elogquotaformat m_logquotaformat = elogquotaformat.no_restriction;
private int m_logsizemax = 0;
private elogprefix m_logprefix = elogprefix.dt_loglevel;
private string m_logfilepath = "";
private string m_logfiletype = ".log";
public eloglevel LogLevel
{
get
{
return m_loglevel;
}
set
{
m_loglevel = (eloglevel)value;
}
}
public elogwhere LogWhere
{
get
{
return m_logwhere;
}
set
{
m_logwhere = value;
}
}
public elognameformat LogNameFormat
{
get
{
return m_lognameformat;
}
set
{
m_lognameformat = value;
}
}
public elogprefix LogPrefix
{
get
{
return m_logprefix;
}
set
{
m_logprefix = value;
}
}
public string LogName
{
get
{
return m_logfilename;
}
set
{
m_logfilename = value;
}
}
public string LogPath
{
get
{
return m_logfilepath;
}
set
{
m_logfilepath = value;
}
}
public string ProcessName
{
get
{
return m_ProcessName;
}
set
{
m_ProcessName = value;
}
}
public elogperiod LogPeriod
{
get
{
return m_logperiod;
}
set
{
m_logperiod = (elogperiod)value;
}
}
public elogquotaformat LogQuotaFormat
{
get
{
return m_logquotaformat;
}
set
{
m_logquotaformat = (elogquotaformat)value;
}
}
public int LogSizeMax
{
get
{
return m_logsizemax;
}
set
{
m_logsizemax = value;
}
}
public void LogReset()
{
if (!(LogName == null))
{
File.Delete(LogName);
}
}
private void AppendToFile(string sPath, string sText)
{
StreamWriter SW;
SW=File.AppendText(sPath);
SW.WriteLine(sText);
SW.Close();
}
private void LogEvent(string sText, eloglevel loglevel)
{
EventLogEntryType EventType;
switch(loglevel)
{
case eloglevel.error:
EventType = EventLogEntryType.Error;
break;
case eloglevel.warn:
EventType = EventLogEntryType.Warning;
break;
case eloglevel.info:
EventType = EventLogEntryType.Information;
break;
default:
EventType = EventLogEntryType.Information;
break;
}
//open and write to event log.
System.Diagnostics.EventLog oEV = new System.Diagnostics.EventLog();
oEV.Source = m_ProcessName;
oEV.WriteEntry (sText, EventType);
oEV.Close();
}
public void TruncateLogFile()
{
TruncateLogFile(LogPath);
}
public void TruncateLogFile(string sLogPath)
{
if (m_logquotaformat == elogquotaformat.no_restriction) { return; }
long nfileSize = 0;
long i=0;
long j=0;
if (!File.Exists(sLogPath)) { return;}
switch (m_logquotaformat)
{
case elogquotaformat.kbytes:
try
{
FileInfo info = new FileInfo(sLogPath);
nfileSize = info.Length;
}
catch (Exception x)
{
System.Console.WriteLine("Error:" + x.Message);
nfileSize = 0;
}
if (nfileSize < (m_logsizemax*1024))
{ return; }
break;
case elogquotaformat.rows:
using (StreamReader sr = new StreamReader(sLogPath))
{
String line;
while ((line = sr.ReadLine()) != null)
{
i++;
}
if (i < m_logsizemax) {return;}
}
break;
}
File.Delete(sLogPath + ".new");
StreamWriter SW;
SW=File.AppendText(sLogPath + ".new");
using (StreamReader sr = new StreamReader(sLogPath))
{
switch (m_logquotaformat)
{
case elogquotaformat.kbytes:
char[] c = null;
long bufsize = 1024; //should match streams natural buffer size.
long kb = 1024;
j = (long)((m_logsizemax*kb) * .9);
while (sr.Peek() >= 0)
{
c = new char[bufsize];
sr.Read(c, 0, c.Length);
i++;
if ((i*bufsize) > j)
{
for (i = 0;i j) { break;}
}
break;
}
}
SW.Close();
File.Delete(sLogPath);
File.Move(sLogPath + ".new",sLogPath);
}
// New method to rollover log files (eg: log.1.txt, log.2.txt, log.3.txt ...)
public void RolloverLogFile(string sLogPath)
{
if (m_logquotaformat == elogquotaformat.no_restriction) { return; }
long nfileSize = 0;
long i=0;
long j=0;
if (!File.Exists(sLogPath)) { return;}
switch (m_logquotaformat)
{
case elogquotaformat.kbytes:
try
{
FileInfo info = new FileInfo(sLogPath);
nfileSize = info.Length;
}
catch (Exception x)
{
System.Console.WriteLine("Error:" + x.Message);
nfileSize = 0;
}
if (nfileSize < (m_logsizemax*1024))
{ return; }
break;
case elogquotaformat.rows:
using (StreamReader sr = new StreamReader(sLogPath))
{
String line;
while ((line = sr.ReadLine()) != null)
{
i++;
}
if (i < m_logsizemax) {return;}
}
break;
}
if (File.Exists(sLogPath))
{
DateTime dt = DateTime.Now;
string filesuffix = dt.ToString("yyyyMMdd") + "_" + dt.ToString("hh-mm-ss");
File.Copy(sLogPath, sLogPath.Replace(m_logfiletype, "." + filesuffix + m_logfiletype), true);
File.Delete(sLogPath);
}
}
private string GetWeek()
{
//I got this code right out of MSDN and only decided to change the
//week to start on Monday instead of Sunday for logging.
//The first and last week of the year will likely be less than 7 days.
// Gets the Calendar instance associated with a CultureInfo.
CultureInfo myCI = new CultureInfo("en-US");
Calendar myCal = myCI.Calendar;
// Gets the DTFI properties required by GetWeekOfYear.
CalendarWeekRule myCWR = myCI.DateTimeFormat.CalendarWeekRule;
//DayOfWeek myFirstDOW = myCI.DateTimeFormat.FirstDayOfWeek;
DayOfWeek myFirstDOW = DayOfWeek.Monday;
// Displays the total number of weeks in the current year.
DateTime LastDay = new System.DateTime( DateTime.Now.Year, 12, 31 );
//Console.WriteLine( "There are {0} weeks in the current year ({1}).", myCal.GetWeekOfYear( LastDay, myCWR, myFirstDOW ), LastDay.Year );
return myCal.GetWeekOfYear( DateTime.Now, myCWR, myFirstDOW ).ToString();
}
public void SetLogPath()
{
string sPeriod = "";
string sLogName = m_logfilename;
if (!(LogPeriod == elogperiod.none))
{
DateTime dt = DateTime.Now;
switch (m_logperiod)
{
case elogperiod.day:
sPeriod = dt.ToString("yyyyMMdd");
break;
case elogperiod.week:
string week = GetWeek();
sPeriod = dt.ToString("yyyyweek" + week);
break;
case elogperiod.month:
sPeriod = dt.ToString("yyyyMM");
break;
}
switch (m_lognameformat)
{
case elognameformat.date_name:
sLogName = sPeriod + "_" + m_logfilename;
break;
case elognameformat.name_date:
sLogName = m_logfilename + "_" + sPeriod;
break;
}
}
string sFilePath = "";
if (sPeriod=="")
{
sFilePath = System.Environment.CurrentDirectory.TrimEnd('\\') + "\\" + LogName + m_logfiletype;
}
else
{
sFilePath = System.Environment.CurrentDirectory.TrimEnd('\\') + "\\" + LogName + "_" + sPeriod + m_logfiletype;
}
m_logfilepath = sFilePath;
//return sFilePath;
return;
}
public void LogThis(string logtext,eloglevel loglevel)
{
LogThis(logtext, loglevel, m_logprefix);
}
public void LogThis(string logtext,eloglevel loglevel, elogprefix logprefix)
{
if (m_loglevel >= loglevel)
{
string sFilePath = LogPath;
if (sFilePath == "" )
{
SetLogPath();
sFilePath = LogPath;
}
//TruncateLogFile(sFilePath); // disabled by Ash 28.07.2005, substituted by the new RolloverLogFile method
RolloverLogFile(sFilePath);
DateTime dt = DateTime.Now;
switch (logprefix)
{
case elogprefix.dt:
logtext = dt.ToString("yyyy.MM.dd") + "-" + dt.ToString("hh.mm.ss") + ": " + logtext;
break;
case elogprefix.loglevel:
logtext = loglevel.ToString() + ": " + logtext;
break;
case elogprefix.dt_loglevel:
logtext = dt.ToString("yyyy.MM.dd") + "-" + dt.ToString("hh.mm.ss") + ":" + loglevel + ": " + logtext;
break;
}
//log it
switch (m_logwhere)
{
case elogwhere.file:
AppendToFile(sFilePath,logtext);
break;
case elogwhere.eventlog:
LogEvent(logtext,loglevel);
break;
case elogwhere.eventlog_and_file:
AppendToFile(sFilePath,logtext);
LogEvent(logtext,loglevel);
break;
}
}
}
}
}