隐藏

C#实现对站点、程序池状态的监控,以及URL能正常返回的监控,状态异常,邮件预警

发布:2021/7/13 9:37:28作者:管理员 来源:本站 浏览次数:985

需求:自动化组提出需要,要对IIS上的站点进行监控,异常停止后报警



需求分析:这站点的运行正常需要多方面的监控,如站点,程序池,资源,所以针对这需求做了三方面的监控。


   站点状态的监控


   站点对应的程序池的监控


   URL的监控,监控url能返回200的状态码



数据库设计:






页面展示:


配置list页



配置Detail页



预警邮件:




核心代码:


   配置页面代码


   index.cshtml


@model IEnumerable<Ctrip.Hotel.QA.Platform.Data.Dao.EnvRunStatusMonitorConfig>

@{

   ViewBag.Title = "Run Monitor";

}

@Styles.Render("~/Content/themes/metro/css")

@Styles.Render("~/Content/themes/custom/chcore.css")

@Styles.Render("~/Content/themes/fakeloader/fakeloader.css")

@Scripts.Render("~/scripts/metro/jquery.dataTables.min.js")

@Scripts.Render("~/Scripts/custom/chcoreui.js")

@Scripts.Render("~/scripts/pages/runmonitor.js")

<div class="grid" style="margin-top:50px;">

   <div class="row cells12">

       <div class="cell colspan10 offset1" id="divState">

       </div>

   </div>

   <div class="row cells12">

       <div class="cell colspan10 offset1" id="divContainer">

           <div style="margin-left:0px;">

               <button class="refreshbtn button primary" style="width:100px" onclick="eidtRunStatusMonitorConfigPage.refresh();">

                   <span class="mif-loop2"></span> 刷新

               </button>&nbsp;

               <button class="addapppoolmonitorbtn button success" style="width:100px" onclick="eidtRunStatusMonitorConfigPage.showEditDialog('editConfigDialog', 0)">

                   <span class="mif-plus"></span> 新建

               </button>

           </div>

           <table id="runMonitorTable" class="dataTable striped border bordered hovered" data-role="datatable" data-searching="true">

               <thead>

                   <tr>

                       <th><button class="invokeallbtn button warning" style="width:50px;">唤醒</button></th>

                       <th>监控器名</th>

                       <th>站点名</th>

                       <th>字站点名</th>

                       <th>机器名</th>

                       <th style="text-align:center">ip</th>

                       <th style="text-align:center">启动</th>

                       <th style="text-align:center">Action</th>

                   </tr>                    

               </thead>

               <tfoot>

                   <tr>

                       <th><button class="invokeallbtn button warning">唤醒</button></th>

                       <th>监控器名</th>

                       <th>站点名</th>

                       <th>字站点名</th>

                       <th>机器名</th>

                       <th style="text-align:center">ip</th>

                       <th style="text-align:center">开启</th>

                       <th style="text-align:center">Action</th>

                   </tr>

               </tfoot>

               <tbody>

                   @foreach (var item in Model)

                   {

                       <tr>

                           <td style="text-align:center;"><span class="fg-cyan mif-play invokebtn"></span></td>

                           <td>

                               @Html.DisplayFor(modelItem => item.Name)

                           </td>

                           <td>

                               @Html.DisplayFor(modelItem => item.DomainName)

                           </td>

                           <td>

                               @Html.DisplayFor(modelItem => item.NodeName)

                           </td>

                           <td>

                               @Html.DisplayFor(modelItem => item.MachineName)

                           </td>

                           <td>

                               @Html.DisplayFor(modelItem => item.Ip)

                           </td>

                           <td>

                               <label class="switch">

                                   @if (item.TurnOn == 1)

                                   {

                                       <input type="checkbox" id="turnOn" checked onchange="eidtRunStatusMonitorConfigPage.postTurnOff(@Html.DisplayFor(modelItem => item.Id))" />

                                   }

                                   else

                                   {

                                       <input type="checkbox" id="turnOn" onchange="eidtRunStatusMonitorConfigPage.postTurnOn(@Html.DisplayFor(modelItem => item.Id))" />

                                   }

                                   <span class="check"></span>

                               </label>        

                           

                           </td>

                           <td>

                               <span class="mif-pencil fg-green" onclick="eidtRunStatusMonitorConfigPage.showEditDialog('editConfigDialog',  @Html.DisplayFor(modelItem => item.Id))"></span>

                               <span class="mif-cancel fg-red" onclick="eidtRunStatusMonitorConfigPage.deleteConfig(@Html.DisplayFor(modelItem => item.Id))"></span>                            

                           </td>

                       </tr>

                   }

                 

               </tbody>

           </table>

       </div>

   </div>

