EndpointPerformanceCountersBase.cs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  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.Administration;
  10. using System.Diagnostics.PerformanceData;
  11. abstract class EndpointPerformanceCountersBase : PerformanceCountersBase
  12. {
  13. protected string instanceName;
  14. protected enum PerfCounters : int
  15. {
  16. Calls = 0,
  17. CallsPerSecond,
  18. CallsOutstanding,
  19. CallsFailed,
  20. CallsFailedPerSecond,
  21. CallsFaulted,
  22. CallsFaultedPerSecond,
  23. CallDuration,
  24. CallDurationBase,
  25. SecurityValidationAuthenticationFailures,
  26. SecurityValidationAuthenticationFailuresPerSecond,
  27. CallsNotAuthorized,
  28. CallsNotAuthorizedPerSecond,
  29. RMSessionsFaulted,
  30. RMSessionsFaultedPerSecond,
  31. RMMessagesDropped,
  32. RMMessagesDroppedPerSecond,
  33. TxFlowed,
  34. TxFlowedPerSecond,
  35. TotalCounters = TxFlowedPerSecond + 1
  36. }
  37. protected static readonly string[] perfCounterNames =
  38. {
  39. PerformanceCounterStrings.SERVICEMODELENDPOINT.ECalls,
  40. PerformanceCounterStrings.SERVICEMODELENDPOINT.ECallsPerSecond,
  41. PerformanceCounterStrings.SERVICEMODELENDPOINT.ECallsOutstanding,
  42. PerformanceCounterStrings.SERVICEMODELENDPOINT.ECallsFailed,
  43. PerformanceCounterStrings.SERVICEMODELENDPOINT.ECallsFailedPerSecond,
  44. PerformanceCounterStrings.SERVICEMODELENDPOINT.ECallsFaulted,
  45. PerformanceCounterStrings.SERVICEMODELENDPOINT.ECallsFaultedPerSecond,
  46. PerformanceCounterStrings.SERVICEMODELENDPOINT.ECallDuration,
  47. PerformanceCounterStrings.SERVICEMODELENDPOINT.ECallDurationBase,
  48. PerformanceCounterStrings.SERVICEMODELENDPOINT.ESecurityValidationAuthenticationFailures,
  49. PerformanceCounterStrings.SERVICEMODELENDPOINT.ESecurityValidationAuthenticationFailuresPerSecond,
  50. PerformanceCounterStrings.SERVICEMODELENDPOINT.ESecurityCallsNotAuthorized,
  51. PerformanceCounterStrings.SERVICEMODELENDPOINT.ESecurityCallsNotAuthorizedPerSecond,
  52. PerformanceCounterStrings.SERVICEMODELENDPOINT.ERMSessionsFaulted,
  53. PerformanceCounterStrings.SERVICEMODELENDPOINT.ERMSessionsFaultedPerSecond,
  54. PerformanceCounterStrings.SERVICEMODELENDPOINT.ERMMessagesDropped,
  55. PerformanceCounterStrings.SERVICEMODELENDPOINT.ERMMessagesDroppedPerSecond,
  56. PerformanceCounterStrings.SERVICEMODELENDPOINT.ETxFlowed,
  57. PerformanceCounterStrings.SERVICEMODELENDPOINT.ETxFlowedPerSecond,
  58. };
  59. const int maxCounterLength = 64;
  60. const int hashLength = 2;
  61. [Flags]
  62. enum truncOptions : uint
  63. {
  64. NoBits = 0,
  65. service15 = 0x01,
  66. contract16 = 0x02,
  67. uri31 = 0x04
  68. }
  69. internal EndpointPerformanceCountersBase(string service, string contract, string uri)
  70. {
  71. this.instanceName = CreateFriendlyInstanceName(service, contract, uri);
  72. }
  73. static internal string CreateFriendlyInstanceName(string service, string contract, string uri)
  74. {
  75. // instance name is: serviceName.interfaceName.operationName@uri
  76. int length = service.Length + contract.Length + uri.Length + 2;
  77. if (length > maxCounterLength)
  78. {
  79. int count = 0;
  80. truncOptions tasks = EndpointPerformanceCounters.GetCompressionTasks(
  81. length, service.Length, contract.Length, uri.Length);
  82. //if necessary, compress service name to 13 chars with a 2 char hash code
  83. if ((tasks & truncOptions.service15) > 0)
  84. {
  85. count = 15;
  86. service = GetHashedString(service, count - hashLength, service.Length - count + hashLength, true);
  87. }
  88. //if necessary, compress contract name to 14 chars with a 2 char hash code
  89. if ((tasks & truncOptions.contract16) > 0)
  90. {
  91. count = 16;
  92. contract = GetHashedString(contract, count - hashLength, contract.Length - count + hashLength, true);
  93. }
  94. //if necessary, compress uri to 29 chars with a 2 char hash code
  95. if ((tasks & truncOptions.uri31) > 0)
  96. {
  97. count = 31;
  98. uri = GetHashedString(uri, 0, uri.Length - count + hashLength, false);
  99. }
  100. }
  101. // replace '/' with '|' because perfmon fails when '/' is in perfcounter instance name
  102. return service + "." + contract + "@" + uri.Replace('/', '|');
  103. }
  104. private static truncOptions GetCompressionTasks(int totalLen, int serviceLen, int contractLen, int uriLen)
  105. {
  106. truncOptions bitmask = 0;
  107. if (totalLen > maxCounterLength)
  108. {
  109. int workingLen = totalLen;
  110. //note: order of if statements important (see spec)!
  111. if (workingLen > maxCounterLength && serviceLen > 15)
  112. {
  113. bitmask |= truncOptions.service15; //compress service name to 16 chars
  114. workingLen -= serviceLen - 15;
  115. }
  116. if (workingLen > maxCounterLength && contractLen > 16)
  117. {
  118. bitmask |= truncOptions.contract16; //compress contract name to 8 chars
  119. workingLen -= contractLen - 16;
  120. }
  121. if (workingLen > maxCounterLength && uriLen > 31)
  122. {
  123. bitmask |= truncOptions.uri31; //compress uri to 31 chars
  124. }
  125. }
  126. return bitmask;
  127. }
  128. internal override string InstanceName
  129. {
  130. get
  131. {
  132. return this.instanceName;
  133. }
  134. }
  135. internal override string[] CounterNames
  136. {
  137. get
  138. {
  139. return perfCounterNames;
  140. }
  141. }
  142. internal override int PerfCounterStart
  143. {
  144. get { return (int)PerfCounters.Calls; }
  145. }
  146. internal override int PerfCounterEnd
  147. {
  148. get { return (int)PerfCounters.TotalCounters; }
  149. }
  150. internal abstract void MethodCalled();
  151. internal abstract void MethodReturnedSuccess();
  152. internal abstract void MethodReturnedError();
  153. internal abstract void MethodReturnedFault();
  154. internal abstract void SaveCallDuration(long time);
  155. internal abstract void AuthenticationFailed();
  156. internal abstract void AuthorizationFailed();
  157. internal abstract void SessionFaulted();
  158. internal abstract void MessageDropped();
  159. internal abstract void TxFlowed();
  160. }
  161. }