On this link: https://azure.microsoft.com/en-us/documentation/articles/app-insights-api-custom-events-metrics/
It explicitly says:
TelemetryClient is thread-safe.
We recommend you use an instance of TelemetryClient for each module of your app.
However, the MSDN documentation (https://msdn.microsoft.com/en-us/library/azure/microsoft.applicationinsights.telemetryclient.aspx) says:
Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.
So the problem is, most functions such as TrackEvent and TrackMetric are not static. If I follow the first article, having a singleton instance for my web service, would I run into threading problems?
Use the Application Insights core telemetry API to send custom events and metrics and your own versions of standard telemetry. This API is the same API that the standard Application Insights data collectors use.
In the Azure Portal, navigate to the Application Insights resource, and click Log Analytics. Log queries help you to fully leverage the value of the data collected in Azure Monitor Logs. Query your custom events by entering “customEvents” in the prompt and click Run.
TelemetryClient is thread safe. A valid usage is to create a singleton and reuse it. You will not run into issues reusing an instance.
The MSDN Docs are frequently incorrect when they say a given class is not thread-safe. I'm not sure how people have to flag their code to get those docs to reflect a class's thread-safety, but I've seen numerous instances where those docs are incorrect.
The current version of the Azure article you linked says:
TelemetryClient is thread-safe.
For ASP.NET and Java projects, incoming HTTP Requests are automatically captured. You might want to create additional instances of TelemetryClient for other module of your app. For instance, you may have one TelemetryClient instance in your middleware class to report business logic events. You can set properties such as UserId and DeviceId to identify the machine. This information is attached to all events that the instance sends.
TelemetryClient.Context.User.Id = "..."; TelemetryClient.Context.Device.Id = "...";
That last bit is extremely important. Even though the class is thread-safe, if you are writing something like a web application where the UserId might change, you should probably reuse an instance of the telemetry client for each scope in which these values would all be the same (like each Request), but not as a static/singleton instance.
In ASP.NET Core, Application Insights makes heavy use of dependency injection and registers TelemetryClient as a singleton! As explained in the docs:
We don't recommend creating new
TelemetryClient
instances in an ASP.NET Core application. A singleton instance ofTelemetryClient
is already registered in theDependencyInjection
container, which sharesTelemetryConfiguration
with rest of the telemetry. Creating a newTelemetryClient
instance is recommended only if it needs a configuration that's separate from the rest of the telemetry.
This means you should avoid setting variables on the client context which you don't want to be used throughout the application, and instead leverage Telemetry Initializers to set things like the user ID on each telemetry object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With