Doug,

I agree that ignoring the exception argument for the xxxFormat methods
makes the most sense. It gives users the full power of the string.Format
but does not complicate things by forcing them to understand the special
processing of the exception. If they want to specify the exception they
still can but have to use the older Debug() methods.

Therefore we would have to add the following:

public void DebugFormat(string format, params object[] args)
{
        Debug(string.Format(format, args));
}

public void DebugFormat(IFormatProvider provider, string format, params
object[] args)
{
        Debug(string.Format(provider, format, args));
}

I still think that it is worth passing the IFormatProvider as that is
how the String.Format supports different locales.

Will this fulfil your requirements?

Nicko

> -----Original Message-----
> From: de la Torre, Douglas [mailto:[EMAIL PROTECTED] 
> Sent: 18 September 2004 01:06
> To: Log4NET Dev
> Subject: RE: New code to allow formatting during logging
> 
> Nicko,
> 
> Thanks for the response.  This is a bit more challenging that 
> it first appeared, but I'm hoping it is still solvable.
> 
> Seems like there are some options
> 
> 1)  Set expectations that DebugFormat is simply a convenience 
> method that wraps string.Format.  Any exceptions are rendered 
> into a string along with the other parameters via a call to 
> string.Format.  The rationale is that if you want to include 
> exception for remote transmission use the Debug methods.  
> DebugFormat is then understood to be just a wrapper for 
> string.Format.  Those who want the shortcut then have the 
> advantage of not needing lots of external string.Format calls.
> Code comments could state this too to make sure there is no 
> confusion ("This method calls string.Format using the input 
> arguments, and passes the result to Debug.  If you need 
> special control over Exceptions, call Debug directly instead").
> 
> 2)  Capture the parameters as part of LoggingEvent, and deal 
> with it at Render time (possible at a remote location)
> 
> 3)  Overloads (like you presented) that include exception as 
> a direct parameter.
> 
> Would it be acceptible to assume (1)?
> 
> If so, then the method is very simple:
> 
> public void DebugFormat( string format, params object[] args ) {
>       string message = string.Format( format, args );
>       Debug( message );
> }
> 
> If it turns out that special formatting control is needed 
> above the default Exception.ToString that would occur like 
> this, then maybe the existing formatting logic could be used
> 
> public void DebugFormat( string format, params object[] args ) {
>       string message;
> 
>       if( ContainsExceptionArgs( args ) )
>       {
>               object[] inlinedArgs = 
> RenderExceptionsToString( args ); // special formatting of exceptions
>               message = string.Format( format, inlinedArgs );
>       }
>       else
>       {       
>               message = string.Format( format, args );
>       }
> 
>       Debug( message );
> }
> 
> private object[] RenderExceptionsToString( args ) {
>       object[] inlined = new object[ args.Length ];
>       for( int i=0; i<args.Length; i++ )
>       {
>               if( args[ i ] is Exception )
>               {       
>                       inlined[ i ] = RenderException( 
> (Exception) args[ i ] );
>               }
>               else
>               {
>                       inlined[ i ] = args[ i ];
>               }
>       }
>       return inlined;
> }
> 
> private string RenderException( Exception ex ) {
>       ... call LoggingEvent.GetExceptionStrRep() or an 
> equivalent method to convert the exception to a string }
> 
> 
> What do you think?  Is it OK to assume a DebugFormat method 
> could be treated as a wrapper for string.Format without 
> needing to generalize it to forward exceptions?  Would the 
> message need to be rendered specially or is 
> Exception.ToString (via string.Format) sufficient?  
> 
> Is there anything else that would be needed to proceed with this?
> 
> -Doug
> 
> -----Original Message-----
> From: Nicko Cadell [mailto:[EMAIL PROTECTED]
> Sent: Thursday, September 16, 2004 3:07 PM
> To: Log4NET Dev
> Subject: RE: New code to allow formatting during logging
> 
> Doug, 
> 
> > I don't see a need to include Exception as a separate 
> argument, since 
> > it can be passed as a parameter.  Am I missing something here?
> 
> The Exception is not part of the message. It is stored 
> separately in the LoggingEvent. If, for example, the 
> RemotingAppender is used then the exception will be 
> serialised and sent to the remoting listener where it can be 
> desterilised.
> 
> 
> > Seems that having it as the first
> > parameter is confusing for users since most would try to 
> pass it as a 
> > parameter.
> 
> I certainly agree that putting the Exception argument first 
> is confusing for users. It reminds me of the inconsistencies with the
> ArgumentNullException:
> 
> ArgumentException(message, paramName)
> ArgumentNullException(paramName, message)
> 
> 
> > Maybe there is something special (related to 
> ExceptionLayout) that is 
> > being done above what we get via Exception.ToString that log4net 
> > performs and you are trying to preserve this logic?
> 
> As above, the Exception is stored seperatly to the message.
> 
> 
> >  Is there any way to test the
> > parameters and automatically grab the exeception if needed?
> 
> The issue with this is how to detect that an exception has 
> been passed to the DebugFormat method as part of the params 
> array, but it is not meant to be part of the message. Also 
> how do we really explain this to users and how discoverable 
> will this be as it won't show up in the method signature.
> 
> This is valid Format string syntax:
> 
> string.Format("Exception {0}", exception);
> 
> And so it this:
> 
> string.Format("Exception {0}", exception, otherException);
> 
> Note that you don't have to use all you parameters in the 
> format string.
> You can use any parameter zero or more times in any order.
> 
> It would be possible to examine the last parameter, and if it 
> is of type Exception then to see if that index is used 
> anywhere in the format string. If the last parameter is an 
> Exception and is the 5th item in the array then we could look 
> for "{4" followed by either "}", ",", or ":".
> We would still need to check for the open brace escape "{{". 
> That would tell us if the last exception is used in the format string.
> If the exception is not used then we could use that as the 
> exception for the LoggingEvent.
> 
> In order to determine if the exception is specified we would 
> need to examine the whole of the format message string.
> 
> The advantage of this method would be to reduce the number of 
> methods in the interface and reduce confusion as to the 
> placement of method arguments.
> The disadvantages of this are that the complexity of the 
> logging method is increased, an additional performance 
> overhead is introduced, it does not conform exactly to the 
> string.Format syntax and it becomes less discoverable. By 
> discoverable I mean that Visual Studio intellisense does not 
> inform you as there isn't an exception argument. A user would 
> need to read the docs to find out that they just pass the 
> exception as the last argument.
> 
> To be honest neither solution is particularly appealing to me.
> 
> Nicko
> 
> 
> 
> 

Reply via email to