e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
303 lines
12 KiB
C#
303 lines
12 KiB
C#
//------------------------------------------------------------
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//------------------------------------------------------------
|
|
|
|
namespace System.ServiceModel.Diagnostics
|
|
{
|
|
using System.Diagnostics;
|
|
using System.Runtime;
|
|
using System.ServiceModel;
|
|
using System.ServiceModel.Activation;
|
|
using System.ServiceModel.Administration;
|
|
using System.Diagnostics.PerformanceData;
|
|
|
|
abstract class ServicePerformanceCountersBase : PerformanceCountersBase
|
|
{
|
|
string instanceName;
|
|
|
|
internal enum PerfCounters : int
|
|
{
|
|
Calls = 0,
|
|
CallsPerSecond,
|
|
CallsOutstanding,
|
|
CallsFailed,
|
|
CallsFailedPerSecond,
|
|
CallsFaulted,
|
|
CallsFaultedPerSecond,
|
|
CallDuration,
|
|
CallDurationBase,
|
|
SecurityValidationAuthenticationFailures,
|
|
SecurityValidationAuthenticationFailuresPerSecond,
|
|
CallsNotAuthorized,
|
|
CallsNotAuthorizedPerSecond,
|
|
Instances,
|
|
InstancesRate,
|
|
RMSessionsFaulted,
|
|
RMSessionsFaultedPerSecond,
|
|
RMMessagesDropped,
|
|
RMMessagesDroppedPerSecond,
|
|
TxFlowed,
|
|
TxFlowedPerSecond,
|
|
TxCommitted,
|
|
TxCommittedPerSecond,
|
|
TxAborted,
|
|
TxAbortedPerSecond,
|
|
TxInDoubt,
|
|
TxInDoubtPerSecond,
|
|
MsmqPoisonMessages,
|
|
MsmqPoisonMessagesPerSecond,
|
|
MsmqRejectedMessages,
|
|
MsmqRejectedMessagesPerSecond,
|
|
MsmqDroppedMessages,
|
|
MsmqDroppedMessagesPerSecond,
|
|
CallsPercentMaxCalls,
|
|
CallsPercentMaxCallsBase,
|
|
InstancesPercentMaxInstances,
|
|
InstancesPercentMaxInstancesBase,
|
|
SessionsPercentMaxSessions,
|
|
SessionsPercentMaxSessionsBase,
|
|
TotalCounters = SessionsPercentMaxSessionsBase + 1
|
|
}
|
|
|
|
protected static readonly string[] perfCounterNames =
|
|
{
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.SCalls,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.SCallsPerSecond,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.SCallsOutstanding,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.SCallsFailed,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.SCallsFailedPerSecond,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.SCallsFaulted,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.SCallsFaultedPerSecond,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.SCallDuration,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.SCallDurationBase,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.SSecurityValidationAuthenticationFailures,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.SSecurityValidationAuthenticationFailuresPerSecond,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.SSecurityCallsNotAuthorized,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.SSecurityCallsNotAuthorizedPerSecond,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.SInstances,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.SInstancesPerSecond,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.SRMSessionsFaulted,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.SRMSessionsFaultedPerSecond,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.SRMMessagesDropped,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.SRMMessagesDroppedPerSecond,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.STxFlowed,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.STxFlowedPerSecond,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.STxCommitted,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.STxCommittedPerSecond,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.STxAborted,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.STxAbortedPerSecond,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.STxInDoubt,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.STxInDoubtPerSecond,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.MsmqPoisonMessages,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.MsmqPoisonMessagesPerSecond,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.MsmqRejectedMessages,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.MsmqRejectedMessagesPerSecond,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.MsmqDroppedMessages,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.MsmqDroppedMessagesPerSecond,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.CallsPercentMaxConcurrentCalls,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.CallsPercentMaxConcurrentCallsBase,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.InstancesPercentMaxConcurrentInstances,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.InstancesPercentMaxConcurrentInstancesBase,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.SessionsPercentMaxConcurrentSessions,
|
|
PerformanceCounterStrings.SERVICEMODELSERVICE.SessionsPercentMaxConcurrentSessionsBase,
|
|
};
|
|
|
|
const int maxCounterLength = 64;
|
|
const int hashLength = 2;
|
|
[Flags]
|
|
enum truncOptions : uint
|
|
{
|
|
NoBits = 0,
|
|
service32 = 0x01,
|
|
uri31 = 0x04
|
|
}
|
|
|
|
internal ServicePerformanceCountersBase(ServiceHostBase serviceHost)
|
|
{
|
|
this.instanceName = CreateFriendlyInstanceName(serviceHost);
|
|
}
|
|
|
|
internal override string InstanceName
|
|
{
|
|
get
|
|
{
|
|
return this.instanceName;
|
|
}
|
|
}
|
|
|
|
internal override string[] CounterNames
|
|
{
|
|
get
|
|
{
|
|
return perfCounterNames;
|
|
}
|
|
}
|
|
|
|
internal override int PerfCounterStart
|
|
{
|
|
get { return (int)PerfCounters.Calls; }
|
|
}
|
|
|
|
internal override int PerfCounterEnd
|
|
{
|
|
get { return (int)PerfCounters.TotalCounters; }
|
|
}
|
|
|
|
private static string GetServiceUri(ServiceHostBase serviceHost, ServiceInfo serviceInfo)
|
|
{
|
|
string uri;
|
|
if (!TryGetFullVirtualPath(serviceHost, out uri))
|
|
{
|
|
uri = serviceInfo.FirstAddress;
|
|
}
|
|
return uri;
|
|
}
|
|
|
|
private static string GetFullInstanceName(ServiceHostBase serviceHost)
|
|
{
|
|
// instance name is: serviceName@uri
|
|
ServiceInfo serviceInfo = new ServiceInfo(serviceHost);
|
|
string serviceName = serviceInfo.ServiceName;
|
|
string uri = GetServiceUri(serviceHost, serviceInfo);
|
|
return String.Format("{0}@{1}", serviceName, uri);
|
|
}
|
|
|
|
private static string GetShortInstanceName(ServiceHostBase serviceHost)
|
|
{
|
|
ServiceInfo serviceInfo = new ServiceInfo(serviceHost);
|
|
string serviceName = serviceInfo.ServiceName;
|
|
string uri = GetServiceUri(serviceHost, serviceInfo);
|
|
|
|
int length = serviceName.Length + uri.Length + 2;
|
|
|
|
if (length > maxCounterLength)
|
|
{
|
|
int count = 0;
|
|
|
|
truncOptions tasks = ServicePerformanceCountersBase.GetCompressionTasks(
|
|
length, serviceName.Length, uri.Length);
|
|
|
|
//if necessary, compress service name to 8 chars with a 2 char hash code
|
|
if ((tasks & truncOptions.service32) > 0)
|
|
{
|
|
count = 32;
|
|
serviceName = GetHashedString(serviceName, count - hashLength, serviceName.Length - count + hashLength, true);
|
|
}
|
|
|
|
//if necessary, compress uri to 36 chars with a 2 char hash code
|
|
if ((tasks & truncOptions.uri31) > 0)
|
|
{
|
|
count = 31;
|
|
uri = GetHashedString(uri, 0, uri.Length - count + hashLength, false);
|
|
}
|
|
}
|
|
|
|
// replace '/' with '|' because perfmon fails when '/' is in perfcounter instance name
|
|
return serviceName + "@" + uri.Replace('/', '|');
|
|
}
|
|
|
|
internal static string CreateFriendlyInstanceName(ServiceHostBase serviceHost)
|
|
{
|
|
string shortInstanceName = GetShortInstanceName(serviceHost);
|
|
if (!ServiceModelAppSettings.EnsureUniquePerformanceCounterInstanceNames)
|
|
{
|
|
return shortInstanceName;
|
|
}
|
|
|
|
string fullInstanceName = GetFullInstanceName(serviceHost);
|
|
|
|
return EnsureUniqueInstanceName(PerformanceCounterStrings.SERVICEMODELSERVICE.ServicePerfCounters, shortInstanceName, fullInstanceName);
|
|
}
|
|
|
|
internal static string GetFriendlyInstanceName(ServiceHostBase serviceHost)
|
|
{
|
|
string shortInstanceName = GetShortInstanceName(serviceHost);
|
|
if (!ServiceModelAppSettings.EnsureUniquePerformanceCounterInstanceNames)
|
|
{
|
|
return shortInstanceName;
|
|
}
|
|
|
|
string fullInstanceName = GetFullInstanceName(serviceHost);
|
|
|
|
return GetUniqueInstanceName(PerformanceCounterStrings.SERVICEMODELSERVICE.ServicePerfCounters, shortInstanceName, fullInstanceName);
|
|
}
|
|
|
|
static bool TryGetFullVirtualPath(ServiceHostBase serviceHost, out string uri)
|
|
{
|
|
VirtualPathExtension pathExtension = serviceHost.Extensions.Find<VirtualPathExtension>();
|
|
if (pathExtension == null)
|
|
{
|
|
uri = null;
|
|
return false;
|
|
}
|
|
uri = pathExtension.ApplicationVirtualPath + pathExtension.VirtualPath.ToString().Replace("~", "");
|
|
return uri != null;
|
|
}
|
|
|
|
static truncOptions GetCompressionTasks(int totalLen, int serviceLen, int uriLen)
|
|
{
|
|
truncOptions bitmask = 0;
|
|
|
|
if (totalLen > maxCounterLength)
|
|
{
|
|
int workingLen = totalLen;
|
|
|
|
//note: order of if statements important (see spec)!
|
|
if (workingLen > maxCounterLength && serviceLen > 32)
|
|
{
|
|
bitmask |= truncOptions.service32; //compress service name to 16 chars
|
|
workingLen -= serviceLen - 32;
|
|
}
|
|
if (workingLen > maxCounterLength && uriLen > 31)
|
|
{
|
|
bitmask |= truncOptions.uri31; //compress uri to 31 chars
|
|
}
|
|
}
|
|
|
|
return bitmask;
|
|
}
|
|
|
|
internal abstract void MethodCalled();
|
|
|
|
internal abstract void MethodReturnedSuccess();
|
|
|
|
internal abstract void MethodReturnedError();
|
|
|
|
internal abstract void MethodReturnedFault();
|
|
|
|
internal abstract void SaveCallDuration(long time);
|
|
|
|
internal abstract void AuthenticationFailed();
|
|
|
|
internal abstract void AuthorizationFailed();
|
|
|
|
internal abstract void ServiceInstanceCreated();
|
|
|
|
internal abstract void ServiceInstanceRemoved();
|
|
|
|
internal abstract void SessionFaulted();
|
|
|
|
internal abstract void MessageDropped();
|
|
|
|
internal abstract void TxCommitted(long count);
|
|
|
|
internal abstract void TxInDoubt(long count);
|
|
|
|
internal abstract void TxAborted(long count);
|
|
|
|
internal abstract void TxFlowed();
|
|
|
|
internal abstract void MsmqDroppedMessage();
|
|
|
|
internal abstract void MsmqPoisonMessage();
|
|
|
|
internal abstract void MsmqRejectedMessage();
|
|
|
|
internal abstract void IncrementThrottlePercent(int counterIndex);
|
|
|
|
internal abstract void SetThrottleBase(int counterIndex, long denominator);
|
|
|
|
internal abstract void DecrementThrottlePercent(int counterIndex);
|
|
}
|
|
}
|