This project is read-only.

Control characters in format string

Sep 1, 2010 at 3:48 PM

Is it possible to put control characters, like newline or tab, in the format string?  I tried just putting in a "\n" (like "Date: {DateTime}\nMessage: {Message}") but it didn't work.  Generally, I prefer getting a single logging statement on a single line, but it seems like it would be useful to be able to create a format string that would allow for multiline logging statements.  NLog and log4net both have an explicit "newline" token.  Using something like that, my above format string would look something like this:

"Date: {DateTime}{newline}Message: {Message}{newline}"

I was able to create my own "NewlineToken" like this:

  public class NewLineToken : StringPropertyReader
  {
    public override bool TryGetValue(out object value, TraceEventCache cache, string source, TraceEventType eventType, int id, string formatOrMessage, object[] data)
    {

      value = Environment.NewLine;

      return true;
    }
  }

I wasn't sure if Ukadc.Diagnostics already supported this concept, or if it didn't, if this was a good approach.  This works and allows me the option of defining a multiline format string.  If desired, similar "readers" could be created other characters that might be difficult to express in an app.config file, like tab ("\t").

I did notice one odd thing when I configured my format statement use my NewlineToken in the format string.  To save typing (in the app.config file), I named the token "N" like this:

      <token name="N"
             type="Ukadc.Diagnostics.Extensions.NewLineToken, Ukadc.Diagnostics.Extensions">
      </token>

However, when I used {N} in a format string, it was not recognized as a token.  Instead, it was considered part of the "literal" part of the string.  When I changed it to NN, or anything longer than one character, it worked fine.  So, it looks like there could be a problem with having one character long tokens.  Maybe that is not a big issue, because most people probably would use longer token names.  It does seem like it might useful (if not error-prone!) to be able to use an abbreviated syntax in the format string by defining at least some one character tokens. 

So, you could go from this:

      <token name="LogFormat"
             format ="{DateTimeLocal:MM/dd/yyyy HH:mm:ss.ffff} | {Timestamp} | {ElapsedTime} | {MachineName} | {ProcessId} | {LoggerName} | {TraceEventType} | {Message}">
      </token>

To this:

      <token name="LogFormat"
             format ="{DateTimeLocal:MM/dd/yyyy HH:mm:ss.ffff} | {S} | {E} | {LogEntryMachineName} | {P} | {LoggerName} | {TraceEventType} | {M}">
      </token>

Where S=Timestamp, E=ElapsedTime, P=Processid, and M=Message.

I don't know if that is good or bad!  Certainly, even with the "problem" of defining one character tokens, one could still use an abbreviated syntax by having each token have at least two characters.  That would still allow for this:

      <token name="LogFormat"
             format ="{DateTimeLocal:MM/dd/yyyy HH:mm:ss.ffff} | {TS} | {ET} | {LogEntryMachineName} | {PID} | {LN} | {ET} | {Msg}">
      </token>

Where TS=Timestamp, ET=ElapsedTime, PID=ProcessId, LN=LoggerName, ET=ElapsedTime, and Msg=Message.

Well, anyway, while I think that a "newline" token is useful, I don't know that I have a string opinion about the ability to configure tokens with one character names.  For N=newline, it seems pretty useful, but it is just about as easy to use NL=newline.

Sep 1, 2010 at 3:54 PM

Thanks wageoghe,

The way I do this is by actually using the required characters where possible, so if you want a new line in your message do this

<Example Message=”NewLineAfterThis

NewLineBeforeThis” />

Works great and your message is more readable. The other alternative is to use XML encoded characters to embed special characters in attributes (I can’t remember the way to do a new line off the top of my head but will demonstrate an & ampersand):

<Example Message=”This&That” />

I have thought about adding special tokens for this but with these alternatives I’ve so far found that unnecessary.

Thoughts?

Ta

Josh

From: wageoghe [mailto:notifications@codeplex.com]
Sent: 01 September 2010 15:49
To: Josh Twist
Subject: Control characters in format string [UkadcDiagnostics:225640]

From: wageoghe

Is it possible to put control characters, like newline or tab, in the format string? I tried just putting in a "\n" (like "Date: {DateTime}\nMessage: {Message}") but it didn't work. Generally, I prefer getting a single logging statement on a single line, but it seems like it would be useful to be able to create a format string that would allow for multiline logging statements. NLog and log4net both have an explicit "newline" token. Using something like that, my above format string would look something like this:

