ServicePerformanceCountersBase.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. //------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------
  4. namespace System.ServiceModel.Diagnostics
  5. {
  6. using System.Diagnostics;
  7. using System.Runtime;
  8. using System.ServiceModel;
  9. using System.ServiceModel.Activation;
  10. using System.ServiceModel.Administration;
  11. using System.Diagnostics.PerformanceData;
  12. abstract class ServicePerformanceCountersBase : PerformanceCountersBase
  13. {
  14. string instanceName;
  15. internal enum PerfCounters : int
  16. {
  17. Calls = 0,
  18. CallsPerSecond,
  19. CallsOutstanding,
  20. CallsFailed,
  21. CallsFailedPerSecond,
  22. CallsFaulted,
  23. CallsFaultedPerSecond,
  24. CallDuration,
  25. CallDurationBase,
  26. SecurityValidationAuthenticationFailures,
  27. SecurityValidationAuthenticationFailuresPerSecond,
  28. CallsNotAuthorized,
  29. CallsNotAuthorizedPerSecond,
  30. Instances,
  31. InstancesRate,
  32. RMSessionsFaulted,
  33. RMSessionsFaultedPerSecond,
  34. RMMessagesDropped,
  35. RMMessagesDroppedPerSecond,
  36. TxFlowed,
  37. TxFlowedPerSecond,
  38. TxCommitted,
  39. TxCommittedPerSecond,
  40. TxAborted,
  41. TxAbortedPerSecond,
  42. TxInDoubt,
  43. TxInDoubtPerSecond,
  44. MsmqPoisonMessages,
  45. MsmqPoisonMessagesPerSecond,
  46. MsmqRejectedMessages,
  47. MsmqRejectedMessagesPerSecond,
  48. MsmqDroppedMessages,
  49. MsmqDroppedMessagesPerSecond,
  50. CallsPercentMaxCalls,
  51. CallsPercentMaxCallsBase,
  52. InstancesPercentMaxInstances,
  53. InstancesPercentMaxInstancesBase,
  54. SessionsPercentMaxSessions,
  55. SessionsPercentMaxSessionsBase,
  56. TotalCounters = SessionsPercentMaxSessionsBase + 1
  57. }
  58. protected static readonly string[] perfCounterNames =
  59. {
  60. PerformanceCounterStrings.SERVICEMODELSERVICE.SCalls,
  61. PerformanceCounterStrings.SERVICEMODELSERVICE.SCallsPerSecond,
  62. PerformanceCounterStrings.SERVICEMODELSERVICE.SCallsOutstanding,
  63. PerformanceCounterStrings.SERVICEMODELSERVICE.SCallsFailed,
  64. PerformanceCounterStrings.SERVICEMODELSERVICE.SCallsFailedPerSecond,
  65. PerformanceCounterStrings.SERVICEMODELSERVICE.SCallsFaulted,
  66. PerformanceCounterStrings.SERVICEMODELSERVICE.SCallsFaultedPerSecond,
  67. PerformanceCounterStrings.SERVICEMODELSERVICE.SCallDuration,
  68. PerformanceCounterStrings.SERVICEMODELSERVICE.SCallDurationBase,
  69. PerformanceCounterStrings.SERVICEMODELSERVICE.SSecurityValidationAuthenticationFailures,
  70. PerformanceCounterStrings.SERVICEMODELSERVICE.SSecurityValidationAuthenticationFailuresPerSecond,
  71. PerformanceCounterStrings.SERVICEMODELSERVICE.SSecurityCallsNotAuthorized,
  72. PerformanceCounterStrings.SERVICEMODELSERVICE.SSecurityCallsNotAuthorizedPerSecond,
  73. PerformanceCounterStrings.SERVICEMODELSERVICE.SInstances,
  74. PerformanceCounterStrings.SERVICEMODELSERVICE.SInstancesPerSecond,
  75. PerformanceCounterStrings.SERVICEMODELSERVICE.SRMSessionsFaulted,
  76. PerformanceCounterStrings.SERVICEMODELSERVICE.SRMSessionsFaultedPerSecond,
  77. PerformanceCounterStrings.SERVICEMODELSERVICE.SRMMessagesDropped,
  78. PerformanceCounterStrings.SERVICEMODELSERVICE.SRMMessagesDroppedPerSecond,
  79. PerformanceCounterStrings.SERVICEMODELSERVICE.STxFlowed,
  80. PerformanceCounterStrings.SERVICEMODELSERVICE.STxFlowedPerSecond,
  81. PerformanceCounterStrings.SERVICEMODELSERVICE.STxCommitted,
  82. PerformanceCounterStrings.SERVICEMODELSERVICE.STxCommittedPerSecond,
  83. PerformanceCounterStrings.SERVICEMODELSERVICE.STxAborted,
  84. PerformanceCounterStrings.SERVICEMODELSERVICE.STxAbortedPerSecond,
  85. PerformanceCounterStrings.SERVICEMODELSERVICE.STxInDoubt,
  86. PerformanceCounterStrings.SERVICEMODELSERVICE.STxInDoubtPerSecond,
  87. PerformanceCounterStrings.SERVICEMODELSERVICE.MsmqPoisonMessages,
  88. PerformanceCounterStrings.SERVICEMODELSERVICE.MsmqPoisonMessagesPerSecond,
  89. PerformanceCounterStrings.SERVICEMODELSERVICE.MsmqRejectedMessages,
  90. PerformanceCounterStrings.SERVICEMODELSERVICE.MsmqRejectedMessagesPerSecond,
  91. PerformanceCounterStrings.SERVICEMODELSERVICE.MsmqDroppedMessages,
  92. PerformanceCounterStrings.SERVICEMODELSERVICE.MsmqDroppedMessagesPerSecond,
  93. PerformanceCounterStrings.SERVICEMODELSERVICE.CallsPercentMaxConcurrentCalls,
  94. PerformanceCounterStrings.SERVICEMODELSERVICE.CallsPercentMaxConcurrentCallsBase,
  95. PerformanceCounterStrings.SERVICEMODELSERVICE.InstancesPercentMaxConcurrentInstances,
  96. PerformanceCounterStrings.SERVICEMODELSERVICE.InstancesPercentMaxConcurrentInstancesBase,
  97. PerformanceCounterStrings.SERVICEMODELSERVICE.SessionsPercentMaxConcurrentSessions,
  98. PerformanceCounterStrings.SERVICEMODELSERVICE.SessionsPercentMaxConcurrentSessionsBase,
  99. };
  100. const int maxCounterLength = 64;
  101. const int hashLength = 2;
  102. [Flags]
  103. enum truncOptions : uint
  104. {
  105. NoBits = 0,
  106. service32 = 0x01,
  107. uri31 = 0x04
  108. }
  109. internal ServicePerformanceCountersBase(ServiceHostBase serviceHost)
  110. {
  111. this.instanceName = CreateFriendlyInstanceName(serviceHost);
  112. }
  113. internal override string InstanceName
  114. {
  115. get
  116. {
  117. return this.instanceName;
  118. }
  119. }
  120. internal override string[] CounterNames
  121. {
  122. get
  123. {
  124. return perfCounterNames;
  125. }
  126. }
  127. internal override int PerfCounterStart
  128. {
  129. get { return (int)PerfCounters.Calls; }
  130. }
  131. internal override int PerfCounterEnd
  132. {
  133. get { return (int)PerfCounters.TotalCounters; }
  134. }
  135. static internal string CreateFriendlyInstanceName(ServiceHostBase serviceHost)
  136. {
  137. // instance name is: serviceName@uri
  138. ServiceInfo serviceInfo = new ServiceInfo(serviceHost);
  139. string serviceName = serviceInfo.ServiceName;
  140. string uri;
  141. if (!TryGetFullVirtualPath(serviceHost, out uri))
  142. {
  143. uri = serviceInfo.FirstAddress;
  144. }
  145. int length = serviceName.Length + uri.Length + 2;
  146. if (length > maxCounterLength)
  147. {
  148. int count = 0;
  149. truncOptions tasks = ServicePerformanceCountersBase.GetCompressionTasks(
  150. length, serviceName.Length, uri.Length);
  151. //if necessary, compress service name to 8 chars with a 2 char hash code
  152. if ((tasks & truncOptions.service32) > 0)
  153. {
  154. count = 32;
  155. serviceName = GetHashedString(serviceName, count - hashLength, serviceName.Length - count + hashLength, true);
  156. }
  157. //if necessary, compress uri to 36 chars with a 2 char hash code
  158. if ((tasks & truncOptions.uri31) > 0)
  159. {
  160. count = 31;
  161. uri = GetHashedString(uri, 0, uri.Length - count + hashLength, false);
  162. }
  163. }
  164. // replace '/' with '|' because perfmon fails when '/' is in perfcounter instance name
  165. return serviceName + "@" + uri.Replace('/', '|');
  166. }
  167. static bool TryGetFullVirtualPath(ServiceHostBase serviceHost, out string uri)
  168. {
  169. VirtualPathExtension pathExtension = serviceHost.Extensions.Find<VirtualPathExtension>();
  170. if (pathExtension == null)
  171. {
  172. uri = null;
  173. return false;
  174. }
  175. uri = pathExtension.ApplicationVirtualPath + pathExtension.VirtualPath.ToString().Replace("~", "");
  176. return uri != null;
  177. }
  178. static truncOptions GetCompressionTasks(int totalLen, int serviceLen, int uriLen)
  179. {
  180. truncOptions bitmask = 0;
  181. if (totalLen > maxCounterLength)
  182. {
  183. int workingLen = totalLen;
  184. //note: order of if statements important (see spec)!
  185. if (workingLen > maxCounterLength && serviceLen > 32)
  186. {
  187. bitmask |= truncOptions.service32; //compress service name to 16 chars
  188. workingLen -= serviceLen - 32;
  189. }
  190. if (workingLen > maxCounterLength && uriLen > 31)
  191. {
  192. bitmask |= truncOptions.uri31; //compress uri to 31 chars
  193. }
  194. }
  195. return bitmask;
  196. }
  197. internal abstract void MethodCalled();
  198. internal abstract void MethodReturnedSuccess();
  199. internal abstract void MethodReturnedError();
  200. internal abstract void MethodReturnedFault();
  201. internal abstract void SaveCallDuration(long time);
  202. internal abstract void AuthenticationFailed();
  203. internal abstract void AuthorizationFailed();
  204. internal abstract void ServiceInstanceCreated();
  205. internal abstract void ServiceInstanceRemoved();
  206. internal abstract void SessionFaulted();
  207. internal abstract void MessageDropped();
  208. internal abstract void TxCommitted(long count);
  209. internal abstract void TxInDoubt(long count);
  210. internal abstract void TxAborted(long count);
  211. internal abstract void TxFlowed();
  212. internal abstract void MsmqDroppedMessage();
  213. internal abstract void MsmqPoisonMessage();
  214. internal abstract void MsmqRejectedMessage();
  215. internal abstract void IncrementThrottlePercent(int counterIndex);
  216. internal abstract void SetThrottleBase(int counterIndex, long denominator);
  217. internal abstract void DecrementThrottlePercent(int counterIndex);
  218. }
  219. }