用户登录
用户注册

分享至

c#实现服务器性能监控并发送邮件保存日志

  • 作者: huijhf5860555
  • 来源: 51数据库
  • 2021-11-19

客户端代码

复制代码 代码如下:

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://www.51sjk.com/Upload/Articles/1/0/296/296345_20210728140127099.jpg")> _
<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

软件
前端设计
程序设计
Java相关