客户端代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using System.Management;
using System.Configuration;
using System.Net;
using System.IO;
namespace MON.WS
{
public partial class Service : ServiceBase
{
//post 11.9
//卸载服务
//installutil /u F:\\XLFX-2\\XLFX\\MON.WS\\bin\\debug\\MON.WS.EXE
//安装服务
//installutil F:\\XLFX-2\\XLFX\\MON.WS\\bin\\debug\\MON.WS.EXE
object threadObj;
Thread jobThread;
Dictionary<string, PerformanceCounter> dicCounter;
Dictionary<string, ManagementObject> dicDisk;
public Service()
{
InitializeComponent();
}
/// <summary>
/// 服务启动
/// </summary>
/// <param name=\"args\"></param>
protected override void OnStart(string[] args)
{
threadObj = new object();
dicCounter = new Dictionary<string, PerformanceCounter>();
dicDisk = new Dictionary<string, ManagementObject>();
jobThread = new Thread(new ThreadStart(Job));
jobThread.IsBackground = true;
jobThread.Start();
}
/// <summary>
/// 服务停止
/// </summary>
protected override void OnStop()
{
if (jobThread.IsAlive)
{
jobThread.Abort();
jobThread.Join();
}
foreach (var obj in dicCounter.Values)
{
obj.Dispose();
}
foreach (var obj in dicDisk.Values)
{
obj.Dispose();
}
dicDisk.Clear();
dicCounter.Clear();
}
/// <summary>
/// 监控线程
/// </summary>
void Job()
{
while (true)
{
lock (threadObj)
{
//监控开始
try
{
var obj = new MONServiceClient.MONService();
var hn = Dns.GetHostName();
var ips = GetIpv4Address(hn);
if (ips.Count < 1)
{
obj.Dispose();
Thread.Sleep(60000);//如果服务器出错,那么就每分钟去检查一次
WriteLog(\"一个IPV4的地址也没有得到\");
continue;
}
DataSet ds = GetConfigDS(hn,ips,obj);
if (ds == null)
{
obj.Dispose();
Thread.Sleep(60000);
WriteLog(\"请检查WEBService和全局变量设置\");
continue;
}
int sleepTime;
try
{
sleepTime = Convert.ToInt32(ds.Tables[0].Rows[0][\"LOG_CIRC\"]) * 1000;//毫秒
}
catch
{
sleepTime = 60000;
}
if (sleepTime < 1)
{
sleepTime = 60000;
}
Thread.Sleep(sleepTime);
if (ds.Tables[1].Rows[0][\"S_ISWATCH\"].ToString() == \"0\")
{
//监控开关->关闭
obj.Dispose();
continue;
}
var arr = getWatchValue(ds).ToArray();
obj.UpdateServerStatus(arr);
obj.Dispose();
}
catch (Exception ex)
{
WriteLog(ex.Message);
}
//监控结束
}
}
}
/// <summary>
/// 获取配置信息
/// </summary>
/// <param name=\"ips\"></param>
/// <returns></returns>
DataSet GetConfigDS(string hn,List<IPAddress> ips,MONServiceClient.MONService obj)
{
DataSet ds;
try
{
if (ips.Count > 1)
{
ds = obj.GetMachineConfig(hn, ips[0].ToString(), ips[1].ToString());
}
else
{
ds = obj.GetMachineConfig(hn, ips[0].ToString(), \"\");
}
}
catch
{
ds = null;
}
return ds;
}
/// <summary>
/// 获取性能数组
/// </summary>
/// <param name=\"ds\"></param>
/// <returns></returns>
List<string> getWatchValue(DataSet ds)
{
var result = new List<string>();
result.Add(ds.Tables[1].Rows[0][\"LIST_ID\"].ToString());
result.Add(GetValue(ds.Tables[1].Rows[0][\"S_CPU\"].ToString()).ToString(\"F2\"));
result.Add(GetDiskValue(ds.Tables[1].Rows[0][\"S_DISK_APP\"].ToString()).ToString(\"F2\"));
result.Add(GetDiskValue(System.Environment.SystemDirectory.Substring(0, 2)).ToString(\"F2\"));
result.Add(GetValue(ds.Tables[1].Rows[0][\"S_MEMORY\"].ToString()).ToString(\"F2\"));
result.Add(GetValue(ds.Tables[1].Rows[0][\"S_FLOW_IN\"].ToString()).ToString(\"F2\"));
result.Add(GetValue(ds.Tables[1].Rows[0][\"S_FLOW_OUT\"].ToString()).ToString(\"F2\"));
result.Add(GetValue(ds.Tables[1].Rows[0][\"S_WEB_PORT\"].ToString()).ToString(\"F2\"));
result.Add(GetValue(ds.Tables[1].Rows[0][\"S_SQL_CONNECT\"].ToString()).ToString(\"F2\"));
result.Add(ds.Tables[1].Rows[0][\"CAMP_ID\"].ToString());
result.Add(ds.Tables[1].Rows[0][\"CICODE\"].ToString());
result.Add(ds.Tables[1].Rows[0][\"S_KIND\"].ToString());
return result;
}
/// <summary>
/// 获取IPV4的地址
/// </summary>
/// <param name=\"hn\"></param>
/// <returns></returns>
List<IPAddress> GetIpv4Address(string hn)
{
var result = new List<IPAddress>();
var ips = Dns.GetHostAddresses(hn);
foreach (var ip in ips)
{
if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
result.Add(ip);
}
}
return result;
}
/// <summary>
/// 获取性能计数器的值
/// </summary>
/// <param name=\"configStr\"></param>
/// <returns></returns>
double GetValue(string configStr)
{
try
{
if (!dicCounter.ContainsKey(configStr))
{
var arr = configStr.Split(\'#\');
var pc = new PerformanceCounter();
pc.CategoryName = arr[0];
pc.CounterName = arr[1];
pc.InstanceName = arr[2];
dicCounter.Add(configStr, pc);
}
return dicCounter[configStr].NextValue();
}
catch (Exception ex)
{
WriteLog(string.Format(\"计数器取值错误:{0}{1}{2}\", configStr, Environment.NewLine, ex.Message));
return -1;
}
}
/// <summary>
/// 获取磁盘信息的值
/// </summary>
/// <param name=\"key\"></param>
/// <returns></returns>
double GetDiskValue(string key)
{
try
{
if (!dicDisk.ContainsKey(key))
{
ManagementObject DiskInfo = new ManagementObject(string.Format(\"win32_logicaldisk.deviceid=\\\"{0}\\\"\", key));
dicDisk.Add(key, DiskInfo);
}
dicDisk[key].Get();
var s = Convert.ToDouble(dicDisk[key][\"Size\"]);
var l = Convert.ToDouble(dicDisk[key][\"FreeSpace\"]);
var d = (s - l) / s * 100;
return d;
}
catch (Exception ex)
{
WriteLog(string.Format(\"获取磁盘信息值错误:{0}{1}{2}\", key, Environment.NewLine, ex.Message));
return -1;
}
}
/// <summary>
/// 写本地日志
/// </summary>
/// <param name=\"text\"></param>
void WriteLog(string text)
{
try
{
var logDic = ConfigurationManager.AppSettings[\"LogDic\"];
int logDays;
try
{
logDays = Convert.ToInt32(ConfigurationManager.AppSettings[\"LogDays\"]);
}
catch
{
logDays = 7;
}
if (logDays < 1)
{
logDays = 7;
}
var fs = LogFileMon(logDic, logDays);
StreamWriter writer = new StreamWriter(fs);
writer.WriteLine(DateTime.Now.ToString());
writer.WriteLine(text);
writer.WriteLine(\"-----------------------------------------------------------\");
writer.Flush();
writer.Close();
fs.Close();
}
catch
{
//写日志出错就没办法了
}
}
/// <summary>
/// 维护日志文件
/// </summary>
/// <param name=\"logDic\"></param>
/// <param name=\"days\"></param>
FileStream LogFileMon(string logDic, int dayCount)
{
DirectoryInfo di = new DirectoryInfo(logDic);
//如果日志文件夹不存在则创建日志文件夹;
if (!di.Exists)
{
di.Create();
}
//当前应保存的日志数据
List<string> days = new List<string>();
for (var i = 0; i < dayCount; i++)
{
var d = DateTime.Now.AddDays(0 - i).ToString(\"yyyy-MM-dd\");
days.Add(string.Format(\"{0}.log\", d));
}
//删除没用的历史数据
foreach (var f in di.GetFiles())
{
if (!days.Contains(f.Name))
{
f.Delete();
}
}
//返回当前日志文件的数据流
var fileName = Path.Combine(logDic, days[0]);
var fs = File.Open(fileName, FileMode.Append,FileAccess.Write);
return fs;
}
}
}
服务端代码
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.ComponentModel
Imports System.Threading
Imports System.Collections.Generic
Imports System.Text
\' 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。
\' <System.Web.Script.Services.ScriptService()> _
<System.Web.Services.WebService(Namespace:=\"http://tempuri.org/\")> _
<System.Web.Services.WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<ToolboxItem(False)> _
Public Class MONService
Inherits System.Web.Services.WebService
<WebMethod()> _
Public Function GetMachineConfig(ByVal HostName As String, ByVal IP1 As String, ByVal IP2 As String) As DataSet
Dim sqlda As New data_source.WebTao.Public.SqlServerData
Try
Dim sSQL As String = \"select * from mon_server_list \" & _
\" where S_HOSTNAME =\'\" & HostName & \"\' and IP1 = \'\" & IP1 & \"\' and IP2 = \'\" & IP2 & \"\'\"
Dim dt As DataTable = sqlda.GetMytable(sSQL)
If dt.Rows.Count < 1 Then
sqlda.runSql(\"insert into mon_server_list (S_HOSTNAME,IP1,IP2,S_ISWATCH,CICODE,S_NAME,CAMP_ID,S_KIND,STATUS) values (\'\" & HostName & \"\',\'\" & IP1 & \"\',\'\" & IP2 & \"\',0,\'待确定\',\'待确定\',-1,0,0)\")
dt = sqlda.GetMytable(sSQL)
sqlda.runSql(\"INSERT INTO [MON_INFO] ([LIST_ID],[S_CPU],[S_DISK_APP],[S_DISK_SYS],[S_MEMORY],[S_FLOW_IN],[S_FLOW_OUT],[S_WEB_PORT],[S_SQL_CONNECT],[IN_TIME]) VALUES (\" & dt.Rows(0)(\"LIST_ID\").ToString() & \",-1,-1,-1,-1,-1,-1,-1,-1,\'\" & Now.ToString() & \"\') \")
End If
Dim result As DataSet = sqlda.GetMyDataSet(\"select * from MON_PARAMETER\")
result.Tables.Add(dt)
Return result
Catch ex As Exception
Return Nothing
End Try
End Function
<WebMethod()> _
Public Function UpdateServerStatus(ByVal ParamArray ValueArr() As String)
Dim sqlda As New data_source.WebTao.Public.SqlServerData
Try
Dim sSQL As String = \"UPDATE [MON_INFO] \" & _
\" SET \" & _
\" [S_CPU] = \" & ValueArr(1) & _
\" ,[S_DISK_APP] = \" & ValueArr(2) & _
\" ,[S_DISK_SYS] = \" & ValueArr(3) & _
\" ,[S_MEMORY] = \" & ValueArr(4) & _
\" ,[S_FLOW_IN] = \" & ValueArr(5) & _
\" ,[S_FLOW_OUT] = \" & ValueArr(6) & _
\" ,[S_WEB_PORT] = \" & ValueArr(7) & _
\" ,[S_SQL_CONNECT] = \" & ValueArr(8) & _
\" ,[IN_TIME] = \'\" & Now.ToString() & \"\'\" & _
\" WHERE LIST_ID = \" & ValueArr(0)
sqlda.runSql(sSQL)
\'没有策略
If ValueArr(9).Trim() = \"-1\" Or String.IsNullOrEmpty(ValueArr(9).Trim()) Then
Return 0
End If
\'找到策略
sSQL = \"select * from MON_CAMPAIGN_LIST where CAMP_ID = \" & ValueArr(9)
Dim dt As DataTable = sqlda.GetMytable(sSQL)
Dim Dic As New Dictionary(Of String, String)
Dic.Add(\"S_PRIORITY\", dt.Rows(0)(\"S_PRIORITY\").ToString())
Dic.Add(\"S_ACTION\", dt.Rows(0)(\"S_ACTION\").ToString())
\'验证策略
sSQL = \"select count(*) from MON_INFO where 1=1 and \" & dt.Rows(0)(\"S_NAME\").ToString & \" and LIST_ID = \" & ValueArr(0)
Dim FLAG = CType(sqlda.myExecuteScalar(sSQL), Integer)
\'没有超标
If FLAG < 1 Then
Return 0
End If
\'是否到了下一个轮训间隔
sSQL = \"select TOP 1 * from [MON_MAIL] WHERE list_id = \" & ValueArr(0) & \" ORDER BY S_SENDTIME DESC \"
dt = sqlda.GetMytable(sSQL)
Dim ts As TimeSpan = TimeSpan.MaxValue
If dt.Rows.Count > 0 Then
Dim thatTime As DateTime = CType(dt.Rows(0)(\"S_SENDTIME\"), DateTime)
ts = DateTime.Now.Subtract(thatTime)
End If
sSQL = \"select * from MON_PARAMETER\"
dt = sqlda.GetMytable(sSQL)
Dim circ As Integer = CType(dt.Rows(0)(\"MAIL_CIRC\"), Integer)
If ts.TotalSeconds < circ Then
Return 0
End If
\'异步发信
Dic.Add(\"S_TITLE\", dt.Rows(0)(\"S_TITLE\").ToString())
Dic.Add(\"MAIL_SMTP_SERVER\", dt.Rows(0)(\"MAIL_SMTP_SERVER\").ToString())
Dic.Add(\"MAIL_ACCOUNT\", dt.Rows(0)(\"MAIL_ACCOUNT\").ToString())
Dic.Add(\"MAIL_PASSWORD\", dt.Rows(0)(\"MAIL_PASSWORD\").ToString())
Dic.Add(\"MAIL_FROM\", dt.Rows(0)(\"MAIL_FROM\").ToString())
Dic.Add(\"MAIL_ADDRESS\", dt.Rows(0)(\"MAIL_ADDRESS\").ToString())
Dim sout As Double
Dim sin As Double
Try
sin = Convert.ToDouble(ValueArr(5)) / 1024.0
sout = Convert.ToDouble(ValueArr(6)) / 1024.0
Catch ex As Exception
sin = -1
sout = -1
End Try
Dim sb As New StringBuilder()
sb.AppendFormat(\"CPU使用率:{0}%<br />\", ValueArr(1))
sb.AppendFormat(\"内存使用率:{0}%<br />\", ValueArr(4))
sb.AppendFormat(\"系统磁盘使用率:{0}%<br />\", ValueArr(3))
sb.AppendFormat(\"文件磁盘使用率:{0}%<br />\", ValueArr(2))
sb.AppendFormat(\"网络下行流量IN:{0}KB/S<br />\", sin.ToString())
sb.AppendFormat(\"网络上行流量OUT:{0}KB/S<br />\", sout.ToString())
sb.AppendFormat(\"网站连接数:{0}<br />\", ValueArr(7))
sb.AppendFormat(\"数据库连接数:{0}<br />\", ValueArr(8))
Dim subject As String = String.Format(\"人力运营管理系统监控告警:{0}{1}\", ValueArr(10), IIf(ValueArr(11) = \"0\", \"WEB服务器\", \"数据库服务器\"))
Dim body As String = String.Format(\"{0}<br />{1}<br />{2}<br />{3}<br />{4}\", DateTime.Now.ToString(), Dic(\"S_PRIORITY\"), Dic(\"S_TITLE\"), sb.ToString(), Dic(\"S_ACTION\"))
\'TODO:oracle不支持~select @@identity
sSQL = \"INSERT INTO [MON_MAIL] ([LIST_ID] ,[S_SOURCE] ,[S_CONTENT] ,[S_ACTION] ,[S_PRIORITY] ,[S_ADDRESS] ,[STATUS] ,[S_SENDTIME]) VALUES \" & _
\"(\" & ValueArr(0) & \",\'\" & Dic(\"S_TITLE\") & \"\',\'\" & sb.ToString() & \"\',\'\" & Dic(\"S_ACTION\") & \"\',\'\" & Dic(\"S_PRIORITY\") & \"\',\'\" & dt.Rows(0)(\"MAIL_ADDRESS\").ToString() & \"\',0,\'\" & DateTime.Now.ToString() & \"\');select @@identity\"
Dim index As Integer = CType(sqlda.myExecuteScalar(sSQL), Integer)
Dic.Add(\"SUBJECT\", subject)
Dic.Add(\"BODY\", body)
Dic.Add(\"INDEX\", index)
Dic.Add(\"CONSTR\", sqlda.GetMyConnStr())
ThreadPool.QueueUserWorkItem(AddressOf SendMail, Dic)
Catch ex As Exception
End Try
End Function
Function SendMail(ByVal setting As Object) As Integer
Try
Dim Dic As Dictionary(Of String, String) = CType(setting, Dictionary(Of String, String))
Dim iSmtpSetting As New PublicFunction.SmtpSetting
iSmtpSetting.SmtpServer = Dic(\"MAIL_SMTP_SERVER\")
iSmtpSetting.SystemEmailAccount = Dic(\"MAIL_ACCOUNT\")
iSmtpSetting.SystemEmailAccountPassword = Dic(\"MAIL_PASSWORD\")
iSmtpSetting.SmtpAuthenticationType = 1
Dim result As Boolean = PublicFunction.Mail.SendMail(iSmtpSetting, Dic(\"MAIL_FROM\"), Dic(\"MAIL_ADDRESS\"), Dic(\"SUBJECT\"), Dic(\"BODY\"), True, System.Web.Mail.MailPriority.High, System.Text.Encoding.UTF8, New String() {})
Dim val As Integer = IIf(result, 1, 2)
Dim sqlda As New data_source.WebTao.Public.SqlServerData(Dic(\"CONSTR\"))
sqlda.runSql(\"update MON_MAIL set STATUS = \" & val & \" where MAIL_ID = \" & Dic(\"INDEX\"))
Catch ex As Exception
End Try
End Function
End Class