📄 ansicolorterminalappender.cs
字号:
/// <remarks>
/// <para>
/// Writes the event to the console.
/// </para>
/// <para>
/// The format of the output will depend on the appender's layout.
/// </para>
/// </remarks>
override protected void Append(log4net.Core.LoggingEvent loggingEvent)
{
string loggingMessage = RenderLoggingEvent(loggingEvent);
// see if there is a specified lookup.
LevelColors levelColors = m_levelMapping.Lookup(loggingEvent.Level) as LevelColors;
if (levelColors != null)
{
// Prepend the Ansi Color code
loggingMessage = levelColors.CombinedColor + loggingMessage;
}
// on most terminals there are weird effects if we don't clear the background color
// before the new line. This checks to see if it ends with a newline, and if
// so, inserts the clear codes before the newline, otherwise the clear codes
// are inserted afterwards.
if (loggingMessage.Length > 1)
{
if (loggingMessage.EndsWith("\r\n") || loggingMessage.EndsWith("\n\r"))
{
loggingMessage = loggingMessage.Insert(loggingMessage.Length - 2, PostEventCodes);
}
else if (loggingMessage.EndsWith("\n") || loggingMessage.EndsWith("\r"))
{
loggingMessage = loggingMessage.Insert(loggingMessage.Length - 1, PostEventCodes);
}
else
{
loggingMessage = loggingMessage + PostEventCodes;
}
}
else
{
if (loggingMessage[0] == '\n' || loggingMessage[0] == '\r')
{
loggingMessage = PostEventCodes + loggingMessage;
}
else
{
loggingMessage = loggingMessage + PostEventCodes;
}
}
#if NETCF
// Write to the output stream
Console.Write(loggingMessage);
#else
if (m_writeToErrorStream)
{
// Write to the error stream
Console.Error.Write(loggingMessage);
}
else
{
// Write to the output stream
Console.Write(loggingMessage);
}
#endif
}
/// <summary>
/// This appender requires a <see cref="Layout"/> to be set.
/// </summary>
/// <value><c>true</c></value>
/// <remarks>
/// <para>
/// This appender requires a <see cref="Layout"/> to be set.
/// </para>
/// </remarks>
override protected bool RequiresLayout
{
get { return true; }
}
/// <summary>
/// Initialize the options for this appender
/// </summary>
/// <remarks>
/// <para>
/// Initialize the level to color mappings set on this appender.
/// </para>
/// </remarks>
public override void ActivateOptions()
{
base.ActivateOptions();
m_levelMapping.ActivateOptions();
}
#endregion Override implementation of AppenderSkeleton
#region Public Static Fields
/// <summary>
/// The <see cref="AnsiColorTerminalAppender.Target"/> to use when writing to the Console
/// standard output stream.
/// </summary>
/// <remarks>
/// <para>
/// The <see cref="AnsiColorTerminalAppender.Target"/> to use when writing to the Console
/// standard output stream.
/// </para>
/// </remarks>
public const string ConsoleOut = "Console.Out";
/// <summary>
/// The <see cref="AnsiColorTerminalAppender.Target"/> to use when writing to the Console
/// standard error output stream.
/// </summary>
/// <remarks>
/// <para>
/// The <see cref="AnsiColorTerminalAppender.Target"/> to use when writing to the Console
/// standard error output stream.
/// </para>
/// </remarks>
public const string ConsoleError = "Console.Error";
#endregion Public Static Fields
#region Private Instances Fields
/// <summary>
/// Flag to write output to the error stream rather than the standard output stream
/// </summary>
private bool m_writeToErrorStream = false;
/// <summary>
/// Mapping from level object to color value
/// </summary>
private LevelMapping m_levelMapping = new LevelMapping();
/// <summary>
/// Ansi code to reset terminal
/// </summary>
private const string PostEventCodes = "\x1b[0m";
#endregion Private Instances Fields
#region LevelColors LevelMapping Entry
/// <summary>
/// A class to act as a mapping between the level that a logging call is made at and
/// the color it should be displayed as.
/// </summary>
/// <remarks>
/// <para>
/// Defines the mapping between a level and the color it should be displayed in.
/// </para>
/// </remarks>
public class LevelColors : LevelMappingEntry
{
private AnsiColor m_foreColor;
private AnsiColor m_backColor;
private AnsiAttributes m_attributes;
private string m_combinedColor = "";
/// <summary>
/// The mapped foreground color for the specified level
/// </summary>
/// <remarks>
/// <para>
/// Required property.
/// The mapped foreground color for the specified level
/// </para>
/// </remarks>
public AnsiColor ForeColor
{
get { return m_foreColor; }
set { m_foreColor = value; }
}
/// <summary>
/// The mapped background color for the specified level
/// </summary>
/// <remarks>
/// <para>
/// Required property.
/// The mapped background color for the specified level
/// </para>
/// </remarks>
public AnsiColor BackColor
{
get { return m_backColor; }
set { m_backColor = value; }
}
/// <summary>
/// The color attributes for the specified level
/// </summary>
/// <remarks>
/// <para>
/// Required property.
/// The color attributes for the specified level
/// </para>
/// </remarks>
public AnsiAttributes Attributes
{
get { return m_attributes; }
set { m_attributes = value; }
}
/// <summary>
/// Initialize the options for the object
/// </summary>
/// <remarks>
/// <para>
/// Combine the <see cref="ForeColor"/> and <see cref="BackColor"/> together
/// and append the attributes.
/// </para>
/// </remarks>
public override void ActivateOptions()
{
base.ActivateOptions();
StringBuilder buf = new StringBuilder();
// Reset any existing codes
buf.Append("\x1b[0;");
// set the foreground color
buf.Append(30 + (int)m_foreColor);
buf.Append(';');
// set the background color
buf.Append(40 + (int)m_backColor);
// set the attributes
if ((m_attributes & AnsiAttributes.Bright) > 0)
{
buf.Append(";1");
}
if ((m_attributes & AnsiAttributes.Dim) > 0)
{
buf.Append(";2");
}
if ((m_attributes & AnsiAttributes.Underscore) > 0)
{
buf.Append(";4");
}
if ((m_attributes & AnsiAttributes.Blink) > 0)
{
buf.Append(";5");
}
if ((m_attributes & AnsiAttributes.Reverse) > 0)
{
buf.Append(";7");
}
if ((m_attributes & AnsiAttributes.Hidden) > 0)
{
buf.Append(";8");
}
if ((m_attributes & AnsiAttributes.Strikethrough) > 0)
{
buf.Append(";9");
}
buf.Append('m');
m_combinedColor = buf.ToString();
}
/// <summary>
/// The combined <see cref="ForeColor"/>, <see cref="BackColor"/> and
/// <see cref="Attributes"/> suitable for setting the ansi terminal color.
/// </summary>
internal string CombinedColor
{
get { return m_combinedColor; }
}
}
#endregion // LevelColors LevelMapping Entry
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -