microsoft / ApplicationInsights-SDK-Labs

Application Insights experimental projects repository
MIT License
61 stars 48 forks source link

Installing Client Dependency Telemetry Tracking With Code #128

Closed vmelamed closed 7 years ago

vmelamed commented 7 years ago

Hello, I am very happy to see the telemetry extended to the WCF clients too and am eager to give it a try. However we configure most of our services and clients in code (we have internal framework for that). Can you please include a short example of how to configure the client in code. I figure it should be something like:

ChannelFactory.Endpoint.EndpointBehaviors.Add(new ClientTelemetryEndpointBehavior());

Thanks

tomasr commented 7 years ago

Hi @vmelamed The readme explains how to configure dependency tracking in detail.

But yes, if you don't want to use the Profiler + ApplicationInsights.config, and want to use code, then doing what you mention is the right way.

Let me know if you have any other questions...

vmelamed commented 7 years ago

I was hoping for code configuration not config file configuration? Thanks

tomasr commented 7 years ago

Sorry, replied initially before I figured out what you were asking and edited the comment too late!

But yes, if you don't want to use the Profiler + ApplicationInsights.config, and want to use code, then simply adding the endpoint behavior is the right way to do it.

vmelamed commented 7 years ago

Thanks! This worked but: when I configure the server/client with WebHttpBinding it throws exception (see below), which by looking at the code, is understandable - there is no soapAction for webHttp. Am I doing something wrong here? Any suggestions?

ArgumentNullException
  Message                  = Value cannot be null.
  Parameter name: key
  ParamName                = key
  InnerException           = <null>
  TargetSite               = (Method): Void RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
  Source                   = mscorlib
  HResult                  = 0x80004003
  IsTransient              = False
  Data                     = (System.Collections.ListDictionaryInternal, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
  StackTrace               =

  Server stack trace:
     at System.Collections.Generic.Dictionary`2.FindEntry(TKey key)
     at System.Collections.Generic.Dictionary`2.TryGetValue(TKey key, TValue& value)
     at Microsoft.ApplicationInsights.Wcf.Implementation.ClientContract.TryLookupByAction(String soapAction, ClientOperation& operation) in C:\Projects\GitRepos\ApplicationInsights-SDK-Labs\WCF\Shared\Implementation\ClientContract.cs:line 31
     at Microsoft.ApplicationInsights.Wcf.Implementation.ClientTelemetryChannelBase.StartSendTelemetry(Message request, String method) in C:\Projects\GitRepos\ApplicationInsights-SDK-Labs\WCF\Shared\Implementation\ClientTelemetryChannelBase.cs:line 184
     at Microsoft.ApplicationInsights.Wcf.Implementation.ClientTelemetryRequestChannel.Request(Message message, TimeSpan timeout) in C:\Projects\GitRepos\ApplicationInsights-SDK-Labs\WCF\Shared\Implementation\ClientTelemetryRequestChannel.cs:line 47
     at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
     at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
     at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
     at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

  Exception rethrown at [0]:
     at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
     at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
     at vm.Aspects.Wcf.TestServer.IRequestResponse.GetStrings(Int32 numberOfStrings)
     at vm.Aspects.Wcf.TestServer.RequestResponseClient.GetStrings(Int32 numberOfStrings) in C:\Projects\GitRepos\vm\Aspects\Test\vm.Aspects.Wcf.TestServer\IRequestResponse.Client.cs:line 238
     at vm.Aspects.Wcf.TestServer.Program.Main(String[] args) in C:\Projects\GitRepos\vm\Aspects\Test\vm.Aspects.Wcf.TestServer\Program.cs:line 117
  RemoteStackTrace         =

  Server stack trace:
     at System.Collections.Generic.Dictionary`2.FindEntry(TKey key)
     at System.Collections.Generic.Dictionary`2.TryGetValue(TKey key, TValue& value)
     at Microsoft.ApplicationInsights.Wcf.Implementation.ClientContract.TryLookupByAction(String soapAction, ClientOperation& operation) in C:\Projects\GitRepos\ApplicationInsights-SDK-Labs\WCF\Shared\Implementation\ClientContract.cs:line 31
     at Microsoft.ApplicationInsights.Wcf.Implementation.ClientTelemetryChannelBase.StartSendTelemetry(Message request, String method) in C:\Projects\GitRepos\ApplicationInsights-SDK-Labs\WCF\Shared\Implementation\ClientTelemetryChannelBase.cs:line 184
     at Microsoft.ApplicationInsights.Wcf.Implementation.ClientTelemetryRequestChannel.Request(Message message, TimeSpan timeout) in C:\Projects\GitRepos\ApplicationInsights-SDK-Labs\WCF\Shared\Implementation\ClientTelemetryRequestChannel.cs:line 47
     at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
     at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
     at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
     at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
tomasr commented 7 years ago

Thanks for reporting! I will investigate.

I am a bit curious as to what the expected results would be?

At the very least, it definitely should not fail, but I'd want to also make the output useful, and I'm wondering if the core HTTP dependency tracing wouldn't actually do a better job altogether here, in which case it might be better to just ignore those requests and let the core HTTP dependency tracking deal with them.

Thoughts?

vmelamed commented 7 years ago

In the last couple of days I played with WCF+AI and was thinking about your question. You are right that there is a bit of overlap between the two dependencies but then again WCF is not only about HTTP and you can see net.tcp or net.pipe client calls just as well and this is nice. Even on HTTP protocols it feels a little more natural to see the WCF language in the event. This was the promise of WCF (sigh, not quite fulfilled) to be able to add new transports, serialization etc. protocols and still have the same business logic codebase, right? Related to that is why I would like to have a fine control on which clients write events to AI. In particular, I really would like to track the client calls, performance etc. to third party API-s.

tomasr commented 7 years ago

I've been looking at this and I think I know how to work this, but need to setup a more extensive escenario to test my ideas.

I also want to see if I can detect Web-based contracts and just ignore them, as another alternative (in which case, the standard HTTP-based dependency tracking would log them only once).