ServicePerformanceCountersV2.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. //------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------
  4. namespace System.ServiceModel.Diagnostics
  5. {
  6. using System.Collections.Generic;
  7. using System.Diagnostics.PerformanceData;
  8. using System.Runtime;
  9. using System.Security;
  10. using System.ServiceModel;
  11. using System.ServiceModel.Administration;
  12. sealed class ServicePerformanceCountersV2 : ServicePerformanceCountersBase
  13. {
  14. static object syncRoot = new object();
  15. static Guid serviceModelProviderId = new Guid("{890c10c3-8c2a-4fe3-a36a-9eca153d47cb}");
  16. static Guid serviceCounterSetId = new Guid("{e829b6db-21ab-453b-83c9-d980ec708edd}");
  17. private static readonly CounterSetInstanceCache counterSetInstanceCache = new CounterSetInstanceCache();
  18. // Double-checked locking pattern requires volatile for read/write synchronization
  19. static volatile CounterSet serviceCounterSet; // Defines the counter set
  20. CounterSetInstance serviceCounterSetInstance; // Instance of the counter set
  21. CounterData[] counters;
  22. internal ServicePerformanceCountersV2(ServiceHostBase serviceHost)
  23. : base(serviceHost)
  24. {
  25. if (serviceCounterSet == null)
  26. {
  27. lock (syncRoot)
  28. {
  29. if (serviceCounterSet == null)
  30. {
  31. CounterSet localCounterSet = CreateCounterSet();
  32. // Add the counters to the counter set definition.
  33. localCounterSet.AddCounter((int)PerfCounters.Calls, CounterType.RawData32, perfCounterNames[(int)PerfCounters.Calls]);
  34. localCounterSet.AddCounter((int)PerfCounters.CallsPerSecond, CounterType.RateOfCountPerSecond32, perfCounterNames[(int)PerfCounters.CallsPerSecond]);
  35. localCounterSet.AddCounter((int)PerfCounters.CallsOutstanding, CounterType.RawData32, perfCounterNames[(int)PerfCounters.CallsOutstanding]);
  36. localCounterSet.AddCounter((int)PerfCounters.CallsFailed, CounterType.RawData32, perfCounterNames[(int)PerfCounters.CallsFailed]);
  37. localCounterSet.AddCounter((int)PerfCounters.CallsFailedPerSecond, CounterType.RateOfCountPerSecond32, perfCounterNames[(int)PerfCounters.CallsFailedPerSecond]);
  38. localCounterSet.AddCounter((int)PerfCounters.CallsFaulted, CounterType.RawData32, perfCounterNames[(int)PerfCounters.CallsFaulted]);
  39. localCounterSet.AddCounter((int)PerfCounters.CallsFaultedPerSecond, CounterType.RateOfCountPerSecond32, perfCounterNames[(int)PerfCounters.CallsFaultedPerSecond]);
  40. localCounterSet.AddCounter((int)PerfCounters.CallDurationBase, CounterType.AverageBase, perfCounterNames[(int)PerfCounters.CallDurationBase]);
  41. localCounterSet.AddCounter((int)PerfCounters.CallDuration, CounterType.AverageTimer32, perfCounterNames[(int)PerfCounters.CallDuration]);
  42. localCounterSet.AddCounter((int)PerfCounters.SecurityValidationAuthenticationFailures, CounterType.RawData32, perfCounterNames[(int)PerfCounters.SecurityValidationAuthenticationFailures]);
  43. localCounterSet.AddCounter((int)PerfCounters.SecurityValidationAuthenticationFailuresPerSecond, CounterType.RateOfCountPerSecond32, perfCounterNames[(int)PerfCounters.SecurityValidationAuthenticationFailuresPerSecond]);
  44. localCounterSet.AddCounter((int)PerfCounters.CallsNotAuthorized, CounterType.RawData32, perfCounterNames[(int)PerfCounters.CallsNotAuthorized]);
  45. localCounterSet.AddCounter((int)PerfCounters.CallsNotAuthorizedPerSecond, CounterType.RateOfCountPerSecond32, perfCounterNames[(int)PerfCounters.CallsNotAuthorizedPerSecond]);
  46. localCounterSet.AddCounter((int)PerfCounters.Instances, CounterType.RawData32, perfCounterNames[(int)PerfCounters.Instances]);
  47. localCounterSet.AddCounter((int)PerfCounters.InstancesRate, CounterType.RateOfCountPerSecond32, perfCounterNames[(int)PerfCounters.InstancesRate]);
  48. localCounterSet.AddCounter((int)PerfCounters.RMSessionsFaulted, CounterType.RawData32, perfCounterNames[(int)PerfCounters.RMSessionsFaulted]);
  49. localCounterSet.AddCounter((int)PerfCounters.RMSessionsFaultedPerSecond, CounterType.RateOfCountPerSecond32, perfCounterNames[(int)PerfCounters.RMSessionsFaultedPerSecond]);
  50. localCounterSet.AddCounter((int)PerfCounters.RMMessagesDropped, CounterType.RawData32, perfCounterNames[(int)PerfCounters.RMMessagesDropped]);
  51. localCounterSet.AddCounter((int)PerfCounters.RMMessagesDroppedPerSecond, CounterType.RateOfCountPerSecond32, perfCounterNames[(int)PerfCounters.RMMessagesDroppedPerSecond]);
  52. localCounterSet.AddCounter((int)PerfCounters.TxFlowed, CounterType.RawData32, perfCounterNames[(int)PerfCounters.TxFlowed]);
  53. localCounterSet.AddCounter((int)PerfCounters.TxFlowedPerSecond, CounterType.RateOfCountPerSecond32, perfCounterNames[(int)PerfCounters.TxFlowedPerSecond]);
  54. localCounterSet.AddCounter((int)PerfCounters.TxCommitted, CounterType.RawData32, perfCounterNames[(int)PerfCounters.TxCommitted]);
  55. localCounterSet.AddCounter((int)PerfCounters.TxCommittedPerSecond, CounterType.RateOfCountPerSecond32, perfCounterNames[(int)PerfCounters.TxCommittedPerSecond]);
  56. localCounterSet.AddCounter((int)PerfCounters.TxAborted, CounterType.RawData32, perfCounterNames[(int)PerfCounters.TxAborted]);
  57. localCounterSet.AddCounter((int)PerfCounters.TxAbortedPerSecond, CounterType.RateOfCountPerSecond32, perfCounterNames[(int)PerfCounters.TxAbortedPerSecond]);
  58. localCounterSet.AddCounter((int)PerfCounters.TxInDoubt, CounterType.RawData32, perfCounterNames[(int)PerfCounters.TxInDoubt]);
  59. localCounterSet.AddCounter((int)PerfCounters.TxInDoubtPerSecond, CounterType.RateOfCountPerSecond32, perfCounterNames[(int)PerfCounters.TxInDoubtPerSecond]);
  60. localCounterSet.AddCounter((int)PerfCounters.MsmqPoisonMessages, CounterType.RawData32, perfCounterNames[(int)PerfCounters.MsmqPoisonMessages]);
  61. localCounterSet.AddCounter((int)PerfCounters.MsmqPoisonMessagesPerSecond, CounterType.RateOfCountPerSecond32, perfCounterNames[(int)PerfCounters.MsmqPoisonMessagesPerSecond]);
  62. localCounterSet.AddCounter((int)PerfCounters.MsmqRejectedMessages, CounterType.RawData32, perfCounterNames[(int)PerfCounters.MsmqRejectedMessages]);
  63. localCounterSet.AddCounter((int)PerfCounters.MsmqRejectedMessagesPerSecond, CounterType.RateOfCountPerSecond32, perfCounterNames[(int)PerfCounters.MsmqRejectedMessagesPerSecond]);
  64. localCounterSet.AddCounter((int)PerfCounters.MsmqDroppedMessages, CounterType.RawData32, perfCounterNames[(int)PerfCounters.MsmqDroppedMessages]);
  65. localCounterSet.AddCounter((int)PerfCounters.MsmqDroppedMessagesPerSecond, CounterType.RateOfCountPerSecond32, perfCounterNames[(int)PerfCounters.MsmqDroppedMessagesPerSecond]);
  66. localCounterSet.AddCounter((int)PerfCounters.CallsPercentMaxCalls, CounterType.RawFraction32, perfCounterNames[(int)PerfCounters.CallsPercentMaxCalls]);
  67. localCounterSet.AddCounter((int)PerfCounters.CallsPercentMaxCallsBase, CounterType.RawBase32, perfCounterNames[(int)PerfCounters.CallsPercentMaxCallsBase]);
  68. localCounterSet.AddCounter((int)PerfCounters.InstancesPercentMaxInstances, CounterType.RawFraction32, perfCounterNames[(int)PerfCounters.InstancesPercentMaxInstances]);
  69. localCounterSet.AddCounter((int)PerfCounters.InstancesPercentMaxInstancesBase, CounterType.RawBase32, perfCounterNames[(int)PerfCounters.InstancesPercentMaxInstancesBase]);
  70. localCounterSet.AddCounter((int)PerfCounters.SessionsPercentMaxSessions, CounterType.RawFraction32, perfCounterNames[(int)PerfCounters.SessionsPercentMaxSessions]);
  71. localCounterSet.AddCounter((int)PerfCounters.SessionsPercentMaxSessionsBase, CounterType.RawBase32, perfCounterNames[(int)PerfCounters.SessionsPercentMaxSessionsBase]);
  72. serviceCounterSet = localCounterSet;
  73. }
  74. }
  75. }
  76. // Create an instance of the counter set (contains the counter data).
  77. this.serviceCounterSetInstance = CreateCounterSetInstance(this.InstanceName);
  78. this.counters = new CounterData[(int)PerfCounters.TotalCounters]; // Cache to dodge dictionary lookups in ServiceModelInstance
  79. for (int i = 0; i < (int)PerfCounters.TotalCounters; i++)
  80. {
  81. this.counters[i] = this.serviceCounterSetInstance.Counters[i];
  82. this.counters[i].Value = 0;
  83. }
  84. }
  85. [Fx.Tag.SecurityNote(Critical = "Calls into Sys.Diag.PerformanceData.CounterSet..ctor marked as SecurityCritical", Safe = "No user provided data is passed to the call")]
  86. [SecuritySafeCritical]
  87. static CounterSet CreateCounterSet()
  88. {
  89. return new CounterSet(serviceModelProviderId, serviceCounterSetId, CounterSetInstanceType.Multiple);
  90. }
  91. [Fx.Tag.SecurityNote(Critical = "Calls into Sys.Diag.PerformanceData.CounterSetInstance.CreateCounterSetInstance marked as SecurityCritical", Safe = "No user provided data is passed to the call, instance name parameter is generated by Sys.ServiceModel.Diagnostics code from service description")]
  92. [SecuritySafeCritical]
  93. static CounterSetInstance CreateCounterSetInstance(string name)
  94. {
  95. return counterSetInstanceCache.Get(name) ?? serviceCounterSet.CreateCounterSetInstance(name);
  96. }
  97. internal override void MethodCalled()
  98. {
  99. this.counters[(int)PerfCounters.Calls].Increment();
  100. this.counters[(int)PerfCounters.CallsPerSecond].Increment();
  101. this.counters[(int)PerfCounters.CallsOutstanding].Increment();
  102. }
  103. internal override void MethodReturnedSuccess()
  104. {
  105. this.counters[(int)PerfCounters.CallsOutstanding].Decrement();
  106. }
  107. internal override void MethodReturnedError()
  108. {
  109. this.counters[(int)PerfCounters.CallsFailed].Increment();
  110. this.counters[(int)PerfCounters.CallsFailedPerSecond].Increment();
  111. this.counters[(int)PerfCounters.CallsOutstanding].Decrement();
  112. }
  113. internal override void MethodReturnedFault()
  114. {
  115. this.counters[(int)PerfCounters.CallsFaulted].Increment();
  116. this.counters[(int)PerfCounters.CallsFaultedPerSecond].Increment();
  117. this.counters[(int)PerfCounters.CallsOutstanding].Decrement();
  118. }
  119. internal override void SaveCallDuration(long time)
  120. {
  121. this.counters[(int)PerfCounters.CallDuration].IncrementBy(time);
  122. this.counters[(int)PerfCounters.CallDurationBase].Increment();
  123. }
  124. internal override void AuthenticationFailed()
  125. {
  126. this.counters[(int)PerfCounters.SecurityValidationAuthenticationFailures].Increment();
  127. this.counters[(int)PerfCounters.SecurityValidationAuthenticationFailuresPerSecond].Increment();
  128. }
  129. internal override void AuthorizationFailed()
  130. {
  131. this.counters[(int)PerfCounters.CallsNotAuthorized].Increment();
  132. this.counters[(int)PerfCounters.CallsNotAuthorizedPerSecond].Increment();
  133. }
  134. internal override void ServiceInstanceCreated()
  135. {
  136. this.counters[(int)PerfCounters.Instances].Increment();
  137. this.counters[(int)PerfCounters.InstancesRate].Increment();
  138. }
  139. internal override void ServiceInstanceRemoved()
  140. {
  141. this.counters[(int)PerfCounters.Instances].Decrement();
  142. }
  143. internal override void SessionFaulted()
  144. {
  145. this.counters[(int)PerfCounters.RMSessionsFaulted].Increment();
  146. this.counters[(int)PerfCounters.RMSessionsFaultedPerSecond].Increment();
  147. }
  148. internal override void MessageDropped()
  149. {
  150. this.counters[(int)PerfCounters.RMMessagesDropped].Increment();
  151. this.counters[(int)PerfCounters.RMMessagesDroppedPerSecond].Increment();
  152. }
  153. internal override void TxCommitted(long count)
  154. {
  155. this.counters[(int)PerfCounters.TxCommitted].Increment();
  156. this.counters[(int)PerfCounters.TxCommittedPerSecond].Increment();
  157. }
  158. internal override void TxInDoubt(long count)
  159. {
  160. this.counters[(int)PerfCounters.TxInDoubt].Increment();
  161. this.counters[(int)PerfCounters.TxInDoubtPerSecond].Increment();
  162. }
  163. internal override void TxAborted(long count)
  164. {
  165. this.counters[(int)PerfCounters.TxAborted].Increment();
  166. this.counters[(int)PerfCounters.TxAbortedPerSecond].Increment();
  167. }
  168. internal override void TxFlowed()
  169. {
  170. this.counters[(int)PerfCounters.TxFlowed].Increment();
  171. this.counters[(int)PerfCounters.TxFlowedPerSecond].Increment();
  172. }
  173. internal override void MsmqDroppedMessage()
  174. {
  175. this.counters[(int)PerfCounters.MsmqDroppedMessages].Increment();
  176. this.counters[(int)PerfCounters.MsmqDroppedMessagesPerSecond].Increment();
  177. }
  178. internal override void MsmqPoisonMessage()
  179. {
  180. this.counters[(int)PerfCounters.MsmqPoisonMessages].Increment();
  181. this.counters[(int)PerfCounters.MsmqPoisonMessagesPerSecond].Increment();
  182. }
  183. internal override void MsmqRejectedMessage()
  184. {
  185. this.counters[(int)PerfCounters.MsmqRejectedMessages].Increment();
  186. this.counters[(int)PerfCounters.MsmqRejectedMessagesPerSecond].Increment();
  187. }
  188. internal override void IncrementThrottlePercent(int counterIndex)
  189. {
  190. this.counters[counterIndex].Increment();
  191. }
  192. internal override void SetThrottleBase(int counterIndex, long denominator)
  193. {
  194. this.counters[counterIndex].Value = denominator;
  195. }
  196. internal override void DecrementThrottlePercent(int counterIndex)
  197. {
  198. this.counters[counterIndex].Decrement();
  199. }
  200. internal override bool Initialized
  201. {
  202. get { return this.serviceCounterSetInstance != null; }
  203. }
  204. protected override void Dispose(bool disposing)
  205. {
  206. try
  207. {
  208. if (disposing && PerformanceCounters.PerformanceCountersEnabled && this.serviceCounterSetInstance != null)
  209. {
  210. counterSetInstanceCache.Cleanup();
  211. OperationPerformanceCountersV2.CleanupCache();
  212. EndpointPerformanceCountersV2.CleanupCache();
  213. counterSetInstanceCache.Add(this.InstanceName, this.serviceCounterSetInstance);
  214. }
  215. }
  216. finally
  217. {
  218. // Not really necessary as base.Dispose() does nothing
  219. // But forced to leave this with try/finally by unability to suspend FxCop 1.35 warning
  220. base.Dispose(disposing);
  221. }
  222. }
  223. }
  224. }