DiskLogListener.cs 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. using System.Collections.Generic;
  2. using System.IO;
  3. using System.Text;
  4. using System.Threading;
  5. namespace BepInEx.Logging
  6. {
  7. /// <summary>
  8. /// Logs entries using Unity specific outputs.
  9. /// </summary>
  10. public class DiskLogListener : ILogListener
  11. {
  12. /// <summary>
  13. /// Log levels to display.
  14. /// </summary>
  15. public LogLevel DisplayedLogLevel { get; set; }
  16. /// <summary>
  17. /// Writer for the disk log.
  18. /// </summary>
  19. public TextWriter LogWriter { get; protected set; }
  20. /// <summary>
  21. /// Timer for flushing the logs to a file.
  22. /// </summary>
  23. public Timer FlushTimer { get; protected set; }
  24. /// <summary>
  25. /// Creates a new disk log listener.
  26. /// </summary>
  27. /// <param name="localPath">Path to the log.</param>
  28. /// <param name="displayedLogLevel">Log levels to display.</param>
  29. /// <param name="appendLog">Whether to append logs to an already existing log file.</param>
  30. public DiskLogListener(string localPath, LogLevel displayedLogLevel = LogLevel.Info, bool appendLog = false)
  31. {
  32. DisplayedLogLevel = displayedLogLevel;
  33. int counter = 1;
  34. FileStream fileStream;
  35. while (!Utility.TryOpenFileStream(Path.Combine(Paths.BepInExRootPath, localPath), appendLog ? FileMode.Append : FileMode.Create, out fileStream, share: FileShare.Read, access: FileAccess.Write))
  36. {
  37. if (counter == 5)
  38. {
  39. Logger.LogError("Couldn't open a log file for writing. Skipping log file creation");
  40. return;
  41. }
  42. Logger.LogWarning($"Couldn't open log file '{localPath}' for writing, trying another...");
  43. localPath = $"LogOutput.log.{counter++}";
  44. }
  45. LogWriter = TextWriter.Synchronized(new StreamWriter(fileStream, Encoding.UTF8));
  46. FlushTimer = new Timer(o => { LogWriter?.Flush(); }, null, 2000, 2000);
  47. }
  48. public static HashSet<string> BlacklistedSources = new HashSet<string>();
  49. /// <inheritdoc />
  50. public void LogEvent(object sender, LogEventArgs eventArgs)
  51. {
  52. if (BlacklistedSources.Contains(eventArgs.Source.SourceName))
  53. return;
  54. if ((eventArgs.Level & DisplayedLogLevel) == 0)
  55. return;
  56. LogWriter.WriteLine(eventArgs.ToString());
  57. }
  58. /// <inheritdoc />
  59. public void Dispose()
  60. {
  61. FlushTimer?.Dispose();
  62. LogWriter?.Flush();
  63. LogWriter?.Dispose();
  64. }
  65. ~DiskLogListener()
  66. {
  67. Dispose();
  68. }
  69. }
  70. }