He estado buscando una manera de registrar nombres de clases y nombres de métodos como parte de mi infraestructura de registro. Obviamente, me gustaría que sea simple de usar y rápido en tiempo de ejecución. He leído mucho sobre el registro de nombres de clases y métodos, pero me he encontrado con 2 temas.Logging ClassName y MethodName usando log4net para un proyecto .NET
- Ese log4net usa una excepción de tiro interno para generar un marco de pila y eso se vuelve costoso si se usa generalmente para todo el registro.
- Confusión. Hay mucha literatura por ahí. He intentado un montón y no conseguí algo útil.
Si me toma el pelo por un segundo, me gustaría restablecer.
he creado una clase como esta en mi proyecto
public static class Log {
private static Dictionary<Type, ILog> _loggers = new Dictionary<Type, ILog>();
private static bool _logInitialized = false;
private static object _lock = new object();
public static string SerializeException(Exception e) {
return SerializeException(e, string.Empty);
}
private static string SerializeException(Exception e, string exceptionMessage) {
if (e == null) return string.Empty;
exceptionMessage = string.Format(
"{0}{1}{2}\n{3}",
exceptionMessage,
(exceptionMessage == string.Empty) ? string.Empty : "\n\n",
e.Message,
e.StackTrace);
if (e.InnerException != null)
exceptionMessage = SerializeException(e.InnerException, exceptionMessage);
return exceptionMessage;
}
private static ILog getLogger(Type source) {
lock (_lock) {
if (_loggers.ContainsKey(source)) {
return _loggers[source];
}
ILog logger = log4net.LogManager.GetLogger(source);
_loggers.Add(source, logger);
return logger;
}
}
public static void Debug(object source, object message) {
Debug(source.GetType(), message);
}
public static void Debug(Type source, object message) {
getLogger(source).Debug(message);
}
public static void Info(object source, object message) {
Info(source.GetType(), message);
}
public static void Info(Type source, object message) {
getLogger(source).Info(message);
}
...
private static void initialize() {
XmlConfigurator.Configure();
}
public static void EnsureInitialized() {
if (!_logInitialized) {
initialize();
_logInitialized = true;
}
}
}
(Si este código parece familiar es porque ha sido tomada de los ejemplos!)
En cualquier caso, a lo largo de mi proyecto utilizo líneas como esta para iniciar sesión:
Log.Info(typeof(Program).Name, "System Start");
Bueno, este tipo de obras. Lo que es más importante, obtengo el nombre de clase pero no el nombre del método. Menos, importante, estoy contaminando mi código con este "tipo de basura". Si copio y pego un fragmento de código entre archivos, etc. ¡el framework de registro estará mintiendo!
Intenté jugar con PatternLayout (% C {1}. {M}) pero eso no funcionó (todo lo que hizo fue escribir "Log.Info" en el registro, porque todo está enrutando a través del Log .X métodos estáticos!). Además, se supone que es lento.
Entonces, ¿cuál es la mejor manera, dada mi configuración y mi deseo de ser simple y rápido?
Apreciar cualquier ayuda con anticipación.
Tenga en cuenta que, de acuerdo con este enlace (http://msdn.microsoft .com/en-us/library/system.diagnostics.stacktrace.aspx), StackTrace en .NET sí requiere el permiso UnmanagedCode. Sin embargo, de acuerdo con este enlace,() StackTrace en Silverlight no tiene la misma restricción. Mi punto es que, si NLog es compatible con Silverlight (como lo será la próxima versión 2.0), GetCurrentClassLogger podría funcionar perfectamente en Silverlight (si se implementa correctamente). Como señala Joe, en .NET o .NET Client Profile "normal", podría encontrarse con la restricción UnmanagedCode. – wageoghe
Perdió pegando el segundo enlace anterior: StackTrace en .NET (http://msdn.microsoft.com/en-us/library/system.diagnostics.stacktrace.aspx) StackTrace en Silverlight (http://msdn.microsoft.com) /en-us/library/system.diagnostics.stacktrace(VS.95).aspx) – wageoghe