Skip to content

Instantly share code, notes, and snippets.

@ferventcoder
Created July 12, 2012 16:17
Show Gist options
  • Save ferventcoder/3099122 to your computer and use it in GitHub Desktop.
Save ferventcoder/3099122 to your computer and use it in GitHub Desktop.
this.Log()
public class SomeClass {
public void SomeMethod() {
this.Log().Info(() => "Here is a log message with params which can be in Razor Views as well: '{0}'".FormatWith(typeof(SomeClass).Name));
}
}
Log.InitializeWith<Log4NetLog>();
/// <summary>
/// Extensions to help make logging awesome
/// </summary>
public static class LogExtensions
{
/// <summary>
/// Concurrent dictionary that ensures only one instance of a logger for a type.
/// </summary>
private static readonly Lazy<ConcurrentDictionary<string,ILog>> _dictionary = new Lazy<ConcurrentDictionary<string, ILog>>(()=>new ConcurrentDictionary<string, ILog>());
/// <summary>
/// Gets the logger for <see cref="T"/>.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="type">The type to get the logger for.</param>
/// <returns>Instance of a logger for the object.</returns>
public static ILog Log<T>(this T type)
{
string objectName = typeof(T).FullName;
return Log(objectName);
}
/// <summary>
/// Gets the logger for the specified object name.
/// </summary>
/// <param name="objectName">Either use the fully qualified object name or the short. If used with Log&lt;T&gt;() you must use the fully qualified object name"/></param>
/// <returns>Instance of a logger for the object.</returns>
public static ILog Log(this string objectName)
{
return _dictionary.Value.GetOrAdd(objectName, Infrastructure.Logging.Log.GetLoggerFor);
}
}
/// <summary>
/// Logger type initialization
/// </summary>
public static class Log
{
private static Type _logType = typeof(NullLog);
private static ILog _logger;
/// <summary>
/// Sets up logging to be with a certain type
/// </summary>
/// <typeparam name="T">The type of ILog for the application to use</typeparam>
public static void InitializeWith<T>() where T : ILog, new()
{
_logType = typeof(T);
}
/// <summary>
/// Sets up logging to be with a certain instance. The other method is preferred.
/// </summary>
/// <param name="loggerType">Type of the logger.</param>
/// <remarks>This is mostly geared towards testing</remarks>
public static void InitializeWith(ILog loggerType)
{
_logType = loggerType.GetType();
_logger = loggerType;
}
/// <summary>
/// Initializes a new instance of a logger for an object.
/// This should be done only once per object name.
/// </summary>
/// <param name="objectName">Name of the object.</param>
/// <returns>ILog instance for an object if log type has been intialized; otherwise null</returns>
public static ILog GetLoggerFor(string objectName)
{
var logger = _logger;
if (_logger == null)
{
logger = Activator.CreateInstance(_logType) as ILog;
if (logger != null)
{
logger.InitializeFor(objectName);
}
}
return logger;
}
}
/// <summary>
/// Custom interface for logging messages
/// </summary>
public interface ILog
{
/// <summary>
/// Initializes the instance for the logger name
/// </summary>
/// <param name="loggerName">Name of the logger</param>
void InitializeFor(string loggerName);
/// <summary>
/// Debug level of the specified message. The other method is preferred since the execution is deferred.
/// </summary>
/// <param name="message">The message.</param>
/// <param name="formatting">The formatting.</param>
void Debug(string message, params object[] formatting);
/// <summary>
/// Debug level of the specified message.
/// </summary>
/// <param name="message">The message.</param>
void Debug(Func<string> message);
/// <summary>
/// Info level of the specified message. The other method is preferred since the execution is deferred.
/// </summary>
/// <param name="message">The message.</param>
/// <param name="formatting">The formatting.</param>
void Info(string message, params object[] formatting);
/// <summary>
/// Info level of the specified message.
/// </summary>
/// <param name="message">The message.</param>
void Info(Func<string> message);
/// <summary>
/// Warn level of the specified message. The other method is preferred since the execution is deferred.
/// </summary>
/// <param name="message">The message.</param>
/// <param name="formatting">The formatting.</param>
void Warn(string message, params object[] formatting);
/// <summary>
/// Warn level of the specified message.
/// </summary>
/// <param name="message">The message.</param>
void Warn(Func<string> message);
/// <summary>
/// Error level of the specified message. The other method is preferred since the execution is deferred.
/// </summary>
/// <param name="message">The message.</param>
/// <param name="formatting">The formatting.</param>
void Error(string message, params object[] formatting);
/// <summary>
/// Error level of the specified message.
/// </summary>
/// <param name="message">The message.</param>
void Error(Func<string> message);
/// <summary>
/// Fatal level of the specified message. The other method is preferred since the execution is deferred.
/// </summary>
/// <param name="message">The message.</param>
/// <param name="formatting">The formatting.</param>
void Fatal(string message, params object[] formatting);
/// <summary>
/// Fatal level of the specified message.
/// </summary>
/// <param name="message">The message.</param>
void Fatal(Func<string> message);
}
/// <summary>
/// Ensures a default constructor for the logger type
/// </summary>
/// <typeparam name="T"></typeparam>
public interface ILog<T> where T : new()
{
}
}
/// <summary>
/// The default logger until one is set.
/// </summary>
public class NullLog : ILog, ILog<NullLog>
{
public void InitializeFor(string loggerName)
{
}
public void Debug(string message, params object[] formatting)
{
}
public void Debug(Func<string> message)
{
}
public void Info(string message, params object[] formatting)
{
}
public void Info(Func<string> message)
{
}
public void Warn(string message, params object[] formatting)
{
}
public void Warn(Func<string> message)
{
}
public void Error(string message, params object[] formatting)
{
}
public void Error(Func<string> message)
{
}
public void Fatal(string message, params object[] formatting)
{
}
public void Fatal(Func<string> message)
{
}
}
using System;
using log4net;
using log4net.Config;
[assembly: XmlConfigurator(Watch = true)]
namespace Some.Namespace {
/// <summary>
/// Log4net logger implementing special ILog class
/// </summary>
public class Log4NetLog : ILog, ILog<Log4NetLog>
{
private global::log4net.ILog _logger;
public void InitializeFor(string loggerName)
{
_logger = LogManager.GetLogger(loggerName);
}
public void Debug(string message, params object[] formatting)
{
if (_logger.IsDebugEnabled) _logger.DebugFormat(DecorateMessageWithAuditInformation(message), formatting);
}
public void Debug(Func<string> message)
{
if (_logger.IsDebugEnabled) _logger.Debug(DecorateMessageWithAuditInformation(message.Invoke()));
}
public void Info(string message, params object[] formatting)
{
if (_logger.IsInfoEnabled) _logger.InfoFormat(DecorateMessageWithAuditInformation(message), formatting);
}
public void Info(Func<string> message)
{
if (_logger.IsInfoEnabled) _logger.Info(DecorateMessageWithAuditInformation(message.Invoke()));
}
public void Warn(string message, params object[] formatting)
{
if (_logger.IsWarnEnabled) _logger.WarnFormat(DecorateMessageWithAuditInformation(message), formatting);
}
public void Warn(Func<string> message)
{
if (_logger.IsWarnEnabled) _logger.Warn(DecorateMessageWithAuditInformation(message.Invoke()));
}
public void Error(string message, params object[] formatting)
{
// don't need to check for enabled at this level
_logger.ErrorFormat(DecorateMessageWithAuditInformation(message), formatting);
}
public void Error(Func<string> message)
{
// don't need to check for enabled at this level
_logger.Error(DecorateMessageWithAuditInformation(message.Invoke()));
}
public void Fatal(string message, params object[] formatting)
{
// don't need to check for enabled at this level
_logger.FatalFormat(DecorateMessageWithAuditInformation(message), formatting);
}
public void Fatal(Func<string> message)
{
// don't need to check for enabled at this level
_logger.Fatal(DecorateMessageWithAuditInformation(message.Invoke()));
}
public string DecorateMessageWithAuditInformation(string message)
{
string currentUserName = ApplicationParameters.GetCurrentUserName();
if (!string.IsNullOrWhiteSpace(currentUserName))
{
return "{0} - {1}".FormatWith(message, currentUserName);
}
return message;
}
}
}
public static class StringExtensions
{
/// <summary>
/// Formats string with the formatting passed in. This is a shortcut to string.Format().
/// </summary>
/// <param name="input">The input.</param>
/// <param name="formatting">The formatting.</param>
/// <returns>A formatted string.</returns>
public static string FormatWith(this string input, params object[] formatting)
{
return string.Format(input, formatting);
}
}
@chrissie1
Copy link

Look at the following gits https://gist.github.com/4299744 and tell me what you think.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment