diff --git a/BASE/src/Microsoft.ApplicationInsights/TelemetryClient.cs b/BASE/src/Microsoft.ApplicationInsights/TelemetryClient.cs
index 6935d0ba7..63f2686ce 100644
--- a/BASE/src/Microsoft.ApplicationInsights/TelemetryClient.cs
+++ b/BASE/src/Microsoft.ApplicationInsights/TelemetryClient.cs
@@ -153,7 +153,7 @@ public bool IsEnabled()
/// Named string values you can use to search and classify events.
public void TrackEvent(string eventName, IDictionary properties = null)
{
- this.Configuration.FeatureReporter.MarkFeatureInUse(StatsbeatFeatures.TrackEvent);
+ this.Configuration.FeatureReporter?.MarkFeatureInUse(StatsbeatFeatures.TrackEvent);
if (string.IsNullOrEmpty(eventName))
{
CoreEventSource.Log.TrackEventInvalidName();
@@ -176,7 +176,7 @@ public void TrackEvent(string eventName, IDictionary properties
/// An event log item.
public void TrackEvent(EventTelemetry telemetry)
{
- this.Configuration.FeatureReporter.MarkFeatureInUse(StatsbeatFeatures.TrackEvent);
+ this.Configuration.FeatureReporter?.MarkFeatureInUse(StatsbeatFeatures.TrackEvent);
if (telemetry == null)
{
CoreEventSource.Log.TrackEventTelemetryIsNull();
@@ -208,7 +208,7 @@ public void TrackEvent(EventTelemetry telemetry)
///
public void TrackAvailability(string name, DateTimeOffset timeStamp, TimeSpan duration, string runLocation, bool success, string message = null, IDictionary properties = null)
{
- this.Configuration.FeatureReporter.MarkFeatureInUse(StatsbeatFeatures.TrackAvailability);
+ this.Configuration.FeatureReporter?.MarkFeatureInUse(StatsbeatFeatures.TrackAvailability);
var availabilityTelemetry = new AvailabilityTelemetry(name, timeStamp, duration, runLocation, success, message);
if (properties != null && properties.Count > 0)
@@ -229,7 +229,7 @@ public void TrackAvailability(string name, DateTimeOffset timeStamp, TimeSpan du
/// An availability telemetry item.
public void TrackAvailability(AvailabilityTelemetry telemetry)
{
- this.Configuration.FeatureReporter.MarkFeatureInUse(StatsbeatFeatures.TrackAvailability);
+ this.Configuration.FeatureReporter?.MarkFeatureInUse(StatsbeatFeatures.TrackAvailability);
if (telemetry == null)
{
CoreEventSource.Log.TrackAvailabilityTelemetryIsNull();
@@ -281,7 +281,7 @@ public void TrackAvailability(AvailabilityTelemetry telemetry)
/// Message to display.
public void TrackTrace(string message)
{
- this.Configuration.FeatureReporter.MarkFeatureInUse(StatsbeatFeatures.TrackTrace);
+ this.Configuration.FeatureReporter?.MarkFeatureInUse(StatsbeatFeatures.TrackTrace);
var state = new DictionaryLogState(null, message);
this.Logger.Log(LogLevel.Information, 0, state, null, (s, ex) => s.Message);
}
@@ -296,7 +296,7 @@ public void TrackTrace(string message)
/// Trace severity level.
public void TrackTrace(string message, SeverityLevel severityLevel)
{
- this.Configuration.FeatureReporter.MarkFeatureInUse(StatsbeatFeatures.TrackTrace);
+ this.Configuration.FeatureReporter?.MarkFeatureInUse(StatsbeatFeatures.TrackTrace);
LogLevel logLevel = GetLogLevel(severityLevel);
var state = new DictionaryLogState(null, message);
this.Logger.Log(logLevel, 0, state, null, (s, ex) => s.Message);
@@ -312,7 +312,7 @@ public void TrackTrace(string message, SeverityLevel severityLevel)
/// Named string values you can use to search and classify events.
public void TrackTrace(string message, IDictionary properties)
{
- this.Configuration.FeatureReporter.MarkFeatureInUse(StatsbeatFeatures.TrackTrace);
+ this.Configuration.FeatureReporter?.MarkFeatureInUse(StatsbeatFeatures.TrackTrace);
var state = new DictionaryLogState(properties, message);
this.Logger.Log(LogLevel.Information, 0, state, null, (s, ex) => s.Message);
}
@@ -328,7 +328,7 @@ public void TrackTrace(string message, IDictionary properties)
/// Named string values you can use to search and classify events.
public void TrackTrace(string message, SeverityLevel severityLevel, IDictionary properties)
{
- this.Configuration.FeatureReporter.MarkFeatureInUse(StatsbeatFeatures.TrackTrace);
+ this.Configuration.FeatureReporter?.MarkFeatureInUse(StatsbeatFeatures.TrackTrace);
LogLevel logLevel = GetLogLevel(severityLevel);
var state = new DictionaryLogState(properties, message);
this.Logger.Log(logLevel, 0, state, null, (s, ex) => s.Message);
@@ -344,7 +344,7 @@ public void TrackTrace(string message, SeverityLevel severityLevel, IDictionary<
/// Message with optional properties.
public void TrackTrace(TraceTelemetry telemetry)
{
- this.Configuration.FeatureReporter.MarkFeatureInUse(StatsbeatFeatures.TrackTrace);
+ this.Configuration.FeatureReporter?.MarkFeatureInUse(StatsbeatFeatures.TrackTrace);
if (telemetry == null)
{
telemetry = new TraceTelemetry();
@@ -379,10 +379,10 @@ public void TrackTrace(TraceTelemetry telemetry)
///
/// Metric name.
/// Metric value.
- /// Named string values you can use to classify and filter metrics.
+ /// Named string values you can use to classify and filter metrics.
public void TrackMetric(string name, double value, IDictionary properties = null)
{
- this.Configuration.FeatureReporter.MarkFeatureInUse(StatsbeatFeatures.TrackMetric);
+ this.Configuration.FeatureReporter?.MarkFeatureInUse(StatsbeatFeatures.TrackMetric);
// Get or create histogram for this metric
var histogram = this.Configuration.MetricsManager.GetOrCreateHistogram(name, null);
@@ -410,10 +410,10 @@ public void TrackMetric(string name, double value, IDictionary p
/// If your application requires sending a separate telemetry item at every occasion without aggregation across time,
/// you likely have a use case for event telemetry; see .
///
- /// The metric telemetry item.
+ /// The metric telemetry item.
public void TrackMetric(MetricTelemetry telemetry)
{
- this.Configuration.FeatureReporter.MarkFeatureInUse(StatsbeatFeatures.TrackMetric);
+ this.Configuration.FeatureReporter?.MarkFeatureInUse(StatsbeatFeatures.TrackMetric);
if (telemetry == null)
{
CoreEventSource.Log.TrackMetricTelemetryIsNull();
@@ -451,7 +451,7 @@ public void TrackMetric(MetricTelemetry telemetry)
///
public void TrackException(Exception exception, IDictionary properties = null)
{
- this.Configuration.FeatureReporter.MarkFeatureInUse(StatsbeatFeatures.TrackException);
+ this.Configuration.FeatureReporter?.MarkFeatureInUse(StatsbeatFeatures.TrackException);
if (exception == null)
{
exception = new InvalidOperationException(Utils.PopulateRequiredStringValue(null, "message", typeof(ExceptionTelemetry).FullName));
@@ -470,7 +470,7 @@ public void TrackException(Exception exception, IDictionary prop
///
public void TrackException(ExceptionTelemetry telemetry)
{
- this.Configuration.FeatureReporter.MarkFeatureInUse(StatsbeatFeatures.TrackException);
+ this.Configuration.FeatureReporter?.MarkFeatureInUse(StatsbeatFeatures.TrackException);
// TODO investigate how problem id, custom message, etc should appear in portal
if (telemetry == null)
{
@@ -531,7 +531,7 @@ public void TrackDependency(string dependencyTypeName, string target, string dep
///
///
///
- /// This method implements a shim layer that converts Application Insights DependencyTelemetry objects
+ /// This method implements a shim layer that converts Application Insights DependencyTelemetry objects
/// into OpenTelemetry Activities. The Azure Monitor Exporter then processes these Activities to emit telemetry.
///
///
@@ -560,14 +560,14 @@ public void TrackDependency(string dependencyTypeName, string target, string dep
///
///
/// These override attributes ensure backward compatibility and prevent data loss during the OpenTelemetry migration.
- /// For Activities created by OpenTelemetry instrumentation (without override attributes), the exporter will map
+ /// For Activities created by OpenTelemetry instrumentation (without override attributes), the exporter will map
/// semantic convention attributes (url.full, db.system, messaging.system, etc.) to Application Insights fields.
///
/// Learn more
///
public void TrackDependency(DependencyTelemetry telemetry)
{
- this.Configuration.FeatureReporter.MarkFeatureInUse(StatsbeatFeatures.TrackDependency);
+ this.Configuration.FeatureReporter?.MarkFeatureInUse(StatsbeatFeatures.TrackDependency);
if (telemetry == null)
{
return;
@@ -707,7 +707,7 @@ public void TrackRequest(string name, DateTimeOffset startTime, TimeSpan duratio
///
///
///
- /// This method implements a shim layer that converts Application Insights RequestTelemetry objects
+ /// This method implements a shim layer that converts Application Insights RequestTelemetry objects
/// into OpenTelemetry Activities. The Azure Monitor Exporter then processes these Activities to emit telemetry.
///
///
@@ -735,14 +735,14 @@ public void TrackRequest(string name, DateTimeOffset startTime, TimeSpan duratio
///
///
/// These override attributes ensure backward compatibility and prevent data loss during the OpenTelemetry migration.
- /// For Activities created by OpenTelemetry instrumentation (without override attributes), the exporter will map
+ /// For Activities created by OpenTelemetry instrumentation (without override attributes), the exporter will map
/// semantic convention attributes (url.full, http.response.status_code, messaging.system, etc.) to Application Insights fields.
///
/// Learn more
///
public void TrackRequest(RequestTelemetry request)
{
- this.Configuration.FeatureReporter.MarkFeatureInUse(StatsbeatFeatures.TrackRequest);
+ this.Configuration.FeatureReporter?.MarkFeatureInUse(StatsbeatFeatures.TrackRequest);
if (request == null)
{
return;
diff --git a/BASE/src/Microsoft.ApplicationInsights/TelemetryClientExtensions.cs b/BASE/src/Microsoft.ApplicationInsights/TelemetryClientExtensions.cs
index 50d7a4cf5..6c8e3416b 100644
--- a/BASE/src/Microsoft.ApplicationInsights/TelemetryClientExtensions.cs
+++ b/BASE/src/Microsoft.ApplicationInsights/TelemetryClientExtensions.cs
@@ -62,7 +62,7 @@ public static IOperationHolder StartOperation(
}
#endif
- telemetryClient.Configuration.FeatureReporter.MarkFeatureInUse(Internal.StatsbeatFeatures.StartOperation);
+ telemetryClient.Configuration.FeatureReporter?.MarkFeatureInUse(Internal.StatsbeatFeatures.StartOperation);
var effectiveName = string.IsNullOrEmpty(operationName) ? typeof(T).Name : operationName;
var kind = ResolveActivityKind();
@@ -161,7 +161,7 @@ public static IOperationHolder StartOperation(
operationTelemetry.Name = typeof(T).Name;
}
- telemetryClient.Configuration.FeatureReporter.MarkFeatureInUse(Internal.StatsbeatFeatures.StartOperation);
+ telemetryClient.Configuration.FeatureReporter?.MarkFeatureInUse(Internal.StatsbeatFeatures.StartOperation);
var kind = ResolveActivityKind();
var source = telemetryClient.TelemetryConfiguration.ApplicationInsightsActivitySource;
@@ -244,7 +244,7 @@ public static IOperationHolder StartOperation(
return null;
}
- telemetryClient.Configuration.FeatureReporter.MarkFeatureInUse(Internal.StatsbeatFeatures.StartOperation);
+ telemetryClient.Configuration.FeatureReporter?.MarkFeatureInUse(Internal.StatsbeatFeatures.StartOperation);
// if already started activity, we just link it — not create a new one
if (activity.Id == null)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b6cf29f0f..fff56c5e5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,7 @@
# Changelog
## Unreleased
+- [Fix #3197: `NullReferenceException` when using TelemetryClient APIs when no connection string is provided.](https://github.com/microsoft/ApplicationInsights-dotnet/pull/3199)
## Version 3.1.2
- [Fix `HttpException: Request is not available in this context` in the WEB package when calling `TrackDependency` from `Application_Start` in classic ASP.NET. The WEB activity processors now safely handle the case where `HttpContext.Request` is not yet available.](https://github.com/microsoft/ApplicationInsights-dotnet/pull/3184)