系统WebServic分布太久了, 都不知道哪些系统在用? 调用的哪些函数?于是乎,写一个Soap Extension, 再加一个页面,来查询一下。 先看一下配制说明,和效果 web.config中 system.web compila
系统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
;
}
}
}
}