"Date: {DateTime}{newline}Message: {Message}{newline}"

I was able to create my own "NewlineToken" like this:

  public class NewLineToken : StringPropertyReader
  {
    public override bool TryGetValue(out object value, TraceEventCache cache, string source, TraceEventType eventType, int id, string formatOrMessage, object[] data)
    {
 
      value = Environment.NewLine;
 
      return true;
    }
  }
 

I wasn't sure if Ukadc.Diagnostics already supported this concept, or if it didn't, if this was a good approach. This works and allows me the option of defining a multiline format string. If desired, similar "readers" could be created other characters that might be difficult to express in an app.config file, like tab ("\t").

I did notice one odd thing when I configured my format statement use my NewlineToken in the format string. To save typing (in the app.config file), I named the token "N" like this:

      <token name="N"
             type="Ukadc.Diagnostics.Extensions.NewLineToken, Ukadc.Diagnostics.Extensions">
      </token>
 

However, when I used {N} in a format string, it was not recognized as a token. Instead, it was considered part of the "literal" part of the string. When I changed it to NN, or anything longer than one character, it worked fine. So, it looks like there could be a problem with having one character long tokens. Maybe that is not a big issue, because most people probably would use longer token names. It does seem like it might useful (if not error-prone!) to be able to use an abbreviated syntax in the format string by defining at least some one character tokens.

So, you could go from this:

      <token name="LogFormat"
             format ="{DateTimeLocal:MM/dd/yyyy HH:mm:ss.ffff} | {Timestamp} | {ElapsedTime} | {MachineName} | {ProcessId} | {LoggerName} | {TraceEventType} | {Message}">
      </token>
 

To this:

      <token name="LogFormat"
             format ="{DateTimeLocal:MM/dd/yyyy HH:mm:ss.ffff} | {S} | {E} | {LogEntryMachineName} | {P} | {LoggerName} | {TraceEventType} | {M}">
      </token>
 

Where S=Timestamp, E=ElapsedTime, P=Processid, and M=Message.

I don't know if that is good or bad! Certainly, even with the "problem" of defining one character tokens, one could still use an abbreviated syntax by having each token have at least two characters. That would still allow for this:

      <token name="LogFormat"
             format ="{DateTimeLocal:MM/dd/yyyy HH:mm:ss.ffff} | {TS} | {ET} | {LogEntryMachineName} | {PID} | {LN} | {ET} | {Msg}">
      </token>
 
Where TS=Timestamp, ET=ElapsedTime, PID=ProcessId, LN=LoggerName, ET=ElapsedTime, and Msg=Message.

Well, anyway, while I think that a "newline" token is useful, I don't know that I have a string opinion about the ability to configure tokens with one character names. For N=newline, it seems pretty useful, but it is just about as easy to use NL=newline.

Read the full discussion online.

To add a post to this discussion, reply to this email (UkadcDiagnostics@discussions.codeplex.com)

To start a new discussion for this project, email UkadcDiagnostics@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Sep 1, 2010 at 4:23 PM

That's pretty cool!  I didn't realize that you could do that (break the format string up over multiple lines).  I tried that and it worked fine.  The one thing that was odd about it is that, by default, pressing ENTER for ach place in the message where I want a newline, enters tabs on the front of the new line (to keep it lined up with the start of the string I guess).  So, I had to explicitly remove the tabs, thus forcing each subsequent line all the way to the left.  That is probably ok and, arguably, might be easier than explicitly adding a token for each newline.

Having said that, this idea just occurred to me...  With the ability to define combined tokens, if there were a newline token, one could define a format string without explicitly adding newline tokens in the string and without explicitly breaking the formatting string over multipel lines.

For example (syntax might not be 100% correct, but you get the idea):

      <token name="NL"
             type="Ukadc.Diagnostics.Extensions.NewLineToken, Ukadc.Diagnostics.Extensions">
      </token>
      <token name="LEMessage"
             type="Ukadc.Diagnostics.Extensions.LogEntryMessagePropertyReader, Ukadc.Diagnostics.Extensions">
      </token>
      <token name="LEMessageNL"
             format="{LEMessage}{NL}">
      </token>


