Format Log File

In almost all projects we have to implement some kind of logging mechanism which facilitates us in finding the root cause of the issue and application health. However generally I believe that log files are not properly formatted due to which we need to spend more time in understanding our log files.

So, finally I have written a small class to format complex object into well formatted log file. Also it uses word wrap on columns of log to ensure readable format. Here is how log files look before:-


And here is how log look after properly formatted:-

Here is code which I used to format my log:-

   1:      public class LogFormatter 
   2:      {
   3:          private static string DefaultNameSpace = ConfigurationManager.AppSettings["Log.DefaultNameSpace"];
   4:          /// <summary>
   5:          /// Formats the object as string.
   6:          /// </summary>
   7:          /// <param name="obj">The obj.</param>
   8:          /// <returns></returns>
   9:          private static string FormatTypeAsString(object obj)
  10:          {
  11:              StringBuilder sb = new StringBuilder(1024);
  12:   
  13:              if (obj is string || obj is Exception || obj is DbCommand || obj is DateTime || obj is TimeSpan || obj == null)
  14:              {
  15:   
  16:              }
  17:              else
  18:              {
  19:                  sb.Append("[Type:" + obj.GetType().ToString() + "]");
  20:              }
  21:   
  22:              if (obj == null)
  23:              {
  24:                  sb.Append("Value: Null");
  25:              }
  26:              else if (obj is string)
  27:              {
  28:                  sb.Append((string)obj);
  29:              }
  30:              else if (obj is DateTime)
  31:              {
  32:                  sb.Append(((DateTime)obj).ToString("dd-MMM-yyyy hh:mm:ss tt"));
  33:              }
  34:              else if (obj is TimeSpan)
  35:              {
  36:                  sb.Append(((TimeSpan)obj).FormatAsString());
  37:              }
  38:              else if (obj is DbCommand)
  39:              {
  40:                  DbCommand cmd = (DbCommand)obj;
  41:                  string commandDetail = string.Empty;
  42:                  commandDetail = cmd.CommandType.ToString();
  43:   
  44:                  if (cmd.Connection != null)
  45:                  {
  46:                      commandDetail += "(" + cmd.Connection.DataSource + ")";
  47:                  }
  48:   
  49:                  sb.Append(" CommandText=[" + cmd.CommandText + "] CommandDetail=[" + commandDetail + "] Parameters= [");
  50:   
  51:                  foreach (DbParameter param in cmd.Parameters)
  52:                  {
  53:                      string paramValue = "null";
  54:                      if (param.Value != null)
  55:                      {
  56:                          paramValue = param.Value.ToString();
  57:                      }
  58:   
  59:                      sb.Append("@" + param.ParameterName + "=" + paramValue + " ");
  60:                  }
  61:                  sb.Append("]");
  62:              }
  63:              else if (obj is Exception)
  64:              {
  65:                  sb.Append(" Exception=[" + obj.ToString().Replace("\r", "").Replace("\n", "\t") + "] Details=[" +
  66:                  ((Exception)obj).StackTrace.Replace("\r", "").Replace("\n", "\t") + "]");
  67:              }
  68:              else
  69:              {
  70:                  var type = obj.GetType();
  71:   
  72:                  foreach (var prop in type.GetProperties())
  73:                  {
  74:                      var val = prop.GetValue(obj, new object[] { });
  75:   
  76:                      var valStr = string.Empty;
  77:                      if (val != null)
  78:                      {
  79:                          if (prop.PropertyType == typeof(DateTime))
  80:                          {
  81:                              valStr = ((DateTime)val).ToString("dd-MMM-yyyy hh:mm:ss tt");
  82:                          }
  83:                          else if (prop.PropertyType == typeof(TimeSpan))
  84:                          {
  85:                              valStr = ((TimeSpan)val).FormatAsString();
  86:                          }
  87:                          else
  88:                          {
  89:                              valStr = val.ToString();
  90:                          }
  91:                          sb.Append("[" + prop.Name + ":" + valStr + "]");
  92:                      }
  93:                  }
  94:              }
  95:              return sb.ToString();
  96:          }
  97:   
  98:          /// <summary>
  99:          /// Formats the log.
 100:          /// </summary>
 101:          /// <param name="eventName">Name of the event.</param>
 102:          /// <param name="details">The details.</param>
 103:          /// <returns></returns>
 104:          public string FormatLog(string eventName, object details, DateTime logDate)
 105:          {
 106:              int eventLength = 30;
 107:              int methodLength = 60;
 108:              int typeDetailLength = 80;
 109:              List<string> eventList = WordWrap(eventName, eventLength);
 110:              List<string> methodList = WordWrap(GetMethodNameFromStackTrace(), methodLength);
 111:              List<string> typeDetailList = WordWrap(FormatTypeAsString(details), typeDetailLength);
 112:   
 113:              StringBuilder sb = new StringBuilder();
 114:   
 115:              int maxCount = eventList.Count;
 116:              if (methodList.Count > maxCount)
 117:              {
 118:                  maxCount = methodList.Count;
 119:              }
 120:              else if (typeDetailList.Count > maxCount)
 121:              {
 122:                  maxCount = typeDetailList.Count;
 123:              }
 124:   
 125:              for (int i = 0; i < maxCount; i++)
 126:              {
 127:                  sb.Append("\r\n");
 128:   
 129:                  string line = string.Format("{0,-23}|{1,-" + eventLength + "}|{2,-" + methodLength + "}|{3,-" + typeDetailLength + "}|",
 130:                      (i == 0) ? logDate.ToString("dd-MMM-yyy hh:mm:ss tt") : string.Empty,
 131:                      GetValueFromList(eventLength, eventList, i),
 132:                      GetValueFromList(methodLength, methodList, i),
 133:                      GetValueFromList(typeDetailLength, typeDetailList, i));
 134:   
 135:                  sb.Append(line);
 136:              }
 137:   
 138:              return sb.ToString();
 139:          }
 140:   
 141:          /// <summary>
 142:          /// Gets the value from list.
 143:          /// </summary>
 144:          /// <param name="maxLength">Length of the max.</param>
 145:          /// <param name="list">The list.</param>
 146:          /// <param name="index">The index.</param>
 147:          /// <returns></returns>
 148:          private string GetValueFromList(int maxLength, List<string> list, int index)
 149:          {
 150:              string result = string.Empty;
 151:              if (index < list.Count)
 152:              {
 153:                  result = list[index];
 154:              }
 155:              else
 156:              {
 157:                  result = new string(' ', maxLength);
 158:              }
 159:              return result;
 160:          }
 161:   
 162:          /// <summary>
 163:          /// Words the wrap.
 164:          /// </summary>
 165:          /// <param name="text">The text.</param>
 166:          /// <param name="width">The width.</param>
 167:          /// <returns></returns>
 168:          private List<string> WordWrap(string text, int width)
 169:          {
 170:              List<string> list = new List<string>();
 171:              StringBuilder sb = new StringBuilder();
 172:   
 173:              if (text.Length < width)
 174:              {
 175:                  list.Add(text);
 176:              }
 177:              else
 178:              {
 179:   
 180:                  for (int i = 0; i < text.Length; i++)
 181:                  {
 182:                      if (i % width == 0 && i != 0)
 183:                      {
 184:                          list.Add(sb.ToString());
 185:                          sb = new StringBuilder();
 186:                      }
 187:   
 188:                      sb.Append(text[i]);
 189:                  }
 190:                  list.Add(sb.ToString());
 191:              }
 192:              return list;
 193:          }
 194:   
 195:          /// <summary>
 196:          /// Gets the name of the method from StackTrace.
 197:          /// </summary>
 198:          /// <returns></returns>
 199:          private string GetMethodNameFromStackTrace()
 200:          {
 201:              try
 202:              {
 203:                  var method = new StackFrame(4, true).GetMethod();
 204:                  string methodName = method.DeclaringType.ToString() + "." + method.Name + "()";
 205:                  methodName = methodName.Replace(DefaultNameSpace, "");
 206:                  return methodName;
 207:              }
 208:              catch //(Exception ex)
 209:              {
 210:                  //Suppress Exception
 211:              }
 212:              return string.Empty;
 213:          }
 214:      }

Happy Coding !!!