</div>

<div data-role="dialog" id="editConfigDialog" class="padding20" data-close-button="true" data-overlay="true" data-overlay-color="op-dark" >

   <h3>运行状态监控配置:</h3><hr/>

   <div class="metro">

       <div style="width:620px">

           <div class="grid">

               <div class="row">

           

                       <div id="subDiv" class="input-control full-size" data-role="select" data-placeholder="请选择环境" data-allow-clear="true">

                           <select class="full-size" id="sub"></select>

                       </div>

                   <div id="templateDiv" class="input-control full-size" data-role="select" data-placeholder="请选择站点" data-allow-clear="true">

                       <select class="full-size" id="template"></select>

                   </div>

                   <div id="nodeDiv" class="input-control full-size" data-role="select" data-placeholder="请选择应用" data-allow-clear="true">

                       <select class="full-size" id="node"></select>

                   </div>                        

                       

                   </div>

               <div class="row" id="ipAndPoolInfoDiv" style="display:none">

                   <div class="span2">

                       <div style="float:left;display:inline;font-weight:bold;margin-left:10px">

                           IP:

                       </div>

                       <div id="ip" style="float:left;display:inline;">

                           10.2.3.410

                       </div>

                   </div>

                   <div class="span6">

                       <div style="float:left;display:inline;font-weight:bold;">

                           程序池:

                       </div>

                       <div id="apppool" style="float:left;display:inline;">

                           hotel-vendor-interfaceadapter

                       </div>

                   </div>

               </div>

                   <div class="row">

                       <div class="span8">

                           <label class="switch" style="float:left;display:inline;margin-left:10px;">

                               <input type="checkbox" checked id="turnOn">

                               <span class="check"></span>

                               &nbsp; 开启监控

                           </label>

                           <label class="switch" style="float:left;display:inline;margin-left:50px;">

                               <input type="checkbox" checked id="emailOn">

                               <span class="check"></span>

                               &nbsp;收邮件

                           </label>                        

                       </div>

                   </div>

                   <div class="row">

                       <div class="span8">

                           <div style="float:left;display:inline;margin-top:10px;margin-left:10px;font-weight:bold;">

                               Monitor Name:

                           </div>

                           <div style="float:left;display:inline;margin-left:10px;width:490px">

                               <!-- Input with clear helper -->

                               <div class="input-control text" data-role="input">

                                   <input type="text" id="monitorName">

                                   <button class="button helper-button clear"><span class="mif-cross"></span></button>

                               </div>                            

                           </div>

                       </div>

                   </div>

                   <div class="row">

                       <div class="span8">

                           <label class="switch" style="float:left;display:inline;margin-left:10px;">

                               <input type="checkbox" id="siteOn">

                               <span class="check"></span>

                               &nbsp;监控站点

                           </label>          

                           <label class="switch" style="float:left;display:inline;margin-left:50px;">

                               <input type="checkbox" id="poolOn">

                               <span class="check"></span>

                               &nbsp;监控程序池

                           </label>          

                           <label class="switch" style="float:left;display:inline;margin-left:50px;">

                               <input type="checkbox" checked id="urlOn">

                               <span class="check"></span>

                               &nbsp;监控Url返回200

                           </label>          

                         

                       </div>

                   </div>

                   <div class="row" id="urlDiv">

                       <div class="span8">

                           <div style="float:left;display:inline;margin-top:10px;margin-left:10px;font-weight:bold;">

                               url:

                           </div>

                           <!-- Input with clear helper -->

                           <div class="input-control text" data-role="input" style="float:left;display:inline;margin-left:10px;width:566px">

                               <input type="text" id="url">

                               <button class="button helper-button clear"><span class="mif-cross"></span></button>

                           </div>    

                       

                       </div>

                   </div>

                   <div class="row">

                       <div class="span8">

                           <div style="float:left;display:inline;margin-left:10px;font-weight:bold;">

                               收件人:

                           </div>

                           <div class="input-control textarea " data-role="input-control" style="float:left;display:inline;width:100%">

                               <textarea id="recievers"></textarea>

                           </div>

                       </div>

                   </div>

               </div>

               <div style="display:inline-block; text-align:right;width:100%">

                   <button id="comitSettingBtn" class="primary"><i class="icon-checkmark on-left"></i>确认</button>&nbsp;

                   <button id="cancelCommitBtn" class="danger"><i class=" icon-cancel-2 on-left"></i>取消</button>&nbsp;

                   <button id="closeCommitBtn" class="warning"><i class=" icon-cancel-2 on-left"></i>关闭</button>

               </div>

           </div>

       </div>

   </div>


  



