log2net是一个用于收集日志到数据库或文件的组件,支持.net和.netcore平台。 此组件自动收集系统的运行日志(服务器运行情况、在线人数等)、异常日志。程序员还可以添加自定义日志。 该组件支持.net平台和.netcore平台,支持将日志写入到文本文件、sql server、oracle、mysql,可以方便地扩展到其他数据库。

  针对这个组件的数据,相应地有日志查询网站,它查询日志数据库的数据(log2net组件存储的日志数据),显示各服务器/网站的实时数据图表显示,提供操作轨迹数据和监控数据的查询功能,并对异常情况进行告警。

一、为什么要开发这个组件

  也有有园友要问了,现在的日志组件太多了啊,什么log4net,elk,kafka,grafana,graylog、facebook scribe,apache chukwa,cloudera flume等。都是国际大厂或知名组织的开源组件,你又何必重复造轮子呢?

  确实,这些开源系统不需要代码开发,且功能强大,支持各种类型(例如文本文本、数据库、缓存等)的日志的接入,有图表等多种展现方式,能实现海量数据的快速查询,能存储为多种类型(例如文本文本、数据库、缓存、hdfs等),天生的适合分布式部署。缺点是部署运维较为复杂,需要较多的插件支持(java、nodejs、erlang等);这些大都采用开源的java、scala等语言开发,优先应用于linux平台,我们不能灵活自由地定制自己的需求,相对我们.net平台来说,资料较少开发难度较大,相对我们的需求来说较为庞大。log4net组件虽然可以灵活地应用到.net系统中,但依然不满足我们的需求。

  在我们的系统中,我们想知道用户进行了什么操作,想知道网站的运行情况(例如在线人数、异常情况等),想监控服务器的运行情况(如内存情况、磁盘使用情况等),目前没有一个合适的方案来较好地满足满足我们的需求。因此,我们开发了一个日志组件和一个集中式日志查询系统。这个日志组件可以自动地收集系统的运行情况(如服务器内存、磁盘使用、在线人数、日常日志等),可以记录用户操作情况等,可以通过日志查询界面显示各网站/服务器的实时数据图表显示,提供操作轨迹数据和监控数据的查询功能等。

二、log2net组件使用效果展示

  使用log2net组件后,可以将日志数据以友好的形式展示:显示各服务器/网站的实时数据图表显示,提供操作轨迹数据和监控数据的查询功能,并对异常情况进行告警。

1 操作日志查询

  操作日志查询主要用于按照系统名称、服务器名称、时段、日志类型、关键词等条件查询操作轨迹类数据,主要以列表数据的形式展示日志数据。在列表的左侧,可以显示服务器的概况,如cpu使用率,内存使用率等。在列表的上侧,显示日志的分类汇总情况。如下图所示:

 

2 系统监控 

  系统监控主要监控各服务器和应用网站的情况,主要以图形化的方面实时显示网站/服务器的运行情况。

  (1)、概况实时显示:显示服务器在当前时刻的cpu/内存使用率等情况;

  (2)、服务器状态监控:显示服务器在某时段内的cpu/内存使用率等情况;

  (3)、系统流量监控:显示系统在某时段内的在线人数、某页面的访问人数等;

  (4)、异常告警:在系统新加入监控或失去监控时音乐告警。

  如下图所示:

  上图中,每台服务器显示一条曲线图。因为本人测试的服务器只有一台,所以只有一个曲线图。随着服务器个数的增加,自动添加曲线图的个数。

      系统代码参见 https://github.com/yuchen1030/log2net-lgwg.logquery 。

三、log2net组件的使用方法

  看了上面炫酷的效果,是不是有点心动了呢,那么怎么将其应用到自己的网站中呢?别急,跟我一步一步来。

  ps. 本组件支持.net4.5~.netcore2.1,应该能满足绝大多数筒子们的需求了吧,后续会支持.netcore的更高版本,与.netcore同步更新。

1 引用组件

  在vs开发工具的nuget中,搜索 log2net 组件安装即可。

  搜索搜索 log2net ,log4net出现在第一位,好吧,我承认,名字是参考他们的,也浏览了他们的代码~~

  但是,小主,第二个才是我们要安装的,不要搞错了哦~~

      你也可以通过nuge官网来下载和安装: https://www.nuget.org/packages/log2net/  。但建议使用vs工具的nuget来安装。

