Files
Umbraco-CMS/umbraco/businesslogic/Log.cs
2010-11-15 14:12:21 +00:00

533 lines
20 KiB
C#
Raw Blame History

using System;
using System.Data;
using System.Diagnostics;
using System.Threading;
using umbraco.DataLayer;
using System.Collections.Generic;
using System.Reflection;
using umbraco.BusinessLogic.Utils;
namespace umbraco.BusinessLogic
{
/// <summary>
/// Summary description for Log.
/// </summary>
public class Log
{
#region Statics
private Interfaces.ILog m_externalLogger = null;
private bool m_externalLoggerInitiated = false;
internal Interfaces.ILog ExternalLogger
{
get
{
if (!m_externalLoggerInitiated)
{
m_externalLoggerInitiated = true;
if (!String.IsNullOrEmpty(UmbracoSettings.ExternalLoggerAssembly)
&& !String.IsNullOrEmpty(UmbracoSettings.ExternalLoggerType))
{
try
{
string assemblyPath = IO.IOHelper.MapPath(UmbracoSettings.ExternalLoggerAssembly);
m_externalLogger = Assembly.LoadFrom(assemblyPath).CreateInstance(UmbracoSettings.ExternalLoggerType) as Interfaces.ILog;
}
catch (Exception ee)
{
Log.AddLocally(LogTypes.Error, User.GetUser(0), -1,
"Error loading external logger: " + ee.ToString());
}
}
}
return m_externalLogger;
}
}
#region Singleton
public static Log Instance
{
get { return Singleton<Log>.Instance; }
}
#endregion
private static ISqlHelper SqlHelper
{
get { return Application.SqlHelper; }
}
/// <summary>
/// Adds the specified log item to the log.
/// </summary>
/// <param name="type">The log type.</param>
/// <param name="user">The user adding the item.</param>
/// <param name="nodeId">The affected node id.</param>
/// <param name="comment">Comment.</param>
public static void Add(LogTypes type, User user, int nodeId, string comment)
{
if (Instance.ExternalLogger != null)
{
Instance.ExternalLogger.Add(type, user, nodeId, comment);
// Audit trail too?
if (!UmbracoSettings.ExternalLoggerLogAuditTrail && type.GetType().GetField(type.ToString()).GetCustomAttributes(typeof(AuditTrailLogItem), true) != null)
{
AddLocally(type, user, nodeId, comment);
}
}
else
{
if (!UmbracoSettings.EnableLogging) return;
if (UmbracoSettings.DisabledLogTypes != null &&
UmbracoSettings.DisabledLogTypes.SelectSingleNode(String.Format("//logTypeAlias [. = '{0}']", type.ToString().ToLower())) == null)
{
if (comment.Length > 3999)
comment = comment.Substring(0, 3955) + "...";
if (UmbracoSettings.EnableAsyncLogging)
{
ThreadPool.QueueUserWorkItem(
delegate { AddSynced(type, user == null ? 0 : user.Id, nodeId, comment); });
return;
}
AddSynced(type, user == null ? 0 : user.Id, nodeId, comment);
}
}
}
public void AddException(Exception ee)
{
if (ExternalLogger != null)
{
ExternalLogger.Add(ee);
}
else
{
Exception ex2 = ee;
string error = String.Empty;
string errorMessage = string.Empty;
while (ex2 != null)
{
error += ex2.ToString();
ex2 = ex2.InnerException;
}
Add(LogTypes.Error, -1, error);
}
}
/// <summary>
/// Adds the specified log item to the Umbraco log no matter if an external logger has been defined.
/// </summary>
/// <param name="type">The log type.</param>
/// <param name="user">The user adding the item.</param>
/// <param name="nodeId">The affected node id.</param>
/// <param name="comment">Comment.</param>
public static void AddLocally(LogTypes type, User user, int nodeId, string comment)
{
if (comment.Length > 3999)
comment = comment.Substring(0, 3955) + "...";
if (UmbracoSettings.EnableAsyncLogging)
{
ThreadPool.QueueUserWorkItem(
delegate { AddSynced(type, user == null ? 0 : user.Id, nodeId, comment); });
return;
}
AddSynced(type, user == null ? 0 : user.Id, nodeId, comment);
}
/// <summary>
/// Adds the specified log item to the log without any user information attached.
/// </summary>
/// <param name="type">The log type.</param>
/// <param name="nodeId">The affected node id.</param>
/// <param name="comment">Comment.</param>
public static void Add(LogTypes type, int nodeId, string comment)
{
Add(type, null, nodeId, comment);
}
/// <summary>
/// Adds a log item to the log immidiately instead of Queuing it as a work item.
/// </summary>
/// <param name="type">The type.</param>
/// <param name="userId">The user id.</param>
/// <param name="nodeId">The node id.</param>
/// <param name="comment">The comment.</param>
public static void AddSynced(LogTypes type, int userId, int nodeId, string comment)
{
try
{
SqlHelper.ExecuteNonQuery(
"insert into umbracoLog (userId, nodeId, logHeader, logComment) values (@userId, @nodeId, @logHeader, @comment)",
SqlHelper.CreateParameter("@userId", userId),
SqlHelper.CreateParameter("@nodeId", nodeId),
SqlHelper.CreateParameter("@logHeader", type.ToString()),
SqlHelper.CreateParameter("@comment", comment));
}
catch (Exception e)
{
Debug.WriteLine(e.ToString(), "Error");
Trace.WriteLine(e.ToString());
}
}
public List<LogItem> GetAuditLogItems(int NodeId)
{
if (UmbracoSettings.ExternalLoggerLogAuditTrail && ExternalLogger != null)
return ExternalLogger.GetAuditLogReader(NodeId);
else
return LogItem.ConvertIRecordsReader(SqlHelper.ExecuteReader(
"select userId, nodeId, logHeader, DateStamp, logComment from umbracoLog where nodeId = @id and logHeader not in ('open','system') order by DateStamp desc",
SqlHelper.CreateParameter("@id", NodeId)));
}
public List<LogItem> GetLogItems(LogTypes type, DateTime sinceDate)
{
if (ExternalLogger != null)
return ExternalLogger.GetLogItems(type, sinceDate);
else
return LogItem.ConvertIRecordsReader(SqlHelper.ExecuteReader(
"select userId, NodeId, DateStamp, logHeader, logComment from umbracoLog where logHeader = @logHeader and DateStamp >= @dateStamp order by dateStamp desc",
SqlHelper.CreateParameter("@logHeader", type),
SqlHelper.CreateParameter("@dateStamp", sinceDate)));
}
public List<LogItem> GetLogItems(int nodeId)
{
if (ExternalLogger != null)
return ExternalLogger.GetLogItems(nodeId);
else
return LogItem.ConvertIRecordsReader(SqlHelper.ExecuteReader(
"select userId, NodeId, DateStamp, logHeader, logComment from umbracoLog where id = @id order by dateStamp desc",
SqlHelper.CreateParameter("@id", nodeId)));
}
public List<LogItem> GetLogItems(User user, DateTime sinceDate)
{
if (ExternalLogger != null)
return ExternalLogger.GetLogItems(user, sinceDate);
else
return LogItem.ConvertIRecordsReader(SqlHelper.ExecuteReader(
"select userId, NodeId, DateStamp, logHeader, logComment from umbracoLog where UserId = @user and DateStamp >= @dateStamp order by dateStamp desc",
SqlHelper.CreateParameter("@user", user.Id),
SqlHelper.CreateParameter("@dateStamp", sinceDate)));
}
public List<LogItem> GetLogItems(User user, LogTypes type, DateTime sinceDate)
{
if (ExternalLogger != null)
return ExternalLogger.GetLogItems(user, type, sinceDate);
else
return LogItem.ConvertIRecordsReader(SqlHelper.ExecuteReader(
"select userId, NodeId, DateStamp, logHeader, logComment from umbracoLog where UserId = @user and logHeader = @logHeader and DateStamp >= @dateStamp order by dateStamp desc",
SqlHelper.CreateParameter("@logHeader", type),
SqlHelper.CreateParameter("@user", user.Id),
SqlHelper.CreateParameter("@dateStamp", sinceDate)));
}
public static void CleanLogs(int maximumAgeOfLogsInMinutes)
{
if (Instance.ExternalLogger != null)
Instance.ExternalLogger.CleanLogs(maximumAgeOfLogsInMinutes);
else
{
try
{
DateTime oldestPermittedLogEntry = DateTime.Now.Subtract(new TimeSpan(0, maximumAgeOfLogsInMinutes, 0));
SqlHelper.ExecuteNonQuery("delete from umbracoLog where datestamp < @oldestPermittedLogEntry and logHeader in ('open','system')",
SqlHelper.CreateParameter("@oldestPermittedLogEntry", oldestPermittedLogEntry));
Add(LogTypes.System, -1, "Log scrubbed. Removed all items older than " + oldestPermittedLogEntry);
}
catch (Exception e)
{
Debug.WriteLine(e.ToString(), "Error");
Trace.WriteLine(e.ToString());
}
}
}
#region New GetLog methods - DataLayer layer compatible
/// <summary>
/// Gets a reader for the audit log.
/// </summary>
/// <param name="NodeId">The node id.</param>
/// <returns>A reader for the audit log.</returns>
[Obsolete("Use the Instance.GetAuditLogItems method which return a list of LogItems instead")]
public static IRecordsReader GetAuditLogReader(int NodeId)
{
return SqlHelper.ExecuteReader(
"select u.userName as [User], logHeader as Action, DateStamp as Date, logComment as Comment from umbracoLog inner join umbracoUser u on u.id = userId where nodeId = @id and logHeader not in ('open','system') order by DateStamp desc",
SqlHelper.CreateParameter("@id", NodeId));
}
/// <summary>
/// Gets a reader for the log for the specified types.
/// </summary>
/// <param name="Type">The type of log message.</param>
/// <param name="SinceDate">The start date.</param>
/// <returns>A reader for the log.</returns>
[Obsolete("Use the Instance.GetLogItems method which return a list of LogItems instead")]
public static IRecordsReader GetLogReader(LogTypes Type, DateTime SinceDate)
{
return SqlHelper.ExecuteReader(
"select userId, NodeId, DateStamp, logHeader, logComment from umbracoLog where logHeader = @logHeader and DateStamp >= @dateStamp order by dateStamp desc",
SqlHelper.CreateParameter("@logHeader", Type.ToString()),
SqlHelper.CreateParameter("@dateStamp", SinceDate));
}
/// <summary>
/// Gets a reader for the log of the specified node.
/// </summary>
/// <param name="NodeId">The node id.</param>
/// <returns>A reader for the log.</returns>
[Obsolete("Use the Instance.GetLogItems method which return a list of LogItems instead")]
public static IRecordsReader GetLogReader(int NodeId)
{
return SqlHelper.ExecuteReader(
"select u.userName, DateStamp, logHeader, logComment from umbracoLog inner join umbracoUser u on u.id = userId where nodeId = @id",
SqlHelper.CreateParameter("@id", NodeId));
}
/// <summary>
/// Gets a reader for the log for the specified user.
/// </summary>
/// <param name="user">The user.</param>
/// <param name="SinceDate">The start date.</param>
/// <returns>A reader for the log.</returns>
[Obsolete("Use the Instance.GetLogItems method which return a list of LogItems instead")]
public static IRecordsReader GetLogReader(User user, DateTime SinceDate)
{
return SqlHelper.ExecuteReader(
"select userId, NodeId, DateStamp, logHeader, logComment from umbracoLog where UserId = @user and DateStamp >= @dateStamp order by dateStamp desc",
SqlHelper.CreateParameter("@user", user.Id),
SqlHelper.CreateParameter("@dateStamp", SinceDate));
}
/// <summary>
/// Gets a reader of specific for the log for specific types and a specified user.
/// </summary>
/// <param name="user">The user.</param>
/// <param name="Type">The type of log message.</param>
/// <param name="SinceDate">The since date.</param>
/// <returns>A reader for the log.</returns>
[Obsolete("Use the Instance.GetLogItems method which return a list of LogItems instead")]
public static IRecordsReader GetLogReader(User user, LogTypes Type, DateTime SinceDate)
{
return SqlHelper.ExecuteReader(
"select userId, NodeId, DateStamp, logHeader, logComment from umbracoLog where UserId = @user and logHeader = @logHeader and DateStamp >= @dateStamp order by dateStamp desc",
SqlHelper.CreateParameter("@logHeader", Type.ToString()),
SqlHelper.CreateParameter("@user", user.Id),
SqlHelper.CreateParameter("@dateStamp", SinceDate));
}
#endregion
#endregion
}
/// <summary>
/// The collection of available log types.
/// </summary>
public enum LogTypes
{
/// <summary>
/// Used when new nodes are added
/// </summary>
[AuditTrailLogItem]
New,
/// <summary>
/// Used when nodes are saved
/// </summary>
[AuditTrailLogItem]
Save,
/// <summary>
/// Used when nodes are opened
/// </summary>
[AuditTrailLogItem]
Open,
/// <summary>
/// Used when nodes are deleted
/// </summary>
[AuditTrailLogItem]
Delete,
/// <summary>
/// Used when nodes are published
/// </summary>
[AuditTrailLogItem]
Publish,
/// <summary>
/// Used when nodes are send to publishing
/// </summary>
[AuditTrailLogItem]
SendToPublish,
/// <summary>
/// Used when nodes are unpublished
/// </summary>
[AuditTrailLogItem]
UnPublish,
/// <summary>
/// Used when nodes are moved
/// </summary>
[AuditTrailLogItem]
Move,
/// <summary>
/// Used when nodes are copied
/// </summary>
[AuditTrailLogItem]
Copy,
/// <summary>
/// Used when nodes are ass<73>gned a domain
/// </summary>
[AuditTrailLogItem]
AssignDomain,
/// <summary>
/// Used when public access are changed for a node
/// </summary>
[AuditTrailLogItem]
PublicAccess,
/// <summary>
/// Used when nodes are sorted
/// </summary>
[AuditTrailLogItem]
Sort,
/// <summary>
/// Used when a notification are send to a user
/// </summary>
[AuditTrailLogItem]
Notify,
/// <summary>
/// Used when a user logs into the umbraco back-end
/// </summary>
Login,
/// <summary>
/// Used when a user logs out of the umbraco back-end
/// </summary>
Logout,
/// <summary>
/// Used when a user login fails
/// </summary>
LoginFailure,
/// <summary>
/// General system notification
/// </summary>
[AuditTrailLogItem]
System,
/// <summary>
/// System debugging notification
/// </summary>
Debug,
/// <summary>
/// System error notification
/// </summary>
Error,
/// <summary>
/// Notfound error notification
/// </summary>
NotFound,
/// <summary>
/// Used when a node's content is rolled back to a previous version
/// </summary>
[AuditTrailLogItem]
RollBack,
/// <summary>
/// Used when a package is installed
/// </summary>
[AuditTrailLogItem]
PackagerInstall,
/// <summary>
/// Used when a package is uninstalled
/// </summary>
[AuditTrailLogItem]
PackagerUninstall,
/// <summary>
/// Used when a ping is send to/from the system
/// </summary>
Ping,
/// <summary>
/// Used when a node is send to translation
/// </summary>
[AuditTrailLogItem]
SendToTranslate,
/// <summary>
/// Notification from a Scheduled task.
/// </summary>
ScheduledTask,
/// <summary>
/// Use this log action for custom log messages that should be shown in the audit trail
/// </summary>
[AuditTrailLogItem]
Custom
}
public class LogItem
{
public int UserId { get; set; }
public int NodeId { get; set; }
public DateTime Timestamp { get; set; }
public LogTypes LogType { get; set; }
public string Comment { get; set; }
public LogItem()
{
}
public LogItem(int userId, int nodeId, DateTime timestamp, LogTypes logType, string comment)
{
UserId = userId;
NodeId = nodeId;
Timestamp = timestamp;
LogType = logType;
Comment = comment;
}
public static List<LogItem> ConvertIRecordsReader(IRecordsReader reader)
{
List<LogItem> items = new List<LogItem>();
while (reader.Read())
{
items.Add(new LogItem(
reader.GetInt("userId"),
reader.GetInt("nodeId"),
reader.GetDateTime("DateStamp"),
convertLogHeader(reader.GetString("logHeader")),
reader.GetString("logComment")));
}
return items;
}
private static LogTypes convertLogHeader(string logHeader)
{
try
{
return (LogTypes)Enum.Parse(typeof(LogTypes), logHeader, true);
}
catch
{
return LogTypes.Custom;
}
}
}
public class AuditTrailLogItem : Attribute
{
public AuditTrailLogItem()
{
}
}
}