js代码:


////// 页面初始化加载 //////

$(document).ready(function () {

});

function showDialog(dialogId) {

   var dialog = $("#" + dialogId).data('dialog');

   if (!dialog.element.data('opened')) {

       dialog.open();

   } else {

       dialog.close();

   }

}

function closeDialog(dialogId) {

   var dialog = $("#" + dialogId).data('dialog');

   if (!dialog.element.data('closed')) {

       dialog.close();

   } else {

       dialog.open();

   }

}

var RunStatusMonitorConfigListPage = {

   refresh: function () {

       window.location.href = window.location.href;

   }

}

var eidtRunStatusMonitorConfigPage = {

   showEditDialog: function (dialogId, configId) {

       eidtRunStatusMonitorConfigPage.bingConfigDialogInfo(configId);

       $('#comitSettingBtn').click(function () {

           eidtRunStatusMonitorConfigPage.commitMonitorConfig();            

       });

       $('#cancelCommitBtn').click(function () {

           eidtRunStatusMonitorConfigPage.showEditDialog(dialogId, configId);

       });

       $('#closeCommitBtn').click(function () {

           closeDialog(dialogId);

       });

       showDialog(dialogId);

   },

   bingConfigDialogInfo: function (id) {

       var subSelect = $("#sub");

       var templateSelect = $("#template");

       var nodeSelect = $("#node");

       // 绑定数据

       if (id != 0) {

           $.getJSON('/RunMonitor/GetMonitorSetting?id=' + id, null, function (data) {

               if (data) {

                   subSelect.empty();

                   subSelect.append("<option></option><option value=" + data.Data.SubId + " select>" + data.Data.SubName + "</option>");

                   templateSelect.empty();

                   templateSelect.append("<option></option><option value=" + data.Data.DomainId + " select>" + data.Data.DomainName + "</option>");

                   nodeSelect.empty();

                   nodeSelect.append("<option></option><option value=" + data.Data.NodeId + " select >" + data.Data.NodeName + "</option>");

                   $("#ipAndPoolInfoDiv").removeAttr("style");

                   $("#ip").html(data.Data.Ip);

                   $("#apppool").html(data.Data.PoolName);

                   if (data.Data.TurnOn == 1) {

                       $("#turnOn").attr("checked", true);

                   }

                   else {

                       $("#turnOn").attr("checked", false);

                   }

                   if (data.Data.EmailOn == 1) {

                       $("#emailOn").attr("checked", true);

                   }

                   else {

                       $("#emailOn").attr("checked", false);

                   }

                   if (data.Data.CheckSiteOn == 1) {

                       $("#siteOn").attr("checked", true);

                   }

                   else {

                       $("#siteOn").attr("checked", false);

                   }

                   if (data.Data.CheckPoolOn == 1) {

                       $("#poolOn").attr("checked", true);

                   }

                   else {

                       $("#poolOn").attr("checked", false);

                   }

                   if (data.Data.CheckUrlOn == 1) {

                       $("#urlOn").attr("checked", true);

                   }

                   else {

                       $("#urlOn").attr("checked", false);

                   }

                   $("#monitorName").val(data.Data.Name);

                   $("#url").val(data.Data.Url);

                   $("#recievers").val(data.Data.Reciever);

               }

           });

       }

       else {

           // 绑定环境        

           subSelect.empty();

           $.getJSON('/env/GetAllEnvSubs', null, function (data) {

               if (data.StateCode == 0) {

                   var content = "<option></option>";

                   $.each(data.Data, function (idx, item) {

                       content += "<option value=" + item.EnvSubId + ">" + item.EnvSubName + "</option>"

                   });

                   subSelect.append(content);

               }

           });

           // 绑定站点          

           templateSelect.empty();

           $.getJSON('/DomainTemplate/GetAllEnvDomainTemplates', null, function (data) {

               if (data.StateCode == 0) {

                   var content = "<option></option>";

                   $.each(data.Data, function (idx, item) {

                       content += "<option value=" + item.Id + ">" + item.DomainName + "</option>"

                   });

                   templateSelect.append(content);

               }

           });

           //绑定onchange事件

           templateSelect.change(function () {

               // 绑定子站点

               eidtRunStatusMonitorConfigPage.bingDomainNode(templateSelect.val(), 0);

           });

       }

   },

   bingDomainNode: function (templateid, nodeid) {

       var nodeSelect = $("#node");

       nodeSelect.empty();

       $.getJSON('/DomainTemplate/GetDomainNodeTemplate?id=' + templateid, null, function (data) {

           if (data.StateCode == 0) {

               var content = "<option select>请选择子站点</option><option>全部</option>";

               $.each(data.Data, function (idx, item) {

                   content += "<option value=" + item.Id + ">" + item.NodeName + "</option>"

               });

               nodeSelect.append(content);

               if (nodeid != 0) {

                   $("#node option[@value='" + nodeid + "']").attr("selected", "true")

               }

               else {

                   $("#monitorName").text = $("#domain").val() + "-" + $("#template").val();

               }

           }

       });

   },

   commitMonitorConfig: function () {

       var config = new Object();

       config.Name = $("#monitorName").val();

       config.SubId = $("#sub").val();

       config.SubName = $("#sub").find("option:selected").text();

       config.DomainId = $("#template").val();

       config.DomainName = $("#template").find("option:selected").text();

       config.NodeId = $("#node").val();

       config.NodeName = $("#node").find("option:selected").text();

       if ($("#turnOn").is(':checked')) {

           config.TurnOn = "1";

       }

       else {

           config.TurnOn = "0";

       }

       if ($("#emailOn").is(':checked')) {

           config.EmailOn = "1";

       }

       else {

           config.EmailOn = "0";

       }

       if ($("#siteOn").is(':checked')) {

           config.CheckSiteOn = "1";

       }

       else {

           config.CheckSiteOn = "0";

       }

       if ($("#poolOn").is(':checked')) {

           config.CheckPoolOn = "1";

       }

       else {

           config.CheckPoolOn = "0";

       }

       if ($("#urlOn").is(':checked')) {

           config.CheckUrlOn = "1";

       }

       else {

           config.CheckUrlOn = "0";

       }

       config.Url = $("#url").val();

       config.Reciever = $("#recievers").val();

       if (config.NodeName == "全部") {

           $("#node option").each(function () { //遍历全部option

               var txt = $(this).text(); //获取option的内容

               if (txt != "全部") //如果不是“全部”和"请选择子站点"

               {

                   config.NodeName = txt;

                   eidtRunStatusMonitorConfigPage.postMonitorConfig(config);

               }

           });

       }

       else {

           eidtRunStatusMonitorConfigPage.postMonitorConfig(config);

       }

   },

   postMonitorConfig: function (postData) {

       var url = '/RunMonitor/CommitMonitorConfig';

       var pack = new Object();

       pack.Token = $.readCookie('accessToken');

       pack.config = postData;

       var submitData = JSON.stringify(pack);

       $.ajax({

           type: "POST",

           url: url,

           data: submitData,

           dataType: "json",

           contentType: "application/json",

           crossDomain: true,

           success: function (results) {

               if (results.Data == "0") {

                   $.note(null, "修改" + name + "运行状态监控配置成功!");

                   RunStatusMonitorConfigListPage.refresh();

               }

               else {

                   $.note(null, "修改" + name + "运行状态监控配置失败!" + results.Message, 'error');

               }

           },

           error: function (xhr, status, error) {

               $.note(null, "发送修改" + name + "运行状态监控配置请求失败!", 'error');

           }

       });

   },

   postTurnOn: function (id) {

       token = $.readCookie('accessToken');

       $.post("/RunMonitor/TurnOnMonitor", { "id": id, "alis": token }, function (data) {

           if (data.StateCode == 0) {

               $.note(null, '开启监控成功.');

           }

           else {

               $.note(null, '开启监控失败.', "error");

           }

       });

   },

   postTurnOff: function (id) {

       token = $.readCookie('accessToken');

       $.post("/RunMonitor/TurnOffMonitor", { "id": id, "alis": token }, function (data) {

           if (data.StateCode == 0) {

               $.note(null, '关闭监控成功.');

           }

           else {

               $.note(null, '关闭监控失败.', "error");

           }

       });

   },

   startInvoke: function (sender) {

       var parentObj = sender.parent();

       parentObj.empty();

       parentObj.append('<img src="../img/loading.jpg" style="width:30px;" id="iloader" />');

       var ip = parentObj.next().next().next().next().next().text();

       var url = 'http://' + ip + ':8167/Monitor/Ping';

       $.ajax({

           type: "POST",

           url: url,

           data: null,

           dataType: "json",

           contentType: "application/json",

           crossDomain: true,

           success: function (results) {

               parentObj.empty();

               var reg = /\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}/;

               if (reg.test(results)) {

                   $.note(null, '唤醒' + ip + '监控成功!');

                   parentObj.append('<button class="link invokesuccessbtn" style="margin-left:30px;"><i class="icon-checkmark fg-green" style="margin-left:45px;"></i></button>');

                   $('.invokesuccessbtn').click(function () {

                       monitorconfigpage.startInvoke($(this));

                   });

               } else {

                   $.note('Error', '唤醒' + ip + '失败!', 'error');

                   parentObj.append('<button class="link invokefailbtn" style="margin-left:30px;"><i class="icon-cancel-2 fg-red"></i></button>');

                   $('.invokefailbtn').click(function () {

                       monitorconfigpage.startInvoke($(this));

                   });

               }

           },

           error: function (xhr, status, error) {

               $.note('Error', '唤醒' + ip + '失败!' + error, 'error');

               parentObj.empty();

               parentObj.append('<button class="link invokefailbtn" style="margin-left:30px;"><i class="icon-cancel-2 fg-red"></i></button>');

               $('.invokefailbtn').click(function () {

                   monitorconfigpage.startInvoke($(this));

               });

           }

       });

   },

   deleteConfig:function(id)

   {

       var r = confirm("确定删除该配置信息?")

       if (r == true) {

           var config = new Object();

           config.id = id;

       }

       else {

           $.note(null, "你已取消删除配置信息id:" + id);

       }

   },

   postDeleteConfig:function(postData)

   {

       var url = '/RunMonitor/DeleteMonitorConfig';

       var pack = new Object();

       pack.Token = $.readCookie('accessToken');

       pack.config = postData;

       var submitData = JSON.stringify(pack);

       $.ajax({

           type: "POST",

           url: url,

           data: submitData,

           dataType: "json",

           contentType: "application/json",

           crossDomain: true,

           success: function (results) {

               if (results.Data == "0") {

                   $.note(null, "删除运行状态监控配置成功!");

                   RunStatusMonitorConfigListPage.refresh();

               }

               else {

                   $.note(null, "删除运行状态监控配置失败!" + results.Message, 'error');

               }

           },

           error: function (xhr, status, error) {

               $.note(null, "发送删除运行状态监控配置请求失败!", 'error');

           }

       });

}

}


 


