问题1: 在公司进行log4net写入服务器配置的时候,一切正常,但是在家里的机器上,就频繁出现这个问题:
SQL Server 2008 报错:已成功与服务器建立连接,但是在登录前的握手期间发生错误 
并且这种错误是随机性的,在log4net往数据库插入几条的时候,没问题,但是插入次数一多起来,就频繁报这个错误。后来没办法,网上搜罗了一圈,最终发现了解决方案:
 
将相关的TCP参数都设置为启动之后,就再没遇到过问题。
 
 问题2,log4net配置都正确,但是一直无法写入数据库。
这个问题困扰了好久,最终得以解决,大家就看看我的解决代码吧,我也懒得帖步骤了。
 
配置文件如下:
  1. <log4net>
  2. <root>
  3. <level value="WARN"/>
  4. <level value="INFO"/>
  5. <level value="DEBUG"/>
  6. <level value="FINE"/>
  7. <!--<appender-ref ref="LogFileAppender" />-->
  8. <appender-ref ref="ADONetAppender" />
  9. </root>
  10. <appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
  11. <!--文件名称-->
  12. <file value="log.txt" />
  13. <!--所有新的日志都进行追加-->
  14. <appendToFile value="true" />
  15. <!--文件名称格式-->
  16. <datePattern value="-yyyy.MM.dd" />
  17. <!--文件名按日期滚动-->
  18. <rollingStyle value="Date" />
  19. <maxSizeRollBackups value="10" />
  20. <!--文件名称不固定,可变-->
  21. <staticLogFileName value="false" />
  22. <layout type="log4net.Layout.PatternLayout">
  23. <param name="ConversionPattern" value="%-5p%d{yyyy-MM-dd hh:mm:ss} – %m%n" />
  24. </layout>
  25. </appender>
  26. <appender name="ADONetAppender" type="log4net.Appender.ADONetAppender">
  27. <!--BufferSize为缓冲区大小,只有日志记录超1条才会一块写入到数据库-->
  28. <bufferSize value="1"/>
  29. <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
  30. <connectionString value="Data Source=****;Initial Catalog=***;Persist Security Info=True;User ID=sa;Password=***;MultipleActiveResultSets=True"/>
  31. <commandText value="INSERT INTO edu_log (Date,Thread,Level,Logger,Message,SchoolID,SysTypeID) values(@log_date,@thread,@log_level,@logger,@content,@s_id,@t_id)"/>
  32. <parameter>
  33. <parameterName value="@log_date" />
  34. <dbType value="DateTime" />
  35. <layout type="log4net.Layout.RawTimeStampLayout" />
  36. </parameter>
  37. <parameter>
  38. <parameterName value="@thread" />
  39. <dbType value="String" />
  40. <size value="255" />
  41. <layout type="log4net.Layout.PatternLayout">
  42. <conversionPattern value="%thread" />
  43. </layout>
  44. </parameter>
  45. <parameter>
  46. <parameterName value="@log_level" />
  47. <dbType value="String" />
  48. <size value="50" />
  49. <layout type="log4net.Layout.PatternLayout">
  50. <conversionPattern value="%level" />
  51. </layout>
  52. </parameter>
  53. <parameter>
  54. <parameterName value="@logger" />
  55. <dbType value="String" />
  56. <size value="255" />
  57. <layout type="log4net.Layout.PatternLayout">
  58. <conversionPattern value="%logger" />
  59. </layout>
  60. </parameter>
  61. <parameter>
  62. <parameterName value="@content" />
  63. <dbType value="String" />
  64. <size value="4000" />
  65. <layout type="FuNong.Framework.Logger.CustomLayout">
  66. <conversionPattern value="%property{content}" />
  67. </layout>
  68. </parameter>
  69. <parameter>
  70. <parameterName value="@s_id" />
  71. <dbType value="String" />
  72. <size value="50" />
  73. <layout type="FuNong.Framework.Logger.CustomLayout">
  74. <conversionPattern value="%property{s_id}" />
  75. </layout>
  76. </parameter>
  77. <parameter>
  78. <parameterName value="@t_id" />
  79. <dbType value="String" />
  80. <size value="50" />
  81. <layout type="FuNong.Framework.Logger.CustomLayout">
  82. <conversionPattern value="%property{t_id}" />
  83. </layout>
  84. </parameter>
  85. </appender>
  86. </log4net>

注意上面配置代码中:log4net.Layout.PatternLayout 是log4net本身提供的配置模板,如果你有的字段需要用到其本身的模板字段的话,就可以使用。

还需要注意这段话: <conversionPattern value="%property{s_id}" />,它表明,我们将会利用log4net提供的已有的property转义模板来识别我们的字段。

但是如果你有自定义字段的话,你就需要自己写layout和converter了。在上面的配置文件中,content,s_id,t_id是我自定义的三个字段,如何让这三个字段也写入到数据库呢,我们一步一步来配置。

