ConsoleLog.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. using Ryujinx.Common.Logging;
  2. using System;
  3. using System.Collections.Concurrent;
  4. using System.Collections.Generic;
  5. using System.Reflection;
  6. using System.Text;
  7. using System.Threading;
  8. namespace Ryujinx
  9. {
  10. static class ConsoleLog
  11. {
  12. private static Thread _messageThread;
  13. private static BlockingCollection<LogEventArgs> _messageQueue;
  14. private static Dictionary<LogLevel, ConsoleColor> _logColors;
  15. static ConsoleLog()
  16. {
  17. _logColors = new Dictionary<LogLevel, ConsoleColor>()
  18. {
  19. { LogLevel.Stub, ConsoleColor.DarkGray },
  20. { LogLevel.Info, ConsoleColor.White },
  21. { LogLevel.Warning, ConsoleColor.Yellow },
  22. { LogLevel.Error, ConsoleColor.Red }
  23. };
  24. _messageQueue = new BlockingCollection<LogEventArgs>(10);
  25. _messageThread = new Thread(() =>
  26. {
  27. while (!_messageQueue.IsCompleted)
  28. {
  29. try
  30. {
  31. PrintLog(_messageQueue.Take());
  32. }
  33. catch (InvalidOperationException)
  34. {
  35. // IOE means that Take() was called on a completed collection.
  36. // Some other thread can call CompleteAdding after we pass the
  37. // IsCompleted check but before we call Take.
  38. // We can simply catch the exception since the loop will break
  39. // on the next iteration.
  40. }
  41. }
  42. });
  43. _messageThread.IsBackground = true;
  44. _messageThread.Start();
  45. }
  46. private static void PrintLog(LogEventArgs e)
  47. {
  48. StringBuilder sb = new StringBuilder();
  49. sb.AppendFormat(@"{0:hh\:mm\:ss\.fff}", e.Time);
  50. sb.Append(" | ");
  51. sb.AppendFormat("{0:d4}", e.ThreadId);
  52. sb.Append(' ');
  53. sb.Append(e.Message);
  54. if (e.Data != null)
  55. {
  56. PropertyInfo[] props = e.Data.GetType().GetProperties();
  57. sb.Append(' ');
  58. foreach (var prop in props)
  59. {
  60. sb.Append(prop.Name);
  61. sb.Append(": ");
  62. sb.Append(prop.GetValue(e.Data));
  63. sb.Append(" - ");
  64. }
  65. // We remove the final '-' from the string
  66. if (props.Length > 0)
  67. {
  68. sb.Remove(sb.Length - 3, 3);
  69. }
  70. }
  71. if (_logColors.TryGetValue(e.Level, out ConsoleColor color))
  72. {
  73. Console.ForegroundColor = color;
  74. Console.WriteLine(sb.ToString());
  75. Console.ResetColor();
  76. }
  77. else
  78. {
  79. Console.WriteLine(sb.ToString());
  80. }
  81. }
  82. public static void Log(object sender, LogEventArgs e)
  83. {
  84. if (!_messageQueue.IsAddingCompleted)
  85. {
  86. _messageQueue.Add(e);
  87. }
  88. }
  89. }
  90. }