2010-10-05 6 views
5

¿Cómo puedo separar el registro/auditoría de mi normal de mi registro/auditoría de seguridad? El Registro de eventos de Windows hace esta distinción con Eventos de aplicaciones y Eventos de seguridad.NLog LogLevels personalizados o varios registradores por clase?

Si pudiera crear un LogLevel personalizado, p. LogLevel.AuditSuccess o LogLevel.AuditFailure, entonces podría establecer mis reglas de archivos de configuración para que sean iguales y dar salida a esos eventos. Por ejemplo,

<logger name="*" levels="AuditSuccess,AuditFailure" writeTo="target1"/> 
<logger name="*" levels="DEBUG,INFO" writeTo="target1"/> 

Entonces posible que utilices 1 cuadro los "Nivel" en una columna, y ser capaz de buscar y ordenar los datos utilizando esta información de la columna. (No creo que podamos crear un LogLevel personalizado.)

Una solución que se me ocurre es usar 2 registradores por clase, con cada registrador se guarda en un objetivo diferente. Sin embargo, esto parece excesivo, especialmente si necesito agregar tipos de objetivos similares adicionales.

<logger name="myNamespace.*" levels="INFO,ERROR" writeTo="target1"/> 
<logger name="mySecurityLogger" levels="INFO,ERROR" writeTo="target2"/> 

public class MyClass { 
    private static Logger _logger = LogManager.GetCurrentClassLogger(); 
    private statac Logger _loggerSecurity = LogManager.GetLogger("mySecurityLogger"); 
    ... 
} 

Con esto, pude crear dos objetivos de bases de datos - cada uno con una tabla diferente - y luego crear 1 regla para cada uno de destino.

¿Alguna sugerencia?

Respuesta

6

Esto podría no ser lo que está después, pero tengan paciencia conmigo ...

Usted puede envolver Nlog tal que puede iniciar sesión con sus propios "madereros". Eche un vistazo a Common.Logging for .NET o SLF para ver ejemplos de cómo ajustar NLog (son abstracciones de registro completas, por lo que son más complejas que lo que busca, pero puede recoger algunas buenas ideas). También vea here (probablemente debería ver aquí primero si cree que podría estar interesado en simplemente envolver o subclasificar el Logger NLog) para ver ejemplos de cómo ajustar (o subclase) NLog correctamente (tenga en cuenta que la clave es pasar el tipo de su el registrador envuelto/subclasificado al método de registro de NLog).

Por lo tanto, es posible que tenga algo como esto (abreviado):

//Wrapped logger that you could create once in a class and use to log both 
//"normal" messages and "audit" messages. NLog log level is determined by the 
//logger configuration for the class. 
public class MyLogger 
{ 
    private Logger logger; //NLog logger 

    public MyLogger(string name) 
    { 
    logger = LogManager.GetLogger(name); 
    } 

    public void Info(string message) 
    { 
    if (!logger.IsInfoEnabled) return; 

    Write(LogLevel.Info, LogLevel.Info.ToString(), message); 
    } 

    public void AuditSuccess(string message) 
    { 
    if (!logger.IsInfoEnabled) return; 

    Write(LogLevel.Info, "AuditSuccess", message); 
    } 

    private void Write(LogLevel level, string customLevel, string message) 
    { 
    LogEventInfo le = new LogEventInfo(level, logger.Name, message); 
    le.Context["CustomLogLevel"] = customLevel; 
    logger.Log(typeof(MyLogger), le); 
    } 
} 

Esto le dará métodos de registro de nivel específico correspondiente a sus niveles personalizados. También le dará la posibilidad de generar una columna personalizada que contenga su "nivel personalizado" (using the event-context layout renderer). No le da la posibilidad de activar o desactivar el registro de nivel "AuditSuccess". Todavía debe ser controlado por los niveles incorporados.

Alternativamente, podría incluir dos registradores en su clase empaquetada y usar uno para niveles incorporados y el otro para niveles personalizados. Su envoltorio podría tener este aspecto:

//Wrapped logger that you could create once in a class and use to log both "normal" 
//and "audit" messages. NLog log level for each type of message is controllable 
//separately since the logger wrapper actually wraps two logger. 
public class MyLogger 
{ 
    private Logger logger; //NLog logger 
    private Logger auditLogger; 

    public MyLogger(string name) 
    { 
    logger = LogManager.GetLogger(name); 
    auditLogger = LogManager.GetLogger("AuditLogger"); 
    } 

    public void Info(string message) 
    { 
    if (!logger.IsInfoEnabled) return; 

    Write(logger, LogLevel.Info, LogLevel.Info.ToString(), messsage); 
    } 

    public void AuditSuccess(string message) 
    { 
    if (!auditLogger.IsInfoEnabled) return; 

    Write(auditLogger, LogLevel.Info, "AuditSuccess", message); 
    } 

    private void Write(Logger log, LogLevel level, string customLevel, string message) 
    { 
    LogEventInfo le = new LogEventInfo(level, log.Name, message); 
    le.Context["CustomLogLevel"] = customLevel; 
    log.Log(typeof(MyLogger), le); 
    } 
} 

a pesar de ello tienen las mismas restricciones que se indican más arriba, pero al menos podrías control "de auditoría/seguridad" registro por separado de registro "normal".

En cualquier caso, puede enviar la salida de todos los registradores a la misma base de datos y solo hacer sus consultas en la columna "nivel personalizado" en lugar de la columna "nivel". Dependiendo del número de seguridad/auditoría "categorías" que tiene, que incluso podría querer hacer una jerarquía concreta de tal manera que usted puede tomar ventaja de las jerarquías del registrador en el archivo de configuración Nlog:

Seguridad Security.Audit Seguridad. Audit.Success Security.Audit.Failure Seguridad.Login Security.Login.Success Security.Login.Failure Salud Health.Heartbeat Health.Whatever

entonces se podría "encender" Seguridad o Security.Audit o . .Fallo (no estoy seguro de si el último funciona o no).

Espero que esto ayude.

3

¿No podría usar dos registradores con nombres diferentes en su clase, generarlos en el mismo destino y usar ${logger} layout renderer como valor de campo?

Honestamente, si estos eventos son tan importantes en el dominio de la aplicación, quizás grabarlos a través del marco de trabajo de registro es la forma incorrecta de hacerlo. Tal vez debería ser un concepto modelado más explícitamente en su aplicación. Por supuesto, si está obligado a almacenar los datos del evento en el mismo lugar que los otros mensajes de registro, es posible que no tenga esa opción.

De lo contrario, tiendo a alejarme de los niveles de registro personalizados, ya que nunca han probado que valga la pena agregarlos.

Cuestiones relacionadas