zoukankan      html  css  js  c++  java
  • 统计WebService的调用者、调用函数、运行时间

    系统WebServic分布太久了, 都不知道哪些系统在用? 调用的哪些函数?于是乎,写一个Soap Extension, 再加一个页面,来查询一下。

    先看一下配制说明,和效果

    web.config中

        <system.web>
            <compilation debug="true" targetFramework="4.0" />
          <!--<httpHandlers>
            <add path="dl" type="OA4.SOA.Impl.HttpHandler.DownloadAttach" verb="GET"/>
          </httpHandlers>-->
          <webServices>
            <soapExtensionTypes>
              <add type=" OA4.CommonLib.Soap.TimeWatchExtension,OACommonLib"
                  priority="1"
                  group="0" />
            </soapExtensionTypes>
          </webServices>
    
        </system.web>
    

      

    然后访问查询页面:

    当前运行:0
    
    最后记录:20,	3.0 (Call/S), 27.8 (MS/Call)
    Host:10.129.255.105,  UseTime:0, Time:2012-9-4 9:15:42, name:GetCanStarFlowList,Arg:AComp:=衡水分公司, ADept:=县公司, AUser:=杨立华
    Host:10.129.255.105,  UseTime:15.6249, Time:2012-9-4 9:15:42, name:GetAgendumList,Arg:sUserName:=杨立华, sCompany:=衡水分公司, sDepartment:=县公司, sDuty:=经理, sRole:=, type:=all, dbfield:=ReceiveTime, order:=ASC, pageSize:=25, pageNumber:=1, pageCount:=0, recordCount:=0
    Host:10.129.255.104,  UseTime:46.8747, Time:2012-9-4 9:15:43, name:GetBillData_done,Arg:ABillID:=54533f29-8979-4b1d-adf8-b8fbf2cf7678, year:=
    Host:10.129.255.104,  UseTime:0, Time:2012-9-4 9:15:43, name:GetCurrentActivityName,Arg:flowInstanceId:=54533f29-8979-4b1d-adf8-b8fbf2cf7678
    Host:10.129.255.218,  UseTime:15.6249, Time:2012-9-4 9:15:43, name:GetAgendumList,Arg:sUserName:=耿书芬, sCompany:=邯郸分公司, sDepartment:=广平分公司, sDuty:=, sRole:=, type:=all, dbfield:=ReceiveTime, order:=DESC, pageSize:=20, pageNumber:=1, pageCount:=0, recordCount:=0
    Host:10.129.255.216,  UseTime:15.6249, Time:2012-9-4 9:15:45, name:GetAgendumList,Arg:sUserName:=魏广芹, sCompany:=张家口分公司, sDepartment:=渠道管理中心, sDuty:=, sRole:=, type:=all, dbfield:=ReceiveTime, order:=DESC, pageSize:=20, pageNumber:=1, pageCount:=0, recordCount:=0
    Host:10.129.255.104,  UseTime:46.8747, Time:2012-9-4 9:15:46, name:GetUserInfo,Arg:userName:=caoruifen_sjz
    Host:10.129.255.104,  UseTime:0, Time:2012-9-4 9:15:46, name:GetDoingFlowInfo,Arg:activeInstId:=c1e1d9ef-6a8f-46e8-98d1-dedac3c6137c
    Host:10.129.255.104,  UseTime:0, Time:2012-9-4 9:15:46, name:GetActiveInstInfo,Arg:activeInstID:=c1e1d9ef-6a8f-46e8-98d1-dedac3c6137c, parentBillID:=47a88d95-05db-4c24-a18c-ff41620495a0
    Host:10.129.255.104,  UseTime:62.4996, Time:2012-9-4 9:15:46, name:GetBillData_done,Arg:ABillID:=e14d1f34-53b5-4824-afd9-f8207dc4bab3, year:=
    Host:10.129.255.104,  UseTime:15.6249, Time:2012-9-4 9:15:46, name:UpdateRead,Arg:ActivityInstanceID:=c1e1d9ef-6a8f-46e8-98d1-dedac3c6137c
    Host:10.129.255.104,  UseTime:15.6249, Time:2012-9-4 9:15:46, name:FindNextRouteReturnConnects,Arg:sFlowID:=ae76d210-85f3-403f-ba4b-485c72cbb96e, sFlowInstanceID:=e14d1f34-53b5-4824-afd9-f8207dc4bab3, sActivityID:=c16d997c-f471-49f1-adef-e64cad616d79
    Host:10.129.255.104,  UseTime:234.3735, Time:2012-9-4 9:15:47, name:GetBillData_done,Arg:ABillID:=da7276c9-80af-485a-975a-f881be30b0f2, year:=2008
    Host:10.129.255.105,  UseTime:15.6249, Time:2012-9-4 9:15:47, name:GetActiveInstInfo,Arg:activeInstID:=4b19dfbc-51e7-4a0f-b3ce-08e17e49f64b, parentBillID:=266d7ab5-57fe-48fc-9118-27b43d1e5f10
    Host:10.129.255.105,  UseTime:46.8747, Time:2012-9-4 9:15:47, name:GetBillData_done,Arg:ABillID:=32d11123-7ab0-4757-ba57-5d3e53b8eafe, year:=
    Host:10.129.255.105,  UseTime:31.2498, Time:2012-9-4 9:15:47, name:UpdateRead,Arg:ActivityInstanceID:=4b19dfbc-51e7-4a0f-b3ce-08e17e49f64b
    Host:10.129.255.105,  UseTime:0, Time:2012-9-4 9:15:47, name:FindNextRouteReturnConnects,Arg:sFlowID:=ae76d210-85f3-403f-ba4b-485c72cbb96e, sFlowInstanceID:=32d11123-7ab0-4757-ba57-5d3e53b8eafe, sActivityID:=12e9306a-5107-493f-8ac9-8966011bd0fc
    Host:10.129.255.104,  UseTime:0, Time:2012-9-4 9:15:47, name:GetCurrentActivityName,Arg:flowInstanceId:=da7276c9-80af-485a-975a-f881be30b0f2
    Host:10.129.255.104,  UseTime:0, Time:2012-9-4 9:15:47, name:GetWordField,Arg:flowInstID:=da7276c9-80af-485a-975a-f881be30b0f2
    Host:10.129.255.104,  UseTime:0, Time:2012-9-4 9:15:47, name:SaveFavorite,Arg:userName:=张翔凯, flowInstID:=7d03a4a1-07ff-4bdc-b2a4-cb381fec357f
    

      

    实现代码:Soap

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Web.Services.Protocols;
    using System.Web;
    using System.Collections.Specialized;
    using System.Collections.Concurrent;
    using System.Collections;
    using log4net;
    using System.Threading;
    
    namespace OA4.CommonLib.Soap
    {
        public class TimeWatchExtension : SoapExtension
        {
            protected static ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
    
            private static ConcurrentDictionary<Guid, WSInvokeInfo> running = new System.Collections.Concurrent.ConcurrentDictionary<Guid, WSInvokeInfo>();
    
            private static ConcurrentQueue<WSInvokeInfo> last = new ConcurrentQueue<WSInvokeInfo>();
    
            private static ConcurrentDictionary<string, ConcurrentQueue<WSInvokeInfo>> remoteUserHost = new ConcurrentDictionary<string, ConcurrentQueue<WSInvokeInfo>>();
    
    
            public static ConcurrentDictionary<Guid, WSInvokeInfo> Running { get { return running; } }
    
            public static ConcurrentQueue<WSInvokeInfo> LastInvoke { get { return last; } }
    
            public static RemoteHostInfo[] RemoteUserHost { get { return remoteUserHost.ToList().ConvertAll(d=>new RemoteHostInfo(){ Host = d.Key, LastInvoke = d.Value.ToArray()}).ToArray(); } }
    
            public static int MaxRunningMilliseconds = int.Parse(System.Configuration.ConfigurationManager.AppSettings["TimeWatchExtension.MaxRunningMilliseconds"] ?? "800");
    
            public static Timer timerSnap = null;
            static TimeWatchExtension()
            {
                timerSnap = new Timer(new TimerCallback(e => {
    
                    if (Running.Count > 0)
                    {
                        var running = Running.ToList();
    
                        running.ForEach(d => {
                            if (d.Value.UseTime.TotalMilliseconds > MaxRunningMilliseconds)
                            {
                                log.Warn(d.Value.ToString());
                            }
                        });
                    }
                
                }));
    
                timerSnap.Change(1000, 1000);
            }
    
    
    
            private WSInvokeInfo invokeInfo = new WSInvokeInfo();
            public override System.IO.Stream ChainStream(System.IO.Stream stream)
            {
                return stream;
            }
    
            public override object GetInitializer(Type serviceType)
            {
                return null;
            }
    
            public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
            {
                return null;
            }
    
            public override void Initialize(object initializer)
            {
    
            }
    
    
            public override void ProcessMessage(SoapMessage message)
            {
                if (message is SoapClientMessage)
                {
                    switch (message.Stage)
                    {
                        case SoapMessageStage.BeforeSerialize:
    
                            break;
    
    
                        case SoapMessageStage.AfterSerialize:
                            break;
    
    
                        case SoapMessageStage.BeforeDeserialize:
                            break;
    
                        // About to call methods
                        case SoapMessageStage.AfterDeserialize:
                            break;
    
                        // After Method call
                        default:
                            throw new Exception("No stage such as this");
                    }
    
                }
                else if (message is SoapServerMessage)
                {
                    SoapServerMessage msg = (SoapServerMessage)message;
                    switch (message.Stage)
                    {
                        case SoapMessageStage.BeforeDeserialize:
                            break;
    
                        case SoapMessageStage.AfterDeserialize:
                            {
                                //采集时间
                                this.invokeInfo.BeginInvokeTime = DateTime.Now;
                                //采集WebService方法名
                                this.invokeInfo.MethodName = message.MethodInfo.Name;
    
                                this.invokeInfo.UserHostAddress = System.Web.HttpContext.Current.Request.UserHostAddress;
    
    
                                this.invokeInfo.Args = new Dictionary<string, object>();
    
                                message.MethodInfo.InParameters.ToList().ForEach(d =>
                                    {
                                        this.invokeInfo.Args.Add(d.Name, message.GetInParameterValue(d.Position));
                                    });
    
                                running.TryAdd(this.invokeInfo.Id, this.invokeInfo);
    
                                {
                                    last.Enqueue(invokeInfo);
    
                                    if (last.Count > 20)
                                    {
                                        WSInvokeInfo removed;
                                        last.TryDequeue(out removed);
                                    }
                                }
                                {
                                    var queue = remoteUserHost.GetOrAdd(invokeInfo.UserHostAddress, uha => new ConcurrentQueue<WSInvokeInfo>());
                                    queue.Enqueue(invokeInfo);
                                    if (queue.Count > 5)
                                    {
                                        WSInvokeInfo removed;
                                        queue.TryDequeue(out removed);
                                    }
                                }
                            }
                            break;
    
                        case SoapMessageStage.BeforeSerialize:
                            {
                                //采集时间
                                this.invokeInfo.EndInvokeTime = DateTime.Now;
                                WSInvokeInfo removed;
                                running.TryRemove(this.invokeInfo.Id, out removed);
    
                                if (log.IsDebugEnabled)
                                {
                                    if (this.invokeInfo.UseTime.TotalMilliseconds > MaxRunningMilliseconds)
                                        log.Debug(this.invokeInfo.ToString());
                                }
                            }
                            break;
    
                        case SoapMessageStage.AfterSerialize:
                            break;
    
                        default:
                            throw new Exception("No stage such as this");
                    }
    
                }
            }
    
    
        }
    
        public class WSInvokeInfo
        {
            public WSInvokeInfo()
            {
                Id = Guid.NewGuid();
            }
            public Guid Id { get; private set; }
            public DateTime BeginInvokeTime { get; set; }
    
            public string MethodName { get; set; }
    
            public string UserHostAddress { get; set; }
    
    
            public DateTime? EndInvokeTime { get; set; }
    
            public Dictionary<string,object> Args { get; set; }
    
            public TimeSpan UseTime { get { return (EndInvokeTime.HasValue ? EndInvokeTime.Value : DateTime.Now) - BeginInvokeTime; } }
    
            public static string GetString(ICollection val)
            {
                var ret = new List<string>();
                var iter = val.GetEnumerator();
                while (iter.MoveNext())
                {
                    if (iter.Current is ICollection)
                        ret.Add(GetString((ICollection)iter.Current));
                    else
                        ret.Add(iter.Current.ToString());
                }
    
                return string.Concat("[", string.Join(", ", ret.ToArray()), "]");
            }
    
    
            public override string ToString()
            {
                return string.Format("Host:{0},  UseTime:{1}, Time:{2}, name:{3},Arg:{4}",
                    this.UserHostAddress ?? "none",
                    this.UseTime.TotalMilliseconds,
                    this.BeginInvokeTime,
                    this.MethodName ?? "unkown",
                    string.Join(", ", this.Args.ToList().ConvertAll(d => string.Format("{0}:={1}", d.Key, d.Value == null ? "null" : (d.Value is ICollection ? GetString((ICollection)d.Value) : d.Value.ToString()))).ToArray()));
            }
    
        }
    
        public class RemoteHostInfo
        {
            public string Host { get; set; }
    
            public WSInvokeInfo[] LastInvoke { get; set; }
        }
    
    }
    

      

    查看页面:

    <%@ WebHandler Language="C#" Class="SoapUtil.ServerStat" %>
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using OA4.CommonLib.Soap;
    
    namespace SoapUtil
    {
        /// <summary>
        /// Alive 的摘要说明
        /// </summary>
        public class ServerStat : IHttpHandler
        {
    
            public void ProcessRequest(HttpContext context)
            {
                context.Response.ContentType = "text/plain";
                var resp = context.Response;
                try
                {
                    var running = TimeWatchExtension.Running.ToList();
    
                    resp.Write(string.Format("当前运行:{0}\n{1}",
                                            running.Count,
                                            string.Join("\n", running.ConvertAll(d =>
                                            {
                                                var ret = "exception";
    
                                                try { ret = d.Value.ToString(); }
                                                catch (Exception ex)
                                                {
                                                    ret = string.Concat(ret, ",", d.Value.MethodName, ",", d.Value.UserHostAddress, ",", d.Value.BeginInvokeTime.ToString());
                                                }
                                                return ret;
                                            }).ToArray())
                                            )
                               );
    
                    var last = TimeWatchExtension.LastInvoke.ToList();
                    {
                        var strInfo = "";
                        if (last.Count > 1)
                        {
                            var f = last.First();
                            TimeSpan ts = DateTime.Now - f.BeginInvokeTime;
                            var speed = last.Count / ts.TotalSeconds;
                            var avgUseTime = last.Average(d => d.UseTime.Milliseconds);
    
    
                            strInfo = string.Format("{0:0.0} (Call/S), {1:0.0} (MS/Call)", speed, avgUseTime);
                        }
                        else
                        {
    
                        }
                        resp.Write(string.Format("\n最后记录:{0},\t{1}\n{2}",
                                               last.Count,
                                               strInfo,
                                               string.Join("\n", last.ConvertAll(d =>
                                               {
                                                   var ret = "exception";
    
                                                   try { ret = d.ToString(); }
                                                   catch (Exception ex)
                                                   {
                                                       ret = string.Concat(ret, ",", d.MethodName, ",", d.UserHostAddress, ",", d.BeginInvokeTime.ToString());
                                                   }
                                                   return ret;
                                               }).ToArray())
                                               )
                                  );
                    }
    
                    resp.Write("\n");
                    var userHost = TimeWatchExtension.RemoteUserHost;
                    Array.ForEach(userHost, info =>
                        {
                            var invoke = info.LastInvoke.ToList();
                            if (invoke.Count > 1)
                            {
                                var f = invoke.First();
    
                                TimeSpan ts = DateTime.Now - f.BeginInvokeTime;
                                var speed = invoke.Count / ts.TotalSeconds;
                                var avgUseTime = invoke.Average(d => d.UseTime.Milliseconds);
    
    
                                var strInfo = string.Format("{0:0.0} (Call/S), {1:0.0} (MS/Call)", speed, avgUseTime);
                                resp.Write("\n\n" + info.Host + "[" + strInfo + "]:");
                            }
                            else
                            {
                                resp.Write("\n\n" + info.Host + ":");
                            }
                            resp.Write(string.Format("\n最后记录:{0}\n{1}",
                                          invoke.Count,
                                          string.Join("\n", invoke.ConvertAll(d =>
                                          {
                                              var ret = "exception";
    
                                              try { ret = d.ToString(); }
                                              catch (Exception ex)
                                              {
                                                  ret = string.Concat(ret, ",", d.MethodName, ",", d.UserHostAddress, ",", d.BeginInvokeTime.ToString());
                                              }
                                              return ret;
                                          }).ToArray())
                                          )
                             );
                        });
    
                }
                catch (Exception ex)
                {
                    context.Response.Write(string.Format("ERROR:{0}",ex.Message));
                }
            }
    
            public bool IsReusable
            {
                get
                {
                    return false;
                }
            }
        }
    }
    

      

    QQ:273352165 evlon#126.com 转载请注明出处。
  • 相关阅读:
    字符串,列表和元组-3
    数据和表达式-2
    python3.6.2(32位)的安装-1
    HTTP协议
    bug无法重现
    当开发说不是BUG时怎么办
    Python流程分类初试
    私有,封装
    Python继承
    编译型语言和解释型语言
  • 原文地址:https://www.cnblogs.com/evlon/p/soapmonitor.html
Copyright © 2011-2022 走看看