2 组件的注册

  要使用该组件,需要进行组件的注册:在应用程序初始化的地方,调用  logapi.registerloginitmsg(syscategory sys, object application, bool bwritestartlog = true, bool blogmonitor = true);

  各参数解释如下: 

  syscategory sys:业务系统的名称,在syscategory枚举中定义好了。

  object application:程序的application对象,用于网站在线人数和历史访客统计,仅在.net平台中使用。netcore中该参数为null;

  bool bwritestartlog:是否写网站启动的日志,默认为true;

  bool blogmonitor:是否写系统定时监控日志,默认为true。

  一般地,在调用该方法时,只需要设置前两个参数,后两个参数可以不设置。

  在.net平台中,是 global.asax 中application_start()事件中注册;

  在.netcore平台中,是startup.cs configure中applifetime.applicationstarted.register方法中注册。

  该方法必须被调用,且必须在应用程序初始化事件中调用,否则调用其他写日志的方法时会出错。

      此时,若您运行网站,则可以在网站的 app_data/log_files 文件夹下看到txt格式的运行日志数据。若您需要将日志记录到数据库,则需要进行下述的日志配置。

3 日志组件的配置

  本组件默认将日志数据记录到网站的 app_data/log_files 文件夹下,格式为文本文件。若希望将日志数据记录到数据库,则需要进行配置。

        1 基础配置

 1   <basecfg>
 2 
 3     <!--日志级别:1、off;2、error;3、warn; 4、business ;5、dbrec; 6、info;7、debug (默认为7)-->
 4     <add key="log2netlevel" value="7" />
 5 
 6     <!--日志记录方式:1、写到文件;2、直接写到数据库;3、消息队列写到数据库;-->
 7     <add key="appendertype" value="2" />
 8 
 9     <!--监控日志每隔多少分钟记录一次,若未设置默认为10分钟,若小于0则不监控-->
10     <add key="logmonitorintervalmins" value="1"/>
11 
12     <!--是否将info信息(仅供调试,不记录到日志的信息)记录到本地debug文件:0不记录,1记录(默认为0)-->
13     <add key="bwriteinfotodebugfile" value="1"/>
14 
15   </basecfg>

       2 文件方式配置

1   <filecfg>
2     <!--写文件的路径(仅在日志记录方式为1时有效)-->
3     <add key = "logtofilepath" value="app_data/log_files"/>
4 
5   </filecfg>

  3 数据库方式配置

 1   <logdbcfg>
 2     <!-- 访问数据库的方式:adonet = 1,  ef = 2,  nh = 3 。默认为1-->
 3     <add key="dbaccesstypekey" value="1" />
 4 
 5     <!--trace数据库的类型:sqlserver = 1,  oracle = 2, mysql = 3,  access = 4,   postgresql = 5,  sqlite = 6。默认为1-->
 6     <add key="usercfg_tracedbtypekey" value="1" />
 7     <!--monitor数据库的类型:sqlserver = 1,  oracle = 2, mysql = 3,  access = 4,   postgresql = 5,  sqlite = 6。默认为1-->
 8     <add key="usercfg_monitordbtypekey" value="1" />
 9 
10     <!--trace数据库的数据库连接字符串name值。默认为logtracesqlstr-->
11     <add key="usercfg_tracedbconkey" value="logtracesqlstr" />
12     <!--monitor数据库的数据库连接字符串name值。默认为logmonitorsqlstr-->
13     <add key="usercfg_monitordbconkey" value="logmonitorsqlstr" />
14 
15   </logdbcfg>

  4 oracle数据库特殊配置

 1   <oraclecfg>
 2     <!--是否使用ef初始化数据库trace 表:0不使用,1使用,默认为0-->
 3     <add key = "inittracedbwhenoracle" value="0"/>
 4 
 5     <!--是否使用ef初始化数据库 monitor 表:0不使用,1使用,默认为0-->
 6     <add key = "initmonitordbwhenoracle" value="0"/>
 7 
 8     <!--oracle数据库驱动方式:0 oracle驱动, 1 微软驱动,默认为0-->
 9     <add key = "oracledrivertype" value="0"/>
10   </oraclecfg>

  5 消息队列配置

1   <mqcfg>
2     <!--消息队列服务器(地址、用户名、密码)-->
3     <add key="rabbitmqserver_log" value="localhost:5672;oawxadmin1;admin123.123"/>
4   </mqcfg>

  6 influxdb数据库方式配置

1   <influxdbcfg>
2 
3     <!--是否需要写到influxdb数据库(默认为0)-->
4     <add key="bwritetoinfluxdb" value="0"/>
5 
6     <!--influxfu服务器的地址,用户名,密码-->
7     <add key="influxdbserver_log" value="http://127.0.0.1:8086/;logadmin;sa123.123"/>
8 
9   </influxdbcfg>

  7 缓存配置

 1   <cachecfg>
 2     <!--缓存策略:0、net缓存;1、cachemanager中的net系统缓存;2、memcached缓存;3、redis缓存;默认为0-->
 3     <add key = "cachestrategy" value="0"/>
 4 
 5     <!--memcache缓存服务器-->
 6     <add key = "memcacheserver" value="127.0.0.1:11211;127.0.0.2:11211"/>
 7 
 8     <!--redis缓存服务器-->
 9     <add key = "rediscacheserver" value="127.0.0.1:6379;127.0.0.2:6379"/>