Controller代码:


using RestSharp;

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using ControllerBase = xxx.xxx.QA.Platform.Common.ControllerBase;

namespace xxx.xxx.QA.Platform.Environment.Controllers.Coverage

{

   public class RunMonitorController : ControllerBase

   {

       //

       // GET: /RunMonitor/

       public ActionResult Index()

       {

           IList <EnvRunStatusMonitorConfig> configList = EnvRunStatusMonitorConfigBiz.GetRunStatusMonitorConfig();

           return View(configList);

       }

       public JsonResult GetMonitorSetting(int id)

       {

           var resp = new APIResponse<EnvRunStatusMonitorConfig>()

           {

               StateCode = StateCode.Success,

               Message = ""

           };

           try

           {

               EnvRunStatusMonitorConfig config = EnvRunStatusMonitorConfigBiz.GetRunStatusMonitorConfig(id);

               resp.Data = config;

           }

           catch (Exception ex)

           {

               resp.StateCode = StateCode.Fail;

               resp.Message += ex.ToString();

           }

           return Json(resp, JsonRequestBehavior.AllowGet);

       }

       public JsonResult TurnOnMonitor(int id, string alis)

       {

           var resp = new APIResponse<string>()

           {

               StateCode = StateCode.Success,

               Message = ""

           };

           var accessToken = LoginSecurity.DecodeAccessToken(alis);

           if (VerifyToken(ref accessToken, ref resp, "EnvIISResetOperator"))

           {

               try

               {

                   EnvRunStatusMonitorConfig config = EnvRunStatusMonitorConfigBiz.GetRunStatusMonitorConfig(id);

                   EnvRunStatusMonitorConfigBiz.TurnOnEnvRunStatusMonitorConfig(config);

                   string desc = string.Format("{0} turn on run monitor {1}  ", accessToken.Alias, config.DomainId + "-" + config.Id);

                   int machineid = config.Id;

                   EnvOperationLogBiz.LogTurnOnRunMonitor(machineid, accessToken.Alias, desc);

               }

               catch (Exception ex)

               {

                   resp.StateCode = StateCode.Fail;

                   resp.Message += ex.ToString();

               }

           }

           return Json(resp, JsonRequestBehavior.DenyGet);

       }

