You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

108 lines
3.4 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. using IPA.Logging;
  2. using Ionic.Zlib;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Runtime.InteropServices;
  8. using System.Text;
  9. using System.Threading.Tasks;
  10. namespace IPA.Logging.Printers
  11. {
  12. /// <summary>
  13. /// A <see cref="LogPrinter"/> abstract class that provides the utilities to write to a GZip file.
  14. /// </summary>
  15. public abstract class GZFilePrinter : LogPrinter
  16. {
  17. [DllImport("Kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
  18. static extern bool CreateHardLink(
  19. string lpFileName,
  20. string lpExistingFileName,
  21. IntPtr lpSecurityAttributes
  22. );
  23. [DllImport("Kernel32.dll")]
  24. static extern int GetLastError();
  25. private FileInfo fileInfo;
  26. /// <summary>
  27. /// The <see cref="StreamWriter"/> that writes to the GZip file.
  28. /// </summary>
  29. protected StreamWriter fileWriter;
  30. private GZipStream zstream;
  31. private FileStream fstream;
  32. /// <summary>
  33. /// Gets the <see cref="FileInfo"/> for the file to write to without the .gz extension.
  34. /// </summary>
  35. /// <returns></returns>
  36. protected abstract FileInfo GetFileInfo();
  37. private void InitLog()
  38. {
  39. try
  40. {
  41. if (fileInfo == null)
  42. { // first init
  43. fileInfo = GetFileInfo();
  44. var ext = fileInfo.Extension;
  45. fileInfo = new FileInfo(fileInfo.FullName + ".gz");
  46. fileInfo.Create().Close();
  47. var symlink = new FileInfo(Path.Combine(fileInfo.DirectoryName, $"latest{ext}.gz"));
  48. if (symlink.Exists) symlink.Delete();
  49. try
  50. {
  51. if (!CreateHardLink(symlink.FullName, fileInfo.FullName, IntPtr.Zero))
  52. {
  53. Logger.log.Error($"Hardlink creation failed {GetLastError()}");
  54. }
  55. }
  56. catch (Exception e)
  57. {
  58. Logger.log.Error("Error creating latest hardlink!");
  59. Logger.log.Error(e);
  60. }
  61. }
  62. }
  63. catch (Exception e)
  64. {
  65. Logger.log.Error("Error initializing log!");
  66. Logger.log.Error(e);
  67. }
  68. }
  69. /// <summary>
  70. /// Called at the start of any print session.
  71. /// </summary>
  72. public override sealed void StartPrint()
  73. {
  74. InitLog();
  75. fstream = fileInfo.Open(FileMode.Append, FileAccess.Write);
  76. zstream = new GZipStream(fstream, CompressionMode.Compress)
  77. {
  78. FlushMode = FlushType.Full
  79. };
  80. fileWriter = new StreamWriter(zstream, new UTF8Encoding(false));
  81. }
  82. /// <summary>
  83. /// Called at the end of any print session.
  84. /// </summary>
  85. public override sealed void EndPrint()
  86. {
  87. fileWriter.Flush();
  88. zstream.Flush();
  89. fstream.Flush();
  90. fileWriter.Close();
  91. zstream.Close();
  92. fstream.Close();
  93. fileWriter.Dispose();
  94. zstream.Dispose();
  95. fstream.Dispose();
  96. }
  97. }
  98. }