ASP.NET Log4net数据库日志新增记录客户端ip
LOG4数据库记录器XML配置
1 <appender name="ADONetAppender" type="log4net.Appender.ADONetAppender"> 2 <!--BufferSize为缓冲区大小,只有日志记录超设定值才会一块写入到数据库--> 3 <bufferSize value="1"/> 4 <Threshold value="Error" /> 5 <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/> 6 <connectionString value="Data Source=USER-20190520KW;Initial Catalog=SiteLogs;Connect Timeout=30;Persist Security Info=True;User ID=electricdb;Password=888888;Max Pool Size = 32767"/> 7 <commandText value="INSERT INTO T_SiteLogs ([LogDate],[LogThread],[LogLevel],[LogLogger],[LogMessage],[LogException],[LogIp]) VALUES (@log_date, @log_thread, @log_level, @log_logger, @log_message, @log_exception,@log_ip)"/> 8 <parameter> 9 <parameterName value="@log_date"/> 10 <dbType value="DateTime"/> 11 <layout type="log4net.Layout.RawTimeStampLayout"/> 12 </parameter> 13 <parameter> 14 <parameterName value="@log_thread"/> 15 <dbType value="String"/> 16 <size value="255"/> 17 <layout type="log4net.Layout.PatternLayout"> 18 <conversionPattern value="%thread"/> 19 </layout> 20 </parameter> 21 <parameter> 22 <parameterName value="@log_level"/> 23 <dbType value="String"/> 24 <size value="50"/> 25 <layout type="log4net.Layout.PatternLayout"> 26 <conversionPattern value="%level"/> 27 </layout> 28 </parameter> 29 <parameter> 30 <parameterName value="@log_logger"/> 31 <dbType value="String"/> 32 <size value="255"/> 33 <layout type="log4net.Layout.PatternLayout"> 34 <conversionPattern value="%logger"/> 35 </layout> 36 </parameter> 37 <parameter> 38 <parameterName value="@log_message"/> 39 <dbType value="String"/> 40 <size value="4000"/> 41 <layout type="log4net.Layout.PatternLayout"> 42 <conversionPattern value="%message"/> 43 </layout> 44 </parameter> 45 <parameter> 46 <parameterName value="@log_exception"/> 47 <dbType value="String"/> 48 <size value="2000"/> 49 <layout type="log4net.Layout.ExceptionLayout"/> 50 </parameter> 51 <parameter> 52 <parameterName value="@log_ip"/> 53 <dbType value="String"/> 54 <size value="50"/> 55 <layout type="Electric.WebUI.ConsoleLog.IPatternLayout"> 56 <conversionPattern value="%log_IP"/> 57 </layout> 58 </parameter> 59 60 </appender>
@log_ip为客户端IP字段名称,名字可以自己取,INSERT语句顺序匹配上就行
配置字段自定义处理程序:
<parameter> <parameterName value="@log_ip"/> <dbType value="String"/> <size value="50"/> <layout type="Electric.WebUI.ConsoleLog.IPatternLayout"> <conversionPattern value="%log_IP"/> </layout> </parameter>
parameterName:我们定义的字段名称
dbType:默认String
layout:处理程序的命名空间
获取客户端IP处理程序:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Text; namespace Electric.WebUI.ConsoleLog { public class LogMessage { public LogMessage() { Computer cp = Computer.Instance; Message = ""; IP = cp.IpAddress; } public LogMessage(string message) : this() { Message = message; } public string IP { get; set; } public string Message { get; set; } public override string ToString() { return Message.ToString(); } } }
获取客户端IP帮助类
using System; using System.Text; using System.Management; using System.Security.Cryptography; using System.Text.RegularExpressions; using System.Web; namespace Electric.WebUI.ConsoleLog { public class Computer { public string IpAddress; private static Computer _instance; public static Computer Instance { get { if (_instance == null) _instance = new Computer(); return _instance; } } protected Computer() { IpAddress = IPAddress; } public string IPAddress { get { string result = String.Empty; if (System.Web.HttpContext.Current == null || System.Web.HttpContext.Current.Request == null || System.Web.HttpContext.Current.Request.ServerVariables == null) return string.Empty; //CDN加速后取到的IP result = System.Web.HttpContext.Current.Request.Headers["Cdn-Src-Ip"]; if (!string.IsNullOrEmpty(result)) { return result; } result = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; if (!string.IsNullOrEmpty(result)) { //可能有代理 if (result.IndexOf(".") == -1) //没有“.”肯定是非IPv4格式 result = null; else { if (result.IndexOf(",") != -1) { //有“,”,估计多个代理。取第一个不是内网的IP。 result = result.Replace(" ", "").Replace("'", ""); string[] temparyip = result.Split(",;".ToCharArray()); for (int i = 0; i < temparyip.Length; i++) { if (IsIPAddress(temparyip[i]) && temparyip[i].Substring(0, 3) != "10." && temparyip[i].Substring(0, 7) != "192.168" && temparyip[i].Substring(0, 7) != "172.16.") { return temparyip[i]; //找到不是内网的地址 } } } else if (IsIPAddress(result)) //代理即是IP格式 ,IsIPAddress判断是否是IP的方法, return result; else result = null; //代理中的内容 非IP,取IP } } if (string.IsNullOrEmpty(result)) result = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]; if (string.IsNullOrEmpty(result) || string.Compare(result, "unknown", true) == 0) result = HttpContext.Current.Request.UserHostAddress; if (result.Equals("::1")) { return "127.0.0.1"; } return result; } } public bool IsIPAddress(string str) { if (string.IsNullOrWhiteSpace(str) || str.Length < 7 || str.Length > 15) return false; string regformat = @"^\d{1,3}[\.]\d{1,3}[\.]\d{1,3}[\.]\d{1,3}{1}quot;"; Regex regex = new Regex(regformat, RegexOptions.IgnoreCase); return regex.IsMatch(str); } } }
using System; using System.Collections.Generic; using System.Text; using System.Collections; using System.IO; using log4net.Core; //using log4net.Layout.Pattern; using log4net.Util; using log4net.Layout; using log4net.Layout.Pattern; namespace Electric.WebUI.ConsoleLog { public class IPatternLayout : log4net.Layout.PatternLayout { public IPatternLayout() { this.AddConverter("log_IP", typeof(IPPatternConverter)); } } internal sealed class IPPatternConverter : PatternLayoutConverter { override protected void Convert(TextWriter writer, LoggingEvent loggingEvent) { LogMessage logMessage = loggingEvent.MessageObject as LogMessage; if (logMessage != null) writer.Write(logMessage.IP); } } }