Then, in the formatting statement, you could reference MessageNL to output the message field, followed by a newline.  So, your formatting like might look like this (to output fields, each a separate line):

      <token name="DebugFormatMultiline"
             format ="***************************{NL}DateTime: {DateTimeLocalNL:MM/dd/yyyy HH:mm:ss.ffff}Timestamp: {TimestampNL}ElapsedTime: {ElapsedTimeNL}ProcessId: {ProcessIdNL}LoggerName: {LoggerNameNL}TraceEventType: {TraceEventTypeNL}Message: {MessageNL}***************************{NL}">
      </token>

Is this better than explicitly entering the newlines in the formatting string?  I don't know.  I don't know if such usage would common enough or useful enough to go the effort of adding the token.  However, for an additional level of consistency with platforms like log4net and NLog (and maybe LAB?  I'm not sure), it might just be worth it to have a newline token so creating multiline output is more obvious (and explicit).

I saw in response to an earlier posting (in October 2009, in response to broec/Christian Broennimann) that you were considering adding support for calling static methods.  If that were the case, I suppose it would be easy enough for someone to define a token that would invoke Environment.Newline without actually having to develop a property reader for that purpose.

Thanks for your time.  Ultimately, I don't know that I even need to allow multiline logging output.  If so, I could use my own "NewlinePropertyReader" or I could explicitly enter the newlines in the app.config file.  It seems like it would be  reasonable addition to Ukadc.Diagnostics, but not to the detriment of anything "more important" that you might be planning on adding.

Thanks again for the library.

Sep 1, 2010 at 4:56 PM

No probs – interesting stuff.

J

From: wageoghe [mailto:notifications@codeplex.com]
Sent: 01 September 2010 16:24
To: Josh Twist
Subject: Re: Control characters in format string [UkadcDiagnostics:225640]

From: wageoghe

That's pretty cool! I didn't realize that you could do that (break the format string up over multiple lines). I tried that and it worked fine. The one thing that was odd about it is that, by default, pressing ENTER for ach place in the message where I want a newline, enters tabs on the front of the new line (to keep it lined up with the start of the string I guess). So, I had to explicitly remove the tabs, thus forcing each subsequent line all the way to the left. That is probably ok and, arguably, might be easier than explicitly adding a token for each newline.

Having said that, this idea just occurred to me... With the ability to define combined tokens, if there were a newline token, one could define a format string without explicitly adding newline tokens in the string and without explicitly breaking the formatting string over multipel lines.

For example (syntax might not be 100% correct, but you get the idea):

      <token name="NL"
             type="Ukadc.Diagnostics.Extensions.NewLineToken, Ukadc.Diagnostics.Extensions">
      </token>
      <token name="LEMessage"
             type="Ukadc.Diagnostics.Extensions.LogEntryMessagePropertyReader, Ukadc.Diagnostics.Extensions">
      </token>
      <token name="LEMessageNL"
             format="{LEMessage}{NL}">
      </token>
 
 

Then, in the formatting statement, you could reference MessageNL to output the message field, followed by a newline. So, your formatting like might look like this (to output fields, each a separate line):

      <token name="DebugFormatMultiline"
             format ="***************************{NL}DateTime: {DateTimeLocalNL:MM/dd/yyyy HH:mm:ss.ffff}Timestamp: {TimestampNL}ElapsedTime: {ElapsedTimeNL}ProcessId: {ProcessIdNL}LoggerName: {LoggerNameNL}TraceEventType: {TraceEventTypeNL}Message: {MessageNL}***************************{NL}">
      </token>
 

Is this better than explicitly entering the newlines in the formatting string? I don't know. I don't know if such usage would common enough or useful enough to go the effort of adding the token. However, for an additional level of consistency with platforms like log4net and NLog (and maybe LAB? I'm not sure), it might just be worth it to have a newline token so creating multiline output is more obvious (and explicit).

I saw in response to an earlier posting (in October 2009, in response to broec/Christian Broennimann) that you were considering adding support for calling static methods. If that were the case, I suppose it would be easy enough for someone to define a token that would invoke Environment.Newline without actually having to develop a property reader for that purpose.

Thanks for your time. Ultimately, I don't know that I even need to allow multiline logging output. If so, I could use my own "NewlinePropertyReader" or I could explicitly enter the newlines in the app.config file. It seems like it would be reasonable addition to Ukadc.Diagnostics, but not to the detriment of anything "more important" that you might be planning on adding.

Thanks again for the library.

Read the full discussion online.

To add a post to this discussion, reply to this email (UkadcDiagnostics@discussions.codeplex.com)

To start a new discussion for this project, email UkadcDiagnostics@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com