问题
I have a WCF Service where I measure timings with Application Insights SDK in this way.
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
[BasicHttpBindingServiceMetadataExchangeEndpoint]
public class DMSWebService : IDMSWebService
{
public static readonly string LoggingPrefix = "DMSWebService";
private TelemetryClient telemetry;
//Defines if Application Insights must be enabled or not
public Boolean EnableApplicationInsights { get; set; }
//Application Insights Instrumentation Key
public string ApplicationInsightsMonitoringKey { get; set; }
//Constructor to get the property bag values only once.
public DMSWebService()
{
InitializeApplicationInsights();
telemetry= new TelemetryClient {InstrumentationKey = ApplicationInsightsMonitoringKey};
}
//Method to initialize ApplicationInsightSettings
private void InitializeApplicationInsights()
{
bool enableApplicationInsights = false;
using (var billingSite = BillingManagement.GetBillingSite())
{
enableApplicationInsights = Convert.ToBoolean(billingSite.WebApplication.GetProperty(Constants.WebApplicationSettings.EnableApplicationInsights));
if(enableApplicationInsights) ApplicationInsightsMonitoringKey = billingSite.WebApplication.GetProperty(Constants.WebApplicationSettings.ApplicationInsightsKey);
}
EnableApplicationInsights = enableApplicationInsights;
}
#region Billing
#region Archiving
// GET
public DMSServiceResult ArchiveBillCycle(string listItemId)
{
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
using (var withDMSServiceResult = new WithDMSServiceResult(LoggingPrefix, "ArchiveBillCycle"))
{
try
{
withDMSServiceResult.InputParameters["listItemId"] = listItemId;
var listItemIdAsInt = Convert.ToInt32(listItemId);
using (var billingSite = BillingManagement.GetBillingSite())
{
// HACK: Necessary to disable form digest validation, which we don't need.
using (var continueWithoutSPContext = new ContinueWithoutSPContext())
{
withDMSServiceResult.RequestSucceeded = BillingRepository.ArchiveBillCycle(billingSite.RootWeb, listItemIdAsInt);
}
}
}
catch (Exception ex)
{
telemetry.TrackException(ex);
withDMSServiceResult.HandleError(ex);
}
stopwatch.Stop();
var metrics = new Dictionary <string, double>{{"processingTime", stopwatch.Elapsed.TotalMilliseconds}};
// Set up some properties:
var properties = new Dictionary <string, string>{{"listItemId", withDMSServiceResult.InputParameters["listItemId"]}};
if(EnableApplicationInsights) telemetry.TrackEvent("ArchiveBillCycle", properties, metrics);
return withDMSServiceResult.Result;
}
}
#endregion
As you can see I start a StopWatch in the beginning of the method, and then I send the event to Application Insights at the end of the method.
Doing this for all the 10 methods on the web service is not a big deal, I already did it.
However these methods call utilities methods in other classes, and the only way to find the bottleneck is to measure each of the methods.
What would be your suggestion?
Please note that the trackEvent has a properties field, which sometimes I use it, sometimes i Just send null.
Thx
回答1:
Look for an AOP (Aspect Oriented Programming) framework like PostSharp (paid) or use something like Aspectize or Castle DynamicProxy. There frameworks enables you to write some custom logic once and apply them at runtime or compile time to all specified methods. See this post for an example.
For WCF you can do it easier as there is built in support for call interception using for example Message Inspectors.
来源:https://stackoverflow.com/questions/46236321/how-to-inject-application-insights-code-to-monitor-timing-in-all-methods