首先,需要将三个自定义字段放到一个entity类中:

  1. namespace FuNong.Framework.Logger
  2. {
  3. public class LogContent
  4. {
  5. public LogContent(string content, string s_id, string t_id)
  6. {
  7. this.content = content;
  8. this.s_id = s_id;
  9. this.t_id = t_id;
  10. }
  11.  
  12. public string content { get; set; }
  13.  
  14. public string s_id { get; set; }
  15. public string t_id { get; set; }
  16. }
  17. }

然后,定义我们自己的layout,由于我们使用了property字段模板,所以我们这里需要按照如下方式添加:

  1. namespace FuNong.Framework.Logger
  2. {
  3. public class CustomLayout:PatternLayout
  4. {
  5. public CustomLayout()
  6. {
  7. this.AddConverter("property", typeof(XPatternConverter));
  8. }
  9. }
  10. }

最后,就是我们的Converter实现了:

  1. namespace FuNong.Framework.Logger
  2. {
  3. public class XPatternConverter : PatternLayoutConverter
  4. {
  5. protected override void Convert(System.IO.TextWriter writer, log4net.Core.LoggingEvent loggingEvent)
  6. {
  7. if (this.Option != null)
  8. {
  9. // Write the value for the specified key
  10. WriteObject(writer, loggingEvent.Repository, LookupProperty(Option, loggingEvent));
  11. }
  12. else
  13. {
  14. // Write all the key value pairs
  15. WriteDictionary(writer, loggingEvent.Repository, loggingEvent.GetProperties());
  16. }
  17.  
  18. }
  19.  
  20. /// <summary>
  21. /// 通过反射获取传入的日志对象的某个属性的值
  22. /// </summary>
  23. /// <param name="property"></param>
  24. /// <returns></returns>
  25. private Object LookupProperty(String property, log4net.Core.LoggingEvent loggingEvent)
  26. {
  27. Object propertyValue = String.Empty;
  28. PropertyInfo propertyInfo;
  29.  
  30. propertyInfo = loggingEvent.MessageObject.GetType().GetProperty(property);
  31. if (propertyInfo != null)
  32. {
  33. propertyValue = propertyInfo.GetValue(loggingEvent.MessageObject, null);
  34. }
  35. return propertyValue;
  36. }
  37.  
  38. }
  39. }

从上面代码,我们可以看到,log4net会通过反射来识别我们logContent这个entity中的字段,然后逐个赋值,再写到数据库的。

下面我们稍微包装一下:

  1. namespace FuNong.Framework.Logger
  2. {
  3. public interface ILoggerService
  4. {
  5. void Debug(object message);
  6. void Error(object message);
  7. void Fatal(object message);
  8. void Info(object message);
  9. void Warn(object message);
  10. }
  11. }
  1. namespace FuNong.Framework.Logger
  2. {
  3. public class LoggerService:ILoggerService
  4. {
  5. public LoggerService()
  6. {
  7. log4net.Config.XmlConfigurator.Configure();
  8. logger = LogManager.GetLogger(typeof(LoggerService));
  9. }
  10.  
  11. private readonly ILog logger;
  12.  
  13. public void Info(object message)
  14. {
  15. logger.Info(message);
  16. }
  17. public void Warn(object message)
  18. {
  19. logger.Warn(message);
  20. }
  21. public void Debug(object message)
  22. {
  23. logger.Debug(message);
  24. }
  25. public void Error(object message)
  26. {
  27. logger.Error(message);
  28. }
  29. public void Fatal(object message)
  30. {
  31. logger.Fatal(message);
  32. }
  33.  
  34. }
  35. }

由于我用了autofac做ioc,所以我们就直接看使用方法吧:

  1. protected override void OnAuthorization(AuthorizationContext filterContext)
  2. {
  3. if (auth)
  4. {
  5. var collection = cookie.GetCookieCollection("FuNong.UserInfo.Login");
  6. if (collection == null)
  7. {
  8. logger.Warn(new LogContent("用户登陆信息提取失败,将会跳转到登陆界面...", "1", "2"));
  9. filterContext.Result = new RedirectResult("Home/Login");
  10. }
  11. else
  12. {
  13. logger.Info(new LogContent("用户验证成功,请继续之前操作...","1","2"));
  14. }
  15. }
  16. }

这样,当我们运行起来后,我们就发现,程序已经将数据写入数据库了。

整个配置不难,但是细节挺多,稍微不小心,就可能导致写入不到数据库。

