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.

LoggerExtension.cs 5.0 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. using Shadowsocks.Common.SystemProxy;
  2. using System;
  3. using System.ComponentModel;
  4. using System.Net;
  5. using System.Net.Sockets;
  6. namespace NLog
  7. {
  8. public static class LoggerExtension
  9. {
  10. // for key, iv, etc...
  11. public static void Dump(this Logger logger, string tag, ReadOnlySpan<byte> arr)
  12. {
  13. logger.Dump(tag, arr.ToArray(), arr.Length);
  14. }
  15. public static void Dump(this Logger logger, string tag, byte[] arr, int length = -1)
  16. {
  17. if (arr == null) logger.Trace($@"
  18. {tag}:
  19. (null)
  20. ");
  21. if (length == -1) length = arr.Length;
  22. if (!logger.IsTraceEnabled) return;
  23. string hex = BitConverter.ToString(arr.AsSpan(0, Math.Min(arr.Length, length)).ToArray()).Replace("-", "");
  24. string content = $@"
  25. {tag}:
  26. {hex}
  27. ";
  28. logger.Trace(content);
  29. }
  30. // for cipher and plain text, so we can use openssl to test
  31. public static void DumpBase64(this Logger logger, string tag, ReadOnlySpan<byte> arr)
  32. {
  33. logger.DumpBase64(tag, arr.ToArray(), arr.Length);
  34. }
  35. public static void DumpBase64(this Logger logger, string tag, byte[] arr, int length = -1)
  36. {
  37. if (arr == null) logger.Trace($@"
  38. {tag}:
  39. (null)
  40. ");
  41. if (length == -1) length = arr.Length;
  42. if (!logger.IsTraceEnabled) return;
  43. string hex = Convert.ToBase64String(arr.AsSpan(0, Math.Min(arr.Length, length)).ToArray());
  44. string content = $@"
  45. {tag}:
  46. {hex}
  47. ";
  48. logger.Trace(content);
  49. }
  50. public static void Debug(this Logger logger, EndPoint local, EndPoint remote, int len, string header = null, string tailer = null)
  51. {
  52. if (logger.IsDebugEnabled)
  53. {
  54. if (header == null && tailer == null)
  55. logger.Debug($"{local} => {remote} (size={len})");
  56. else if (header == null && tailer != null)
  57. logger.Debug($"{local} => {remote} (size={len}), {tailer}");
  58. else if (header != null && tailer == null)
  59. logger.Debug($"{header}: {local} => {remote} (size={len})");
  60. else
  61. logger.Debug($"{header}: {local} => {remote} (size={len}), {tailer}");
  62. }
  63. }
  64. public static void Debug(this Logger logger, Socket sock, int len, string header = null, string tailer = null)
  65. {
  66. if (logger.IsDebugEnabled)
  67. logger.Debug(sock.LocalEndPoint, sock.RemoteEndPoint, len, header, tailer);
  68. }
  69. public static void LogUsefulException(this Logger logger, Exception e)
  70. {
  71. // just log useful exceptions, not all of them
  72. if (e is SocketException se)
  73. {
  74. if (se.SocketErrorCode == SocketError.ConnectionAborted)
  75. {
  76. // closed by browser when sending
  77. // normally happens when download is canceled or a tab is closed before page is loaded
  78. }
  79. else if (se.SocketErrorCode == SocketError.ConnectionReset)
  80. {
  81. // received rst
  82. }
  83. else if (se.SocketErrorCode == SocketError.NotConnected)
  84. {
  85. // The application tried to send or receive data, and the System.Net.Sockets.Socket is not connected.
  86. }
  87. else if (se.SocketErrorCode == SocketError.HostUnreachable)
  88. {
  89. // There is no network route to the specified host.
  90. }
  91. else if (se.SocketErrorCode == SocketError.TimedOut)
  92. {
  93. // The connection attempt timed out, or the connected host has failed to respond.
  94. }
  95. else
  96. {
  97. logger.Warn(e);
  98. }
  99. }
  100. else if (e is ObjectDisposedException)
  101. {
  102. }
  103. else if (e is Win32Exception ex)
  104. {
  105. // Win32Exception (0x80004005): A 32 bit processes cannot access modules of a 64 bit process.
  106. if ((uint)ex.ErrorCode != 0x80004005)
  107. logger.Warn(e);
  108. }
  109. else if (e is ProxyException pe)
  110. {
  111. switch (pe.Type)
  112. {
  113. case ProxyExceptionType.FailToRun:
  114. case ProxyExceptionType.QueryReturnMalformed:
  115. case ProxyExceptionType.SysproxyExitError:
  116. logger.Error($"sysproxy - {pe.Type}:{pe.Message}");
  117. break;
  118. case ProxyExceptionType.QueryReturnEmpty:
  119. case ProxyExceptionType.Unspecific:
  120. logger.Error($"sysproxy - {pe.Type}");
  121. break;
  122. }
  123. }
  124. else
  125. {
  126. logger.Warn(e);
  127. }
  128. }
  129. }
  130. }