StackTracePatternConverter.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #region Apache License
  2. //
  3. // Licensed to the Apache Software Foundation (ASF) under one or more
  4. // contributor license agreements. See the NOTICE file distributed with
  5. // this work for additional information regarding copyright ownership.
  6. // The ASF licenses this file to you under the Apache License, Version 2.0
  7. // (the "License"); you may not use this file except in compliance with
  8. // the License. You may obtain a copy of the License at
  9. //
  10. // http://www.apache.org/licenses/LICENSE-2.0
  11. //
  12. // Unless required by applicable law or agreed to in writing, software
  13. // distributed under the License is distributed on an "AS IS" BASIS,
  14. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. // See the License for the specific language governing permissions and
  16. // limitations under the License.
  17. //
  18. #endregion
  19. #if !NETCF
  20. using System;
  21. using System.IO;
  22. using System.Diagnostics;
  23. using log4net.Util;
  24. using log4net.Core;
  25. namespace log4net.Layout.Pattern
  26. {
  27. /// <summary>
  28. /// Write the caller stack frames to the output
  29. /// </summary>
  30. /// <remarks>
  31. /// <para>
  32. /// Writes the <see cref="LocationInfo.StackFrames"/> to the output writer, using format:
  33. /// type3.MethodCall3 > type2.MethodCall2 > type1.MethodCall1
  34. /// </para>
  35. /// </remarks>
  36. /// <author>Michael Cromwell</author>
  37. internal class StackTracePatternConverter : PatternLayoutConverter, IOptionHandler
  38. {
  39. private int m_stackFrameLevel = 1;
  40. /// <summary>
  41. /// Initialize the converter
  42. /// </summary>
  43. /// <remarks>
  44. /// <para>
  45. /// This is part of the <see cref="IOptionHandler"/> delayed object
  46. /// activation scheme. The <see cref="ActivateOptions"/> method must
  47. /// be called on this object after the configuration properties have
  48. /// been set. Until <see cref="ActivateOptions"/> is called this
  49. /// object is in an undefined state and must not be used.
  50. /// </para>
  51. /// <para>
  52. /// If any of the configuration properties are modified then
  53. /// <see cref="ActivateOptions"/> must be called again.
  54. /// </para>
  55. /// </remarks>
  56. public void ActivateOptions()
  57. {
  58. if (Option == null)
  59. return;
  60. string optStr = Option.Trim();
  61. if (optStr.Length != 0)
  62. {
  63. int stackLevelVal;
  64. if (SystemInfo.TryParse(optStr, out stackLevelVal))
  65. {
  66. if (stackLevelVal <= 0)
  67. {
  68. LogLog.Error(declaringType, "StackTracePatternConverter: StackeFrameLevel option (" + optStr + ") isn't a positive integer.");
  69. }
  70. else
  71. {
  72. m_stackFrameLevel = stackLevelVal;
  73. }
  74. }
  75. else
  76. {
  77. LogLog.Error(declaringType, "StackTracePatternConverter: StackFrameLevel option \"" + optStr + "\" not a decimal integer.");
  78. }
  79. }
  80. }
  81. /// <summary>
  82. /// Write the strack frames to the output
  83. /// </summary>
  84. /// <param name="writer"><see cref="TextWriter" /> that will receive the formatted result.</param>
  85. /// <param name="loggingEvent">the event being logged</param>
  86. /// <remarks>
  87. /// <para>
  88. /// Writes the <see cref="LocationInfo.StackFrames"/> to the output writer.
  89. /// </para>
  90. /// </remarks>
  91. override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
  92. {
  93. StackFrameItem[] stackframes = loggingEvent.LocationInformation.StackFrames;
  94. if ((stackframes == null) || (stackframes.Length <= 0))
  95. {
  96. LogLog.Error(declaringType, "loggingEvent.LocationInformation.StackFrames was null or empty.");
  97. return;
  98. }
  99. int stackFrameIndex = m_stackFrameLevel - 1;
  100. while (stackFrameIndex >= 0)
  101. {
  102. if (stackFrameIndex >= stackframes.Length)
  103. {
  104. stackFrameIndex--;
  105. continue;
  106. }
  107. StackFrameItem stackFrame = stackframes[stackFrameIndex];
  108. writer.Write("{0}.{1}", stackFrame.ClassName, GetMethodInformation(stackFrame.Method));
  109. if (stackFrameIndex > 0)
  110. {
  111. // TODO: make this user settable?
  112. writer.Write(" > ");
  113. }
  114. stackFrameIndex--;
  115. }
  116. }
  117. /// <summary>
  118. /// Returns the Name of the method
  119. /// </summary>
  120. /// <param name="method"></param>
  121. /// <remarks>This method was created, so this class could be used as a base class for StackTraceDetailPatternConverter</remarks>
  122. /// <returns>string</returns>
  123. internal virtual string GetMethodInformation(MethodItem method)
  124. {
  125. return method.Name;
  126. }
  127. #region Private Static Fields
  128. /// <summary>
  129. /// The fully qualified type of the StackTracePatternConverter class.
  130. /// </summary>
  131. /// <remarks>
  132. /// Used by the internal logger to record the Type of the
  133. /// log message.
  134. /// </remarks>
  135. private readonly static Type declaringType = typeof(StackTracePatternConverter);
  136. #endregion Private Static Fields
  137. }
  138. }
  139. #endif