Web Services Trace / Log

I have a set of web services and I want to add a trace layer. I do not want to change every web service, since I have a lot of them. I would like to write a log of every web service entry: web service name and parameters.

What is the best way to do this?

PS I am using asp.net and C #.

EDIT: I only want to wrap web services, as each one will have a log (..) at the beginning.

+6
c # logging web-services asmx trace
source share
7 answers

A common way to achieve this is to implement the SOAP extension. From there, you can intercept every request / response packet in raw SOAP. The example shows how to implement it, and the explanation describes how it works and how to configure it.

Example:

http://msdn.microsoft.com/en-us/library/system.web.services.protocols.soapextension.aspx

Explanation:

http://msdn.microsoft.com/en-us/library/esw638yk(vs.71).aspx

Configuration:

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> 
+6
source share

Add the Global.asax file of the global Class.asax application to your project and add the logging logic to the Application_BeginRequest () method. The sender object will contain the HTTP request and parameters. You can only filter .asmx requests and record them.

  protected void Application_BeginRequest(object sender, EventArgs e) { } 
+1
source share

EDIT--
Try PostSharp. This is the easiest way to get this functionality. For posterity, I will leave my post below, but just ignore it and use PostSharp.


If your web services are WCF, you should check out http://msdn.microsoft.com/en-us/magazine/cc163302.aspx .

At every step along the way, they provide extensibility points that you can connect. You can use these extensibility points to implement a wide range of custom actions, including checking messages or parameters, message logging, message conversion.

Without a doubt, this is a way to go to WCF services. Otherwise, if it's just web services, you can use the Unity infrastructure and connectivity and Interceptor to do the same.

+1
source share

I maintain an open source web services infrastructure that allows you to simply achieve this if all web services are inherited from the base class and the logging itself.

Here is an example of a base class where I maintain a distributed skating log for all exceptions in redis - a very fast NoSQL data warehouse:

 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 ie //'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); } 

Otherwise, for regular ASP.NET web services infrastructures, I would look at Global.asax events, in particular the Application_BeginRequest event, which fires every time a new request arrives.

0
source share

If the programming language is not important, you can put Apache Synapse as a proxy server in front of your services. Your customers will then send requests to Synapse, which will delegate the requests to your original services. The proxy server can be configured to do something with requests between them, such as logging.

For more information, see the following links:

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

A combination of the following examples may be used for you:

http://synapse.apache.org/Synapse_Samples.html#Sample0
http://synapse.apache.org/Synapse_Samples.html#ProxyServices

eg:.

 <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> 

0
source share

How about writing your own HttpModule ? This negates the need to touch existing web service code. You just need to add your module to every web.config file.

0
source share

I don’t know if this is what you are looking for, just add this to the WCF configuration file after "

This will create very extensive logging that you can read using the 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> 
-one
source share

All Articles