Log4Net写入到数据库配置过程中的一些小问题备忘的更多相关文章

  1. 使用log4net连接Mysql数据库配置

    log4net配置: //Author:GaoBingBing [assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net ...

  2. 菜鸟帮你跳过openstack配置过程中的坑

    一:前言 对于一个以前做java全栈工程师而言,而且没学过Linux,很少用虚拟机(还是在大学的时候简单的用过),去配置openstack我想我入的坑肯定比有基础的一定要多,躺在每个坑中徘徊思索的时间 ...

  3. 菜鸟帮你跳过openstack配置过程中的坑[文末新添加福利]

    一:前言 对于一个以前做java全栈工程师而言,而且没学过Linux,很少用虚拟机(还是在大学的时候简单的用过),去配置openstack我想我入的坑肯定比有基础的一定要多,躺在每个坑中徘徊思索的时间 ...

  4. Redis配置过程中的问题

    记录一下配置过程中的坑~~ 当Redis在服务器上安装完成后,get.set没有问题了,接下来在程序中使用看看... 首先 在配置文件redis.conf中,默认的bind 接口是127.0.0.1, ...

  5. CAS SSO:汇集配置过程中的错误解决方法

    本教程为gevin.me原创文章,转载请注明: CAS SSO:配置过程中的错误解决方法 | Gevin’s Blog 本文将收集在配置CAS SSO遇到的所有错误,希望对大家有帮助,也方便下次搭建的 ...

  6. ESXi与物理交换机静态链路聚合配置过程中的小陷阱

    作者:陆斌文章来自微信公众号:平台人生 内容简介:ESXi与物理交换机之间配置静态链路聚合时,因为静态链路聚合的特点,在进行down网卡和从虚拟交换机移除网卡的操作时,可能会无法完成故障流量切换,影响 ...

  7. springmvc配置过程中遇到的一些问题总结

    springmvc配置过程中遇到的一些问题总结 1.配置tomcat过程中的错误: 2.配置web.xml中DispatchServlet报红(配置好已有依赖条件下) 解决的办法: 因为新添加依赖,m ...

  8. ACM 做题过程中的一些小技巧。

    ACM做题过程中的一些小技巧. 1.一般用C语言节约空间,要用C++库函数或STL时才用C++; cout.cin和printf.scanf最好不要混用. 2.有时候int型不够用,可以用long l ...

  9. 使用Mac的过程中的一些小操作

    前言:使用Mac的过程中的一些小操作 查看Mac系统是32位还是64位: 方法1: 点击左上角的苹果按钮->关于本机->概览->系统报告->软件->偏好设置面板:右侧有提 ...

随机推荐

  1. svn错误

    在myEclipse客户端第一次连到SVN时,如:svn://192.168.20.242/MyProject1,然后要求输入用户名和密码.如果用户名和密码输入出错了,强行确定后.问题来了!会出现,以 ...

  2. 【转】Python开发指南:最佳实践精选

    总体原则 价值 “为别人开发你也想要使用的工具.” ——Kenneth Reitz "简洁总是胜过可用." ——Pieter Hintjens "满足90%的使用场景.忽 ...

  3. Android开源项目汇总【转】

    主要介绍那些不错个性化的View,包括ListView.ActionBar.Menu.ViewPager.Gallery.GridView.ImageView.ProgressBar.TextView ...

  4. 深入剖析 Spring 框架的 BeanFactory

    说到Spring框架,人们往往大谈特谈一些似乎高逼格的东西,比如依赖注入,控制反转,面向切面等等.但是却忘记了最基本的一点,Spring的本质是一个bean工厂(beanFactory)或者说bean ...

  5. Oracle与SQL SERVER编程差异分析(入门)

    网上有关Oracle与SQL SERVER性能差异的文章很多,结论往往是让你根据数据量与预算来选择数据库.但实际项目中,特别是使用 .Net 开发的系统,支持以上两种数据库或者更多已经成为Boss的普 ...

  6. ERP产品价格成本计算的几个方法(转)

          一般财务计算产品价格又很多方法,我这里做了几个供参考,实体属性主要是编号.数量.价格等,这里就不列出了. /// <summary> /// 先进先出算法 /// </s ...

  7. Redis系列(二)—— 数据类型及其使用

    Redis数据类型及其使用 参考:http://www.cnblogs.com/jackluo/p/3173436.html Redis支持五种数据类型:string(字符串),hash(哈希),li ...

  8. ElasticSearch Filter Aggregations

    类似于sql语句中where子句的作用 { "query": { "match_all": {} }, "aggs": { "ag ...

  9. nyoj 120 校园网络

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=120 思路:先将原图强连通缩点为新图,统计新图中入度,出度为0的点的个数,两者取最大值即为 ...

  10. 虚拟机Linux----Ubuntu1204----安装jdk1.8

    1.介绍 这里主要讲一下,如何在Ubuntu1204下通过压缩包的方式安装jdk1.8,rpm的直接运行就行了. 2.步骤 2.1 下载 地址:http://www.oracle.com/techne ...