10   </cachecfg>

       8 日志数据库连接字符串配置        

 1   <connectionstrings>
 2     <!--操作轨迹日志的数据库(sql server)-->
 3     <add name="logtracesqlstr" connectionstring="data source=.;initial catalog=logtracew;user id=sa;password=sa123.123;multipleactiveresultsets=true;application name=entityframework" providername="system.data.sqlclient" />
 4     <!--系统监控日志的数据库(sql server)-->
 5     <add name="logmonitorsqlstr" connectionstring="data source=.;initial catalog=logmonitorw;user id=sa;password=sa123.123;multipleactiveresultsets=true;application name=entityframework" providername="system.data.sqlclient" />
 6 
 7     <!--操作轨迹日志的数据库(oracle)-->
 8     <add name="logtracesqlstr2" connectionstring="user id=scott;password=sa123123;data source=(description=(address=(protocol=tcp)(host=localhost)(port=1521))(connect_data=(service_name=logtracew)))" providername="oracle.manageddataaccess.client" />
 9     <!--系统监控日志的数据库(oracle)-->
10     <add name="logmonitorsqlstr2" connectionstring="user id=scott;password=sa123123;data source=(description=(address=(protocol=tcp)(host=localhost)(port=1521))(connect_data=(service_name=logmonitorw)))" providername="oracle.manageddataaccess.client" />
11 
12     <!--操作轨迹日志的数据库(mysql)-->
13     <add name="logtracesqlstr3" connectionstring="data source=localhost;port=3306;initial catalog=logtracew;user id=sa;password=sa123123;" providername="mysql.data.mysqlclient" />
14     <!--系统监控日志的数据库(mysql)-->
15     <add name="logmonitorsqlstr3" connectionstring="data source=localhost;port=3306;initial catalog=logmonitorw;user id=sa;password=sa123123;" providername="mysql.data.mysqlclient" />
16   </connectionstrings>

  一般地,我们只需要在基础配置中配置  日志记录方式 appendertype 的值为 2 (直接写到数据库),在数据库方式中配置访问数据库的方式和数据库类型,最后配置数据库连接字符串即可。若需要使用消息队列、缓存、influxdb等高级特性时,再进行相应配置即可。

  上述1~7的配置,是在单独的文件中进行配置的。在web.config文件中定义该文件的名称和类型,并添加第8项的数据库连接字符串配置。

      例如,在web.config文件进行如下配置:

 1 <configsections>
 2 <!--log2net模块声明-->
 3 <section name="log2netcfg" type="log2net.config.log2netconfigurationsectionhandler, log2net" />
 4 </configsections>
 5 
 6   <log2netcfg configsource="log2netcfg.config" />
 7 
 8 <connectionstrings>
 9 <!--操作轨迹日志的数据库(sql server)-->