       public JsonResult TurnOffMonitor(int id, string alis)

       {

           var resp = new APIResponse<string>()

           {

               StateCode = StateCode.Success,

               Message = ""

           };

           var accessToken = LoginSecurity.DecodeAccessToken(alis);

           if (VerifyToken(ref accessToken, ref resp, "EnvIISResetOperator"))

           {

               try

               {

                   EnvRunStatusMonitorConfig config = EnvRunStatusMonitorConfigBiz.GetRunStatusMonitorConfig(id);

                   EnvRunStatusMonitorConfigBiz.TurnOffEnvRunStatusMonitorConfig(config);

                   string desc = string.Format("{0} turn off run monitor {1}  ", accessToken.Alias, config.DomainId + "-" + config.Id);

                   int machineid = config.Id;

                   EnvOperationLogBiz.LogTurnOffRunMonitor(machineid, accessToken.Alias, desc);

               }

               catch (Exception ex)

               {

                   resp.StateCode = StateCode.Fail;

                   resp.Message += ex.ToString();

               }

           }

           return Json(resp, JsonRequestBehavior.DenyGet);

       }

       public JsonResult CommitMonitorConfig(RunStatusMonitorConfigPack pack)

       {

           var resp = new APIResponse<string>()

           {

               StateCode = StateCode.Success,

               Message = ""

           };

           var accessToken = LoginSecurity.DecodeAccessToken(pack.Token);

           if (VerifyToken(ref accessToken, ref resp, "EnvIISResetOperator"))

           {

               try

               {

                   EnvRunStatusMonitorConfig config = pack.config;

                   config.DomainName = DomainUtil.GetDomainName(config.SubName, config.DomainName);

                   // 根据环境跟站点获取机器

                   IEnumerable<EnvDomainConfig> domainConfigs = EnvDomainConfigBiz.GetAllDomainsByEnvAndDomainName(config.SubName, config.DomainName);

                   if (domainConfigs != null && domainConfigs.Count() >= 1)

                   {

                       EnvDomainConfig domainConfig = domainConfigs.First();

                       EnvMachine machine = EnvMachineBiz.FindByMachineName(domainConfig.MachineName);

                       config.MachineName = domainConfig.MachineName;

                       config.MachineId = machine.Id;

                       config.Ip = machine.IP;

                       // 查询机器上是否存在该子站点

                       var client = new RestClient("http://" + machine.IP + ":8167");

                       string nodename = config.NodeName;

                       string path = nodename.IndexOf("/") < 0 ? "/" + nodename : nodename;

                       var request = new RestRequest("/IIS/GetAppPoolNameBySite?siteName=" + config.DomainName + "&path=" + path, Method.GET);

                       var response = client.Execute(request);

                       if (!response.Content.ToString().Equals("") && response.Content.ToString().IndexOf("无效的应用程序路径") < 0)

                       {

                           config.PoolName = response.Content.ToString().Replace("\"", "");

                           EnvRunStatusMonitorConfigBiz.CommitRunStatusMonitorConfig(config);

                           resp.Data = "0";

                       }

                       // 存在子站点,查询程序池,提交

                       else

                       {

                           // 程序池不存在,返回102,提示请检查站点是否最近有更新

                           resp.Data = "102";

                           resp.Message = "站点:" + config.DomainName + "子站点" + config.NodeName + "的程序池不存在, 请检查站点是否最近有更新";

                       }

                   }

                   else

                   {

                       // 机器不存在,返回101,提示请检查该站点是否部署

                       resp.Data = "101";

                       resp.Message = "环境:" + config.SubName + "站点" + config.DomainName + "的机器不存在, 请检查站点是否部署";

                   }

                   // EnvAppPoolMonitorConfigBiz.CommitAppPoolMonitorConfigInfo(pack.config);

               }

               catch (Exception ex)

               {

                   resp.StateCode = StateCode.Fail;

                   resp.Message += ex.ToString();

                   resp.Data = "1";

               }

           }

           return Json(resp, JsonRequestBehavior.AllowGet);

       }

