Opserver 初探二《exceptions配置》

上一节主要介绍Opserver的搭建以及redis、sqlserver监控的配置,本节主要介绍异常日志的记录和监控。要实现异常日志的监控我们需要在项目中引入StackExchange.Exceptional组件,用于日志的采集和存储操作。

首先我们简单的来认识一下Opserver项目config文件夹下的ExceptionsSettings.json.example文件,

{
  "warningRecentCount": "100",           //警告提醒最近条目数,当超出该值在头部高亮显示警告
  "criticalRecentCount": "200",          //严重警告提醒最近条目数,当超出该值在头部高亮显示严重警告
  "viewGroups": "StatusExceptionsRO",    //安全模式“ad"下的分组查看权限设置
  // You can have a simple applications list here, or a grouped structure when dealing with many apps.
  //"applications": [                    //产生异常日志的程序
  //  "Core",
  //  "Chat",
  //  "Stack Auth",
  //  "StackExchange.com",
  //  "API",
  //  "API v2",
  //  "Area 51",
  //  "Status",
  //  "Push Server",
  //  "Sockets",
  //  "Careers",
  //  "BackOffice",
  //  "Control Panel"
  //],

//以分组在形式归类异常日志,未在groups定义的在others中显示
"groups": [ { "name": "Core Q&A", "applications": [ "Core", "Chat", "Stack Auth", "StackExchange.com", "API v2", "Sockets", "Area 51", "Open ID", "Stack Server", "StackSnippets", "Status" ] }, { "name": "Careers", "applications": [ "Careers", "BackOffice", "BackOffice", "Control Panel", "StackShop", "CareersAuth" ] }, { "name": "Mobile", "applications": [ "Push Server" ] }, { "name": "Ads & Data", "applications": [ "Prov Read API" ] } ], "stores": [ //异常日志存储位置 { "name": "New York", "queryTimeoutMs": 2000, "pollIntervalSeconds": 10, "connectionString": "Server=ny-sql03.ds.stackexchange.com;Database=NY.Exceptions;Integrated Security=SSPI;" } ] }

1、StackExchange.Exceptional引入及记录异常日志

异常日志可以有web,console,service等程序产生

web项目,需要3步配置:

  • 在web项目中nuget安装StackExchange.Exceptional组件(依赖dapper)
  • 在web.config中增加section “Exceptional
<section name="Exceptional" type="StackExchange.Exceptional.Settings" />
<Exceptional applicationName="Samples.MVC4">
  <ErrorStore type="Memory" />
<!--连接opserver数据库时开启-->
<!--<ErrorStore type="SQL" connectionString="Server=.;Database=Exceptions;Uid=Exceptions;Pwd=myPassword!" />-->
</Exceptional>

applicatinName 产生异常日志的程序名称用于Opserve显示归类

ErrorStore 错误存储有4种实现方式,Memory,JSON,SQL,MySQL,参考官方说明

    <!-- Which ErrorStore to use, if no element is declared here a Memory store with defaults will be used -->
    <!--<ErrorStore type="Memory" />-->
    <!-- Other store types, common attributes:
         - rollupSeconds: optional (default 600 seconds), determines how long the window is to roll up exceptions with the same stack trace - 0 to not roll up
         - backupQueueSize: optional (default 1000), determines how many errors to cache (excluding rollups) in memory when logging fails...every 2 seconds we'll retry logging and flush these out to the final store -->
    <!-- JSON: size defaults to 200, this is how many files are kept before the oldest error is removed -->
    <!--<ErrorStore type="JSON" path="~/Errors" size="200" />-->
    <!-- SQL: only a connection string or connection string name is needed, many applications can log to the same place as long as they have unique names (otherwise we can't tell them apart). -->
    <!--<ErrorStore type="SQL" connectionString="Server=.;Database=Exceptions;Uid=Exceptions;Pwd=myPassword!" />-->
    <!--<ErrorStore type="SQL" connectionStringName="MyConnectionString" />-->
    <!-- You can also use a MySQL Database with the MySQL ErorrStore -->
    <!--<ErrorStore type="MySQL" connectionString="Server=.;Database=Exceptions;Username=Exceptions;Pwd=myPassword!" />-->
    <!--<ErrorStore type="MySQL" connectionStringName="MyConnectionString" />-->
  • 在web.config中增加handler和module,module配置后,异常日志自动记录
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <handlers>
      <!-- OPTIONAL: if not using a router, or you don't want to access the errors directly via this application,
           this is not necessary.  A common scenario for this is logging all errors to a common SQL store and viewing
           them through another application or a dashboard elsewhere.  
           Note: If the error list isn't exposed in the application, any errors in logging exceptions will be queued up, 
           but not visible (since that's exposed on the error list view).
      -->
      <add name="Exceptional" path="exceptions.axd" verb="POST,GET,HEAD" type="StackExchange.Exceptional.HandlerFactory, StackExchange.Exceptional" preCondition="integratedMode" />
    </handlers>
    <!-- Here the error log needs to be registered to catch all unhandled exceptions, 
         these are exceptions that make it all the way to being a 500 page the user sees. -->
    <modules runAllManagedModulesForAllRequests="true">
      <add name="ErrorLog" type="StackExchange.Exceptional.ExceptionalModule, StackExchange.Exceptional" />
    </modules>
  </system.webServer>

 console,service前两步同web项目,需要nuget安装StackExchange.Exceptional,在app.config配置section“Exceptional”,然后在main主函数中添加未处理异常记录

        static void Main(string[] args)
        {
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
             /*
             ...
             */
         }

    private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            Exception ex = e.ExceptionObject as Exception;
            if (ex != null)
            {
                StackExchange.Exceptional.ErrorStore.LogExceptionWithoutContext(ex);
            }
        }

 如果需要自定义添加异常,可以在try...catch中记录,如:

           try
            {
                throw new Exception("Just a try/catch test");
            }
            catch (Exception ex)
            {
                // logged, but caught so we don't crash
                ErrorStore.LogExceptionWithoutContext(ex);
            }

3、异常数据存储SQL,创建表语句

USE [OpServerTest]
GO

/****** Object:  Table [dbo].[Exceptions]    Script Date: 2016/11/16 16:28:56 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[Exceptions](
    [Id] [bigint] IDENTITY(1,1) NOT NULL,
    [GUID] [uniqueidentifier] NOT NULL,
    [ApplicationName] [nvarchar](50) NOT NULL,
    [MachineName] [nvarchar](50) NOT NULL,
    [CreationDate] [datetime] NOT NULL,
    [Type] [nvarchar](100) NOT NULL,
    [IsProtected] [bit] NOT NULL,
    [Host] [nvarchar](100) NULL,
    [Url] [nvarchar](500) NULL,
    [HTTPMethod] [nvarchar](10) NULL,
    [IPAddress] [varchar](40) NULL,
    [Source] [nvarchar](100) NULL,
    [Message] [nvarchar](1000) NULL,
    [Detail] [nvarchar](max) NULL,
    [StatusCode] [int] NULL,
    [SQL] [nvarchar](max) NULL,
    [DeletionDate] [datetime] NULL,
    [FullJson] [nvarchar](max) NULL,
    [ErrorHash] [int] NULL,
    [DuplicateCount] [int] NOT NULL,
 CONSTRAINT [PK_Exceptions] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[Exceptions] ADD  DEFAULT ((0)) FOR [IsProtected]
GO

ALTER TABLE [dbo].[Exceptions] ADD  DEFAULT ((1)) FOR [DuplicateCount]
GO

4、在Opserver项目中,配置 ExceptionsSettings.json文件,修改groups和stores,如:

"stores": [      //异常日志存储位置
    {
      "name": "ExceptionDB",
      "queryTimeoutMs": 2000,
      "pollIntervalSeconds": 10,
      "connectionString": "Data Source=192.168.1.120;User ID=sa;Password=*******;Initial Catalog=OpserverTest;"
    }


注:目前Opserver版本支持store在sql server服务器上,不支持在文件,内存,和Mysql中,如果需要mysql支持,需要修改Opserver.core代码。
      在配置多个store的情况,默认第一个有效

 官方示例dome和源码下载:https://github.com/NickCraver/StackExchange.Exceptional

原文地址:https://www.cnblogs.com/hobinly/p/6069891.html