using System; using System.ComponentModel; using System.IO; using System.Net.Sockets; using System.Net; using System.Diagnostics; using System.Text; using Shadowsocks.Util.SystemProxy; namespace NLog { public static class LoggerExtension { public static void Dump(this Logger logger, string tag, byte[] arr, int length) { if (logger.IsTraceEnabled) { var sb = new StringBuilder($"{Environment.NewLine}{tag}: "); for (int i = 0; i < length - 1; i++) { sb.Append($"0x{arr[i]:X2}, "); } sb.Append($"0x{arr[length - 1]:X2}"); sb.Append(Environment.NewLine); logger.Trace(sb.ToString()); } } public static void Debug(this Logger logger, EndPoint local, EndPoint remote, int len, string header = null, string tailer = null) { if (logger.IsDebugEnabled) { if (header == null && tailer == null) logger.Debug($"{local} => {remote} (size={len})"); else if (header == null && tailer != null) logger.Debug($"{local} => {remote} (size={len}), {tailer}"); else if (header != null && tailer == null) logger.Debug($"{header}: {local} => {remote} (size={len})"); else logger.Debug($"{header}: {local} => {remote} (size={len}), {tailer}"); } } public static void Debug(this Logger logger, Socket sock, int len, string header = null, string tailer = null) { if (logger.IsDebugEnabled) { logger.Debug(sock.LocalEndPoint, sock.RemoteEndPoint, len, header, tailer); } } public static void LogUsefulException(this Logger logger, Exception e) { // just log useful exceptions, not all of them if (e is SocketException) { SocketException se = (SocketException)e; if (se.SocketErrorCode == SocketError.ConnectionAborted) { // closed by browser when sending // normally happens when download is canceled or a tab is closed before page is loaded } else if (se.SocketErrorCode == SocketError.ConnectionReset) { // received rst } else if (se.SocketErrorCode == SocketError.NotConnected) { // The application tried to send or receive data, and the System.Net.Sockets.Socket is not connected. } else if (se.SocketErrorCode == SocketError.HostUnreachable) { // There is no network route to the specified host. } else if (se.SocketErrorCode == SocketError.TimedOut) { // The connection attempt timed out, or the connected host has failed to respond. } else { logger.Warn(e); } } else if (e is ObjectDisposedException) { } else if (e is Win32Exception) { var ex = (Win32Exception)e; // Win32Exception (0x80004005): A 32 bit processes cannot access modules of a 64 bit process. if ((uint)ex.ErrorCode != 0x80004005) { logger.Warn(e); } } else if (e is ProxyException) { var ex = (ProxyException)e; switch (ex.Type) { case ProxyExceptionType.FailToRun: case ProxyExceptionType.QueryReturnMalformed: case ProxyExceptionType.SysproxyExitError: logger.Error($"sysproxy - {ex.Type.ToString()}:{ex.Message}"); break; case ProxyExceptionType.QueryReturnEmpty: case ProxyExceptionType.Unspecific: logger.Error($"sysproxy - {ex.Type.ToString()}"); break; } } else { logger.Warn(e); } } } }