       public JsonResult DeleteMonitorConfig(RunStatusMonitorConfigPack pack)

       {

           var resp = new APIResponse<string>()

           {

               StateCode = StateCode.Success,

               Message = ""

           };

           var accessToken = LoginSecurity.DecodeAccessToken(pack.Token);

           if (VerifyToken(ref accessToken, ref resp, "EnvIISResetOperator"))

           {

               try

               {

                   EnvRunStatusMonitorConfigBiz.DeleteEnvAppPoolMonitorConfig(pack.config.Id);

                   resp.Data = "0";

               }

               catch (Exception ex)

               {

                   resp.StateCode = StateCode.Fail;

                   resp.Message += ex.ToString();

                   resp.Data = "1";

               }

           }

           return Json(resp, JsonRequestBehavior.AllowGet);

       }

   }

   public class RunStatusMonitorConfigPack : PostPackBase

   {

       public EnvRunStatusMonitorConfig config { get; set; }

   }

}


 




2. 服务器端监控代码


监控站点程序池的状态,是放在该服务器上的EnvAgency里面


using FluentScheduler;

using NLog;

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

namespace xxx.xxx.QA.Platform.EnvAgent.Services.Tasks

{

   public class RunStatusMonitorTask : ITask

   {

       private static readonly object Locker = new object();

