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

Logging.cs 6.0 kB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. using System;
  2. using System.IO;
  3. using System.Net.Sockets;
  4. using System.Net;
  5. using Shadowsocks.Util;
  6. namespace Shadowsocks.Controller
  7. {
  8. public class Logging
  9. {
  10. public static string LogFilePath;
  11. private static DateTime LogFileCreationTime;
  12. public static bool OpenLogFile()
  13. {
  14. try
  15. {
  16. LogFilePath = Utils.GetTempPath("shadowsocks.log");
  17. if (!File.Exists(LogFilePath))
  18. using (File.Create(LogFilePath)) { }
  19. LogFileCreationTime = File.GetCreationTime(LogFilePath);
  20. if ((DateTime.Now - LogFileCreationTime).Days >= 1)
  21. RollLogFile();
  22. else
  23. {
  24. FileStream fs = new FileStream(LogFilePath, FileMode.Append);
  25. StreamWriterWithTimestamp sw = new StreamWriterWithTimestamp(fs);
  26. sw.AutoFlush = true;
  27. Console.SetOut(sw);
  28. Console.SetError(sw);
  29. }
  30. return true;
  31. }
  32. catch (IOException e)
  33. {
  34. Console.WriteLine(e.ToString());
  35. return false;
  36. }
  37. }
  38. private static void RollLogFile()
  39. {
  40. Console.Out.Close();
  41. Console.Error.Close();
  42. MemoryStream ms = new MemoryStream();
  43. StreamWriterWithTimestamp sw = new StreamWriterWithTimestamp(ms);
  44. sw.AutoFlush = true;
  45. Console.SetOut(sw);
  46. Console.SetError(sw);
  47. byte[] logContents = File.ReadAllBytes(LogFilePath);
  48. string datestr = DateTime.Now.AddDays(-1).ToString("yyyyMMdd");
  49. string filepath = Utils.GetTempPath($"shadowsocks.{datestr}.log.zip");
  50. FileManager.CompressFile(filepath, logContents);
  51. File.Delete(LogFilePath);
  52. FileStream fs = new FileStream(LogFilePath, FileMode.CreateNew);
  53. LogFileCreationTime = DateTime.Now;
  54. ms.CopyTo(fs);
  55. StreamWriterWithTimestamp sw2 = new StreamWriterWithTimestamp(fs);
  56. sw2.AutoFlush = true;
  57. Console.SetOut(sw2);
  58. Console.SetError(sw2);
  59. }
  60. private static void WriteToLogFile(object o)
  61. {
  62. if ((DateTime.Now - LogFileCreationTime).Days >= 1)
  63. RollLogFile();
  64. Console.WriteLine(o);
  65. }
  66. public static void Error(object o)
  67. {
  68. WriteToLogFile("[E] " + o);
  69. }
  70. public static void Info(object o)
  71. {
  72. WriteToLogFile(o);
  73. }
  74. public static void Debug(object o)
  75. {
  76. #if DEBUG
  77. WriteToLogFile("[D] " + o);
  78. #endif
  79. }
  80. public static void Debug(EndPoint local, EndPoint remote, int len, string header = null, string tailer = null)
  81. {
  82. #if DEBUG
  83. if (header == null && tailer == null)
  84. Debug($"{local} => {remote} (size={len})");
  85. else if (header == null && tailer != null)
  86. Debug($"{local} => {remote} (size={len}), {tailer}");
  87. else if (header != null && tailer == null)
  88. Debug($"{header}: {local} => {remote} (size={len})");
  89. else
  90. Debug($"{header}: {local} => {remote} (size={len}), {tailer}");
  91. #endif
  92. }
  93. public static void Debug(Socket sock, int len, string header = null, string tailer = null)
  94. {
  95. #if DEBUG
  96. Debug(sock.LocalEndPoint, sock.RemoteEndPoint, len, header, tailer);
  97. #endif
  98. }
  99. public static void LogUsefulException(Exception e)
  100. {
  101. // just log useful exceptions, not all of them
  102. if (e is SocketException)
  103. {
  104. SocketException se = (SocketException)e;
  105. if (se.SocketErrorCode == SocketError.ConnectionAborted)
  106. {
  107. // closed by browser when sending
  108. // normally happens when download is canceled or a tab is closed before page is loaded
  109. }
  110. else if (se.SocketErrorCode == SocketError.ConnectionReset)
  111. {
  112. // received rst
  113. }
  114. else if (se.SocketErrorCode == SocketError.NotConnected)
  115. {
  116. // The application tried to send or receive data, and the System.Net.Sockets.Socket is not connected.
  117. }
  118. else if (se.SocketErrorCode == SocketError.HostUnreachable)
  119. {
  120. // There is no network route to the specified host.
  121. }
  122. else if (se.SocketErrorCode == SocketError.TimedOut)
  123. {
  124. // The connection attempt timed out, or the connected host has failed to respond.
  125. }
  126. else
  127. {
  128. Info(e);
  129. }
  130. }
  131. else if (e is ObjectDisposedException)
  132. {
  133. }
  134. else
  135. {
  136. Info(e);
  137. }
  138. }
  139. }
  140. // Simply extended System.IO.StreamWriter for adding timestamp workaround
  141. public class StreamWriterWithTimestamp : StreamWriter
  142. {
  143. public StreamWriterWithTimestamp(Stream stream) : base(stream)
  144. {
  145. }
  146. private string GetTimestamp()
  147. {
  148. return "[" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "] ";
  149. }
  150. public override void WriteLine(string value)
  151. {
  152. base.WriteLine(GetTimestamp() + value);
  153. }
  154. public override void Write(string value)
  155. {
  156. base.Write(GetTimestamp() + value);
  157. }
  158. }
  159. }