private static void OnMessageLogged(string message, LogLevel level, LogType type, DateTime time, string fullmessage) => MessageLogged?.Invoke(message, level, type, time, fullmessage);
private static void Log(LogLevel level, LogType type, string message, ConsoleColor fg = ConsoleColor.Gray, ConsoleColor bg = ConsoleColor.Black, params object[] args) { try { // Prevent messages from appearing messed up due to Write calls being out of order. lock (locker) { // Replace variables. var str = LogFormat.Replace("%timestamp", GetTimestamp()) .Replace("%level", new string(' ', levelColumnLength - level.ToString().Length) + level); if (type == LogType.None) str = str.Remove(str.IndexOf("%type", StringComparison.Ordinal) + "%type".Length, 2); str = str.Replace("%type", type.ToString()); var msgIndex = str.IndexOf("%message", StringComparison.Ordinal); str = str.Replace("%message", string.Format(message, args)); var colors = str.Split('@'); // Reset console line. Console.ForegroundColor = fg; Console.BackgroundColor = bg; FixBuffer(); Console.CursorLeft = 0; // For each color string, change the console color and write the text. for (var i = 0; i < colors.Length; i++) { var colorStr = colors[i]; if (string.IsNullOrWhiteSpace(colorStr)) continue; var color = FromHex(colorStr, fg, bg, level, type); Console.ForegroundColor = color.Item1; Console.BackgroundColor = color.Item2; if (i == colors.Length - 1) Console.WriteLine(colorStr.Substring(2)); else Console.Write(colorStr.Substring(2)); Console.ForegroundColor = fg; Console.BackgroundColor = bg; } Console.ForegroundColor = ConsoleColor.Gray; Console.BackgroundColor = ConsoleColor.Black; var msg = str.Substring(msgIndex); var fullmsg = string.Join("", colors.Select(x => x.Substring(Math.Min(x.Length, 2)))); OnMessageLogged(msg, level, type, DateTime.Now, fullmsg); } } catch (Exception e) { Console.CursorTop = 0; Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Error logging message: " + e); Console.ForegroundColor = ConsoleColor.Gray; } }
private static Tuple<ConsoleColor, ConsoleColor> FromHex(string colorStr, ConsoleColor fg, ConsoleColor bg, LogLevel level, LogType type) { // First 2 characters of segment contain color hex code: var hex = colorStr.Substring(0, 2); switch (hex) { // Special codes begin with an X. case "XL": return new Tuple<ConsoleColor, ConsoleColor>(level.FG, level.BG); case "XT": return new Tuple<ConsoleColor, ConsoleColor>(type.FG, type.BG); case "XR": return new Tuple<ConsoleColor, ConsoleColor>(fg, bg); default: // Parse regular hex codes. return new Tuple<ConsoleColor, ConsoleColor>( (ConsoleColor) int.Parse(hex[1].ToString(), NumberStyles.HexNumber), (ConsoleColor) int.Parse(hex[0].ToString(), NumberStyles.HexNumber)); } }
/// <summary> /// Log a message with the specified type. /// See https://www.pyratron.com/assets/consolehex.png for hex codes that can be used in the message. /// </summary> public static void Log(LogType type, string message, params object[] args) => Info(type, message, args);
/// <summary> /// Log a message with the specified type and color. /// See https://www.pyratron.com/assets/consolehex.png for hex codes that can be used in the message. /// </summary> public static void Log(LogType type, ConsoleColor fg, string message, params object[] args) => Log(LogLevel.Info, type, message, fg, ConsoleColor.Black, args);
public static void Trace(LogType type, string message, params object[] args) => Log(LogLevel.Trace, type, message, args);
/// <summary> /// Log a message with the specified level, type, and color. /// See https://www.pyratron.com/assets/consolehex.png for hex codes that can be used in the message. /// </summary> public static void Log(LogLevel level, LogType type, ConsoleColor color, string message, params object[] args) => Log(level, type, message, color, ConsoleColor.Black, args);
public static void Debug(LogType type, string message, params object[] args) => Log(LogLevel.Debug, type, message, args);
public static void Info(LogType type, string message, params object[] args) => Log(LogLevel.Info, type, message, args);
public static void Warn(LogType type, string message, params object[] args) => Log(LogLevel.Warn, type, message, args);
public static void Error(LogType type, string message, params object[] args) => Log(LogLevel.Error, type, message, args);
public static void Fatal(LogType type, string message, params object[] args) => Log(LogLevel.Fatal, type, message, args);