       private static bool _isRunning;

       private static readonly Logger Logger = LogManager.GetCurrentClassLogger();

       public void Execute()

       {

           if (_isRunning)

           {

               return;

           }

           ChangeState(true);

           try

           {

               Logger.Info("Monitor  start");

               EnvMachine envMachine = EnvMachineBiz.GetCurrentMachine();

               #region 监控站点

               IList<EnvRunStatusMonitorConfig> configList = EnvRunStatusMonitorConfigBiz.GetRunStatusSiteMonitorConfigByMachineId(envMachine.Id);

               foreach (EnvRunStatusMonitorConfig config in configList)

               {                    

                   DateTime dt = DateTime.Now.ToLocalTime();

                   bool siteStared = RunStatusMonitorUtil.IsSiteStarted(config.DomainName);

                   EnvRunStatusMonitorLogBiz.AddEnvRunSiteStatusMonitorLog(envMachine.Id, siteStared, dt);

                   if (!siteStared)

                   {

                       string reciever = config.Reciever;

                       string body = "";

                       body += "<h3>机器</h3>" + config.Ip + ")<br/><br/>";

                       body += "<h3>站点</h3>" + config.DomainName + ")<br/><br/>";

                       // 未设置情况默认为该账户

                       if (reciever == null || reciever.Equals(""))

                       {

                           reciever = "chenjz@Ctrip.com";

                       }

                       Mail.SendMailWithHtml2(reciever, "站点未启动预警:" + envMachine.Name+"-"+config.DomainName, body, "chenjz@Ctrip.com");

                       Logger.Info("Send 站点未开启预警 mail:" + body);

                   }

               }

               #endregion

               #region 监控程序池

               IList<EnvRunStatusMonitorConfig> configList2 = EnvRunStatusMonitorConfigBiz.GetRunStatusAppPoolMonitorConfigByMachineId(envMachine.Id);

               foreach (EnvRunStatusMonitorConfig config in configList2)

               {

                   DateTime dt = DateTime.Now.ToLocalTime();

                   bool poolStared = RunStatusMonitorUtil.IsAppPoolStarted(config.PoolName);

                   EnvRunStatusMonitorLogBiz.AddEnvRunSiteStatusMonitorLog(envMachine.Id, poolStared, dt);

                   if (!poolStared)

                   {

                       string reciever = config.Reciever;

                       string body = "";

                       body += "<h3>机器</h3>" + config.Ip + ")<br/><br/>";

                       body += "<h3>程序池</h3>" + config.PoolName + ")<br/><br/>";

                       // 未设置情况默认为该账户

                       if (reciever == null || reciever.Equals(""))

                       {

                           reciever = "chenjz@Ctrip.com";

                       }

                       Mail.SendMailWithHtml2(reciever, "程序池未启动预警:" + envMachine.Name + "-" + config.PoolName, body, "xxx@xxx.com");

                       Logger.Info("Send 程序池未开启预警 mail:" + body);

                   }

               }

               #endregion

               //监控URL放在主站点做比较合适

           }

           catch (Exception ex)

           {

               Logger.Error("MonitorTask异常信息:" + ex.ToString());

           }

           finally

           {

               ChangeState(false);

           }

       }

       private void ChangeState(bool running)

       {

           lock (Locker)

           {

               _isRunning = running;

           }

       }

 

   

   }

}




监控URL状态是放在环境系统平台里面


using FluentScheduler;

using NLog;

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

namespace xxx.xxx.QA.Platform.Environment.Services.Task

{

   public class RunStatusMonitorTask : ITask

   {

       private static readonly object Locker = new object();

       private static bool _isRunning;

       private static readonly Logger Logger = LogManager.GetCurrentClassLogger();

