You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4net-dev@logging.apache.org by Ron Grabowski <ro...@yahoo.com> on 2006/04/30 23:31:22 UTC

LoggingContext

I couldn't think of a good name for this concept...

Imagine you need to authenticate a user's login and password against a
data source. Your code might look like this:

 // EXAMPLE 0 - normal 
 log.InfoFormat("txtLogin.Text: [{0}]", txtLogin.Text); 
 log.InfoFormat("txtPassword.Text: [{0}]", txtPassword.Text); 
 if (authenticate(txtLogin.Text, txtPassword.Text) == false) 
 { 
  log.Info("Invalid username or password"); 
 } 
 else 
 { 
  // everything ok...do not create any messages 
 }

You might not always need to record those first two InfoFormat. If you
do record them, its important to know the exact timestamp and where
they were geenerated from. Here's a more complex example that uses the
idea of a "LoggingContext" to buffer messages then allows the buffered
messages to be flushed at a specific level or ignored entirely. In the
example, failed login attempts over a predefined limit are record
differently then just one or two failed login attempts:

 // EXAMPLE 1 - basic usage 
 using (LoggingContext lc = new LoggingContext(log)) 
 { 
  lc.Write("txtLogin.Text: [{0}]", txtLogin.Text); 
  lc.Write("txtPassword.Text: [{0}]", txtPassword.Text); 
  if (authenticate(txtLogin.Text, txtPassword.Text) == false) 
  { 
   lc.Write("Invalid username or password"); 
   failedAttempts++; 
   if (failedAttempts >= 5) 
   { 
    lc.Flush(LogLevel.Critical); 
   } 
   else if (failedAttempts > 3 && failedAttempts < 5) 
   { 
    lc.Flush(LogLevel.Warn); 
   } 
   else 
   { 
    lc.Flush(LogLevel.Info); 
   }  
  } 
  else 
  { 
   // everything ok...do not create any messages 
  } 
 }

This example writes the same log message with different log levels to
different loggers. The security logger may be more sensitive to certain
events than the audit logger or the developer's logger:

 // EXAMPLE 2 - register loggers from within the context 
 using (LoggingContext lc = new LoggingContext()) 
 { 
  lc.Write("txtLogin.Text: [{0}]", txtLogin.Text); 
  lc.Write("txtPassword.Text: [{0}]", txtPassword.Text); 
  if (authenticate(txtLogin.Text, txtPassword.Text) == false) 
  { 
   lc.Write("Invalid username or password"); 
   lc.Register(auditLog, LogLevel.Info); 
   lc.Register(log, LogLevel.Debug); 
   lc.Register(securityLog, LogLevel.Warn); 
   lc.Flush(); 
  } 
  else 
  { 
   // everything ok...do not create any messages 
  } 
 } 

Here's more examples showing various overloads:

 // EXAMPLE 3 - flushing to loggers within context 
 using (LoggingContext lc = new LoggingContext()) 
 { 
  lc.Write("txtLogin.Text: [{0}]", txtLogin.Text); 
  lc.Write("txtPassword.Text: [{0}]", txtPassword.Text); 
  if (authenticate(txtLogin.Text, txtPassword.Text) == false) 
  { 
   lc.Write("Invalid username or password"); 
   lc.Flush(auditLog, LogLevel.Info); 
   lc.Flush(securitylog, LogLevel.Warn); 
  } 
  else 
  { 
   lc.Flush(log, LogLevel.Debug); 
  } 
 } 

 // EXAMPLE 4 - Flush() automatically called in Dispose() 
 using (LoggingContext lc = new LoggingContext(log, LogLevel.Debug)) 
 { 
  lc.Write("txtLogin.Text: [{0}]", txtLogin.Text); 
  lc.Write("txtPassword.Text: [{0}]", txtPassword.Text); 
  if (authenticate(txtLogin.Text, txtPassword.Text) == false) 
  { 
   lc.Write("Invalid username or password"); 
  } 
  else 
  { 
   lc.Clear(); 
   // everything ok...do not create any messages 
  } 
 } 

 // EXAMPLE 5 - overloaded constructor to emit messages at non-standard
levels 
 using (LoggingContext lc = new LoggingContext(log, LogLevel.Debug,
"AUDIT")) 
 { 
  lc.Write("txtLogin.Text: [{0}]", txtLogin.Text); 
  lc.Write("txtPassword.Text: [{0}]", txtPassword.Text); 
  if (authenticate(txtLogin.Text, txtPassword.Text) == false) 
  { 
   lc.Write("Invalid username or password"); 
   lc.Flush(); 
  } 
  else 
  { 
   // everything ok...do not create any messages 
  } 
 } 

 // EXAMPLE 6: get access to a LoggingContext from the LogManager
 LoggingContext lc = LogManager.GetLoggingContext(typeof(Class1)); 
 lc.Write("Hello World"); 
 lc.Write(LogLevel.Debug, "Hello World");

Comments?

- Ron