10 <add name="logtracesqlstr" connectionstring="data source=.;initial catalog=logtracew;user id=sa;password=sa123.123;multipleactiveresultsets=true;application name=entityframework" providername="system.data.sqlclient" />
11 <!--系统监控日志的数据库(sql server)-->
12 <add name="logmonitorsqlstr" connectionstring="data source=.;initial catalog=logmonitorw;user id=sa;password=sa123.123;multipleactiveresultsets=true;application name=entityframework" providername="system.data.sqlclient" />
13 
14 </connectionstrings>

      并在网站中添加 log2netcfg.config 文件,在该文件中添加1~7的配置。

      以上配置项,值为数字,进行了简单的分组。事实上,您可以在值的位置填写名称。例如   <add key=”log2netlevel” value=”debug” />。您可以随意分组,随意明明分组的名称。例如将 logdbcfg 分组命名为 log2netdbcfg,将 appendertype加入到该分组中,都是可以的,只要不改变配置项的名称,配置项名称不重复即可。

 

  以上配置介绍,都是基于.net平台。那么,在.netcore平台中,又该如何配置呢?配置方法如下:

      新建log2netcfg.json文件,内容如下:

 1 {
 2   "connectionstrings": {
 3     "logtracesqlstr": "data source =127.0.0.1;initial catalog = logtracew;uid=sa;pwd=sa123.123;",
 4     "logmonitorsqlstr": "data source =127.0.0.1;initial catalog = logmonitorw;uid=sa;pwd=sa123.123;",
 5     "logtracesqlstr2": "user id=scott;password=sa123123;data source=(description=(address=(protocol=tcp)(host=localhost)(port=1521))(connect_data=(service_name=logtracew)))",
 6     "logmonitorsqlstr2": "user id=scott;password=sa123123;data source=(description=(address=(protocol=tcp)(host=localhost)(port=1521))(connect_data=(service_name=logmonitorw)))",
 7     "logtracesqlstr3": "data source=localhost;port=3306;initial catalog=logtracew;user id=sa;password=sa123123;",
 8     "logmonitorsqlstr3": "data source=localhost;port=3306;initial catalog=logmonitorw;user id=sa;password=sa123123;"
 9   },
10 
11   "basecfg": {
12     "log2netlevel": "info",
13     "appendertype": "2",
14     "logmonitorintervalmins": "1",
15     "dncsessiontimeoutmins": "20",
16     "bwriteinfotodebugfile": "0"
17   },
18 
19   "filecfg": {
20     "logtofilepath": "app_data/log_files"
21   },
22 
23 
24   "logdbcfg": {
25     "dbaccesstypekey": "2",
26     "usercfg_tracedbtypekey": "1",
27     "usercfg_monitordbtypekey": "1",
28     "usercfg_tracedbconkey": "logtracesqlstr",
29     "usercfg_monitordbconkey": "logmonitorsqlstr"
30   },
31 
32   "oraclecfg": {
33     "inittracedbwhenoracle": "0",
34     "initmonitordbwhenoracle": "0",
35     "oracledrivertype": "0"
36   },
37 
38   "mqcfg": {
39     "rabbitmqserver_log": "localhost:5672;oawxadmin1;admin123.123"
40   },
41 
42   "influxdbcfg": {
43     "bwritetoinfluxdb": "0",
44     "influxdbserver_log": "http://127.0.0.1:8086/;logadmin;sa123.123"
45   },
46 
47   "cachecfg": {
48     "cachestrategy": "0",
49     "memcacheserver": "127.0.0.1:11211;127.0.0.2:11211",
50     "rediscacheserver": "127.0.0.1:6379;127.0.0.2:6379"
51   }
52 }

  然后在启动代码中声明使用该配置文件:configureappconfiguration((context, config) =>{config.addjsonfile(“log2netcfg.json”, false, true);})  。

 

  另外,对于系统的名字,系统中默认的名称为sys字母_两位数字(sysa_01 ~ sysz_99)。您可以通过配置将其映射为您想要的名称。例如

1   <usersystemnames>
2     <add key="sysa_01" value="短信接口网站" />
3     <add key="201" value="公司oa系统" />
4     <add key="901" value="用户数据网站" />
5   </usersystemnames>

      这个配置项在查询网站中很有用。该配置也是在 log2netcfg 文件中配置的。

4 .net平台日志记录方法

   (1) 按照上述方法进行组件的注册、web.config文件和log2netcfg.config文件的配置;

  (2)  网站生命周期事件的日志记录

日志记录的说明

使用位置

方法

网站全局错误日志

application_error事件

handandwriteexception

网站停止日志

application_end事件

writeserverstoplog

在线人数和历史访客的增加

session_start事件

increaseonlinevisitnum

在线人数的减少

session_end事件

reduceonlinenum

网站启动后初次访问

application_beginrequest事件

writefirstvisitlog

  (3) 在需要进行日志记录的位置调用 logapi.writelog ( loglevel loglevel, params log_operatetraceblledm[] model)  或  logapi.writelog ( loglevel loglevel, params logmonitoredm[] model)  方法进行操作轨迹日志或监控日志的记录。

  具体使用方法可参考 https://github.com/yuchen1030/log2net/tree/master/log2netweb_net45 。

5 .netcore平台日志记录方法

   (1) 按照上述方法进行组件的注册、log2netcfg.json文件的配置和声明;

  (2) 相关服务配置

      a、在startup.cs的configureservices方法中,调用logapi.addlog2netservice(services, configuration);
      b、在 startup.cs的configure中,调用logapi.addlog2netconfigure(app, env);

  (3) 在需要进行日志记录的位置调用 logapi.writelog ( loglevel loglevel, params log_operatetraceblledm[] model)  或  logapi.writelog ( loglevel loglevel, params logmonitoredm[] model)  方法进行操作轨迹日志或监控日志的记录。

  具体使用方法可参考 https://github.com/yuchen1030/log2net/tree/master/log2netweb_dnc 。

四、项目开源地址

  本组件已开源,项目地址为 https://github.com/yuchen1030/log2net 。建议使用的vs工具为vs2017。

  查询网站亦开源,项目地址为 https://github.com/yuchen1030/log2net-lgwg.logquery 。该项目使用abp+ef框架开发,建议使用vs工具为vs2017。

    接下来,我会介绍该日志组件的代码实现,敬请期待~~

      over,sleep.