       public void Execute()

       {

           if (_isRunning)

           {

               return;

           }

           ChangeState(true);

           try

           {

               Logger.Info("Monitor  start");

               EnvMachine envMachine = EnvMachineBiz.GetCurrentMachine();

               #region 监控URL

               IList<EnvRunStatusMonitorConfig> configList = EnvRunStatusMonitorConfigBiz.GetRunStatusUrlMonitorConfig();

               foreach (EnvRunStatusMonitorConfig config in configList)

               {

                   DateTime dt = DateTime.Now.ToLocalTime();

                   bool urlStared = RunStatusMonitorUtil.IsUrlReturnOK(config.Url);

                   EnvRunStatusMonitorLogBiz.AddEnvRunSiteStatusMonitorLog(config.Id, urlStared, dt);

                   if (!urlStared)

                   {

                       string reciever = config.Reciever;

                       string body = "";

                       body += "<h3>Name</h3>" + config.Name + "<br/><br/>";

                       body += "<h3>URL</h3>" + config.Url + "<br/><br/>";

                       body += "<h3>环境</h3>" + config.SubName + "<br/><br/>";

                       body += "<h3>站点</h3>" + config.DomainName+ "<br/><br/>";

                       body += "<h3>子站点</h3>" + config.NodeName + "<br/><br/>";

                       body += "<h3>IP</h3>" + config.Ip + "<br/><br/>";

                       // 未设置情况默认为该账户

                       if (reciever == null || reciever.Equals(""))

                       {

                           reciever = "xxx@xxx.com";

                       }

                       Mail.SendMailWithHtml2(reciever, "URL未返回成功预警:" + config.Url, body, "chenjz@Ctrip.com");

                       Logger.Info("Send 站点未开启预警 mail:" + body);

                   }

               }            

               #endregion

           }

           catch (Exception ex)

           {

               Logger.Error("MonitorTask异常信息:" + ex.ToString());

           }

           finally

           {

               ChangeState(false);

           }

       }

       private void ChangeState(bool running)

       {

           lock (Locker)

           {

               _isRunning = running;

           }

       }

 

   }

}



监控核心代码:


using System;

using System.Collections.Generic;

using System.Linq;

using System.Net;

using System.Text;

namespace Ctrip.Hotel.QA.Platform.Core.Monitor

{

   public class RunStatusMonitorUtil

   {

       public static bool IsSiteStarted(string siteName)

       {

           return IISUtil.GetSiteState(siteName).Equals("Started");

       }

       public static bool IsAppPoolStarted(string poolName)

       {

           return IISUtil.getAppPoolSatus(poolName).Equals("Started");

       }

       public static bool IsUrlReturnOK(string url)

       {

           string status = GetResponseStatueCode(url);

           return  status.Equals("OK");  

       }

       public static string GetResponseStatueCode(string url)

       {

           HttpWebRequest webrequest = (HttpWebRequest)HttpWebRequest.Create(url);

           try

           {

               HttpWebResponse webreponse = (HttpWebResponse)webrequest.GetResponse();

               return webreponse.StatusCode.ToString();

           }

           catch (Exception ex)

           {

               return "";

           }

       }

   }

}


   /// <summary>

       /// 获取站点状态

       /// </summary>

       /// <param name="siteName"></param>

       /// <returns></returns>

       public static string GetSiteState(string siteName)

       {

           ServerManager manager = new ServerManager();


           Site site = manager.Sites[siteName];


           return site.State.ToString();

       }

       

             /// <summary>

       /// 获取程序池状态

       /// </summary>

       /// <param name="poolName"></param>

       /// <returns></returns>

       public static ObjectState getAppPoolSatus(string poolName)

       {

           ServerManager manager = new ServerManager();

               return manager.ApplicationPools[poolName].State;

       }


 



如此一来,功能在匆匆忙忙中实现了,但是想想如此现实,有些多余,



光Url的正常返回就能确定站点跟程序池的正常运行,配置url的话,就不需要配很多参数,如环境,站点,应用等,


或者配置站点,程序池,url做成三个页面


   配置站点:需要选择环境,站点名,需要检查该环境上配置该站点的机器,并把机器也保存在数据库中


   配置程序池:需要选择环境,站点,子站点,需要检查该环境上配置该站点的机器,并把机器也保存在数据库中,并且还需要去机子上查找该子站点对应的程序池名,把程序池也保存在数据库里


   配置URL:这个就简单了,只需要配置url就能了,直接在List也增删改查就行了



再加个结果的图标分析页就更好了