Search code examples
c#azureazure-application-insightsmetrics

Why do some Azure App Insight metrics not appear in the Portal?


I've implemented custom metrics into my app, so that these are sent to App Insights in Azure:

using (var operation = tc.StartOperation<DependencyTelemetry>("MetricName"))
{
  //some long running code
}

If I run this code say, 5 times, and then go look at the App Insights metrics in the Azure Portal:

dependencies 
| where type == 'Other'

Then I'll usually see about 1-2 entries for this metric with timestamps. I've repeated this over and over and it's always the same, what happens to the other missing metrics given that the code ran 5 times? (with considerable delay between each run)

I wondered if they were being filtered out from sampling, but according to the docs App Insights does not sample metrics: https://learn.microsoft.com/en-us/azure/azure-monitor/app/sampling

"Application Insights does not sample session, metrics (including custom metrics), or performance counter telemetry types in any of the sampling techniques. These types are always excluded from sampling as a reduction in precision can be highly undesirable for these telemetry types."

I can confirm it's not a delay, I've tried waiting many hours to see if the missing ones appear. Any ideas?


Solution

  • Uhm, you are tracking a dependency, not a metric (those are stored in the customMetrics table). And since you are tracking dependencies sampling might be the cause.

    To track metrics use the method described in the docs:

    _telemetryClient.GetMetric("myMetric").TrackValue(42);
    

    If we want to simply time the duration of a block of code inside a using statement, is StartOperation() not the way to go then? Is that some other concept than metrics?

    It is definitely an option as the dependency telemetry does store the time spend executing. But it is stored in a different table than a metric and is subject to sampling. So you can exclude the dependency from sampling but that might cause a lot of data ingestion. Or you create your own code to track a metric like this:

    public class MetricOperation : IDisposable
    {
        private readonly TelemetryClient _tc;
        private readonly Stopwatch _sw = new Stopwatch();
        private readonly string _operationName;
        
        public MetricOperation(TelemetryClient tc, string operationName)
        {
            _tc = tc;
            _operationName = operationName;
            
            _sw.Start();
        }
        
        public void Dispose()
        {
            _sw.Stop();
            _tc.GetMetric(_operationName).TrackValue(_sw.ElapsedMilliseconds);
        }
    }
    

    and call it like this

    using(new MetricOperation(tc, "metricName"))
    {
        // some long running operation
    }