-
Notifications
You must be signed in to change notification settings - Fork 0
/
RequestTrackingTelemetryModule.cs
142 lines (121 loc) · 4.68 KB
/
RequestTrackingTelemetryModule.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
namespace WcfApplicationInsights
{
using System;
using System.Net;
using System.ServiceModel.Channels;
using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.Extensibility.Implementation;
using WcfApplicationInsights.Implementation;
/// <summary>
/// Telemetry module that collects requests to WCF services.
/// </summary>
public sealed class RequestTrackingTelemetryModule : IWcfTelemetryModule
{
private TelemetryClient telemetryClient;
/// <summary>
/// Initializes a new instance of the <see cref="RequestTrackingTelemetryModule"/> class.
/// </summary>
public RequestTrackingTelemetryModule()
{
}
void ITelemetryModule.Initialize(TelemetryConfiguration configuration)
{
this.telemetryClient = new TelemetryClient(configuration);
this.telemetryClient.Context.GetInternalContext().SdkVersion = "wcf: " + SdkVersionUtils.GetAssemblyVersion();
}
void IWcfTelemetryModule.OnBeginRequest(IOperationContext operation)
{
if (operation == null)
{
throw new ArgumentNullException("operation");
}
if (this.telemetryClient == null)
{
return;
}
RequestTelemetry telemetry = operation.Request;
// if ASP.NET has already started the request, leave the start time alone.
if (operation.OwnsRequest)
{
telemetry.Start();
}
// TODO: server
// telemetry.Url = operation.EndpointUri;
// telemetry.Name = operation.OperationName;
telemetry.Properties["soapAction"] = operation.SoapAction;
var httpHeaders = operation.GetHttpRequestHeaders();
if (httpHeaders != null)
{
telemetry.Properties["httpMethod"] = httpHeaders.Method;
if (operation.ToHeader != null)
{
// overwrite it for WebHttpBinding requests
telemetry.Url = operation.ToHeader;
}
}
// run telemetry initializers here, while the request message is still open
this.telemetryClient.Initialize(telemetry);
}
void IWcfTelemetryModule.OnEndRequest(IOperationContext operation, Message reply)
{
if (operation == null)
{
throw new ArgumentNullException("operation");
}
if (this.telemetryClient == null)
{
return;
}
if (reply != null && reply.IsClosed())
{
WcfEventSource.Log.ResponseMessageClosed(nameof(RequestTrackingTelemetryModule), "OnEndRequest");
}
RequestTelemetry telemetry = operation.Request;
// make some assumptions
var isFault = false;
var responseCode = HttpStatusCode.OK;
if (reply != null && !reply.IsClosed())
{
isFault = reply.IsFault;
}
HttpResponseMessageProperty httpHeaders = operation.GetHttpResponseHeaders();
if (httpHeaders != null)
{
responseCode = httpHeaders.StatusCode;
if ((int)responseCode >= 400)
{
isFault = true;
}
}
else if (isFault)
{
responseCode = HttpStatusCode.InternalServerError;
}
// if the operation code has already marked the request as failed
// don't overwrite the value if we think it was successful
if (isFault || !telemetry.Success.HasValue)
{
telemetry.Success = !isFault;
}
telemetry.ResponseCode = responseCode.ToString("d");
if (telemetry.Url != null)
{
telemetry.Properties["protocol"] = telemetry.Url.Scheme;
}
// if the Microsoft.ApplicationInsights.Web package started
// tracking this request before WCF handled it, we
// don't want to track it because it would duplicate the event.
// Let the HttpModule instead write it later on.
if (operation.OwnsRequest)
{
telemetry.Stop();
this.telemetryClient.TrackRequest(telemetry);
}
}
void IWcfTelemetryModule.OnError(IOperationContext operation, Exception error)
{
}
}
}