我有一组Web服务,想要添加一个跟踪层。 由于数量众多,我不想修改每个Web服务。 我希望在进入Web服务时记录日志:Web服务名称和参数。
最好的方法是什么?
P.S. 我使用asp.net和C#。
编辑: 我只想对Web服务进行包装,每个Web服务开头都有log(..)。
我有一组Web服务,想要添加一个跟踪层。 由于数量众多,我不想修改每个Web服务。 我希望在进入Web服务时记录日志:Web服务名称和参数。
最好的方法是什么?
P.S. 我使用asp.net和C#。
编辑: 我只想对Web服务进行包装,每个Web服务开头都有log(..)。
http://msdn.microsoft.com/en-us/library/system.web.services.protocols.soapextension.aspx
解释:
http://msdn.microsoft.com/en-us/library/esw638yk(vs.71).aspx
配置:
http://msdn.microsoft.com/en-us/library/b5e8e7kk(v=vs.71).aspx
<configuration>
<system.web>
<webServices>
<soapExtensionTypes>
<add type="{Type name}, {Assembly}" priority="1" group="0" />
</soapExtensionTypes>
</webServices>
</system.web>
</configuration>
protected void Application_BeginRequest(object sender, EventArgs e)
{
}
编辑--
试试PostSharp吧。这是最简单的获取此功能的方法。为了后人,我将保留下面的帖子,但请忽略它并使用PostSharp。
如果您的 Web 服务是 WCF,则应查看 http://msdn.microsoft.com/en-us/magazine/cc163302.aspx。
在每个步骤中,它们都提供了可插入的可扩展性点。 您可以使用这些可扩展性点来实现各种自定义行为,包括消息或参数验证、消息记录、消息转换等。
毫无疑问,这是 WCF 服务的最佳选择。 否则,如果它们只是 Web 服务,则可以使用 Unity 框架并连接截取器来完成相同的操作。
http://synapse.apache.org/Synapse_Configuration_Language.html#proxy,
http://synapse.apache.org/Synapse_Configuration_Language.html#send,
http://synapse.apache.org/Synapse_Configuration_Language.html#log
http://synapse.apache.org/Synapse_Samples.html#Sample0
http://synapse.apache.org/Synapse_Samples.html#ProxyServices
e.g.:
<definitions xmlns="http://ws.apache.org/ns/synapse"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ws.apache.org/ns/synapse http://synapse.apache.org/ns/2010/04/configuration/synapse_config.xsd">
<proxy name="StockQuoteProxy">
<target>
<endpoint>
<address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
</endpoint>
<outSequence>
<!-- log all attributes of messages passing through -->
<log level="full"/>
<!-- Send the message to implicit destination -->
<send/>
</outSequence>
</target>
<publishWSDL uri="file:repository/conf/sample/resources/proxy/sample_proxy_1.wsdl"/>
</proxy>
我维护一个开源Web服务框架,通过让所有Web服务继承自一个基类并进行自定义日志记录,您可以轻松实现此目标。
这里是一个基类示例,我在其中维护了一个分布式滚动日志,用于记录Redis中的所有异常 - 这是一个非常快速的NoSQL数据存储:
public object Execute(TRequest request)
{
try
{
//Run the request in a managed scope serializing all
return Run(request);
}
catch (Exception ex)
{
return HandleException(request, ex);
}
}
protected object HandleException(TRequest request, Exception ex)
{
var responseStatus = ResponseStatusTranslator.Instance.Parse(ex);
if (EndpointHost.UserConfig.DebugMode)
{
// View stack trace in tests and on the client
responseStatus.StackTrace = GetRequestErrorBody() + ex;
}
Log.Error("ServiceBase<TRequest>::Service Exception", ex);
//If Redis is configured, maintain rolling service error logs in Redis (an in-memory datastore)
var redisManager = TryResolve<IRedisClientsManager>();
if (redisManager != null)
{
try
{
//Get a thread-safe redis client from the client manager pool
using (var client = redisManager.GetClient())
{
//Get a client with a native interface for storing 'ResponseStatus' objects
var redis = client.GetTypedClient<ResponseStatus>();
//Store the errors in predictable Redis-named lists i.e.
//'urn:ServiceErrors:{ServiceName}' and 'urn:ServiceErrors:All'
var redisSeriviceErrorList = redis.Lists[UrnId.Create(UrnServiceErrorType, ServiceName)];
var redisCombinedErrorList = redis.Lists[UrnId.Create(UrnServiceErrorType, CombinedServiceLogId)];
//Append the error at the start of the service-specific and combined error logs.
redisSeriviceErrorList.Prepend(responseStatus);
redisCombinedErrorList.Prepend(responseStatus);
//Clip old error logs from the managed logs
const int rollingErrorCount = 1000;
redisSeriviceErrorList.Trim(0, rollingErrorCount);
redisCombinedErrorList.Trim(0, rollingErrorCount);
}
}
catch (Exception suppressRedisException)
{
Log.Error("Could not append exception to redis service error logs", suppressRedisException);
}
}
var responseDto = CreateResponseDto(request, responseStatus);
if (responseDto == null)
{
throw ex;
}
return new HttpResult(responseDto, null, HttpStatusCode.InternalServerError);
}
你考虑过编写自己的HttpModule吗?这样就不需要修改现有的Web服务代码了。你只需要将你的模块添加到每个web.config文件中即可。
如果这是你要找的内容,就在你的WCF配置文件中加上这段代码:
它会创建非常详细的日志,你可以使用Microsoft Service Trace Viewer来阅读。
<system.diagnostics>
<sources>
<source name="System.ServiceModel.MessageLogging" switchValue="Warning, ActivityTracing">
<listeners>
<add type="System.Diagnostics.DefaultTraceListener" name="Default">
<filter type="" />
</add>
<add name="ServiceModelMessageLoggingListener">
<filter type="" />
</add>
</listeners>
</source>
<source name="System.ServiceModel" switchValue="Warning, ActivityTracing"
propagateActivity="true">
<listeners>
<add type="System.Diagnostics.DefaultTraceListener" name="Default">
<filter type="" />
</add>
<add name="ServiceModelTraceListener">
<filter type="" />
</add>
</listeners>
</source>
</sources>
<sharedListeners>
<add initializeData="C:\ServiceLog.svclog"
type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
name="ServiceModelMessageLoggingListener" traceOutputOptions="Timestamp">
<filter type="" />
</add>
<add initializeData="C:\Tracelog.svclog"
type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
name="ServiceModelTraceListener" traceOutputOptions="Timestamp">
<filter type="" />
</add>
</sharedListeners>
</system.diagnostics>