When running the web API on a local machine with app insights enabled, we could see a nice set of graphs as shown here below:
But when I deploy this to the Azure Mobile services, this results in a page that only shows the dependency calls, bet never any incoming requests and also no request duration. You only see a first request and after this the incoming requests are a flat liner.
After some inquiries at the app insights team, I got the information that since Azure Mobile Services is using OWIN, because the app insights HTTP modules are not loaded since that is not allowed and finally because performance counters are not exposed to the web application, these metrics will not show. After going back and forth on this, I got information that it would be possible to at least get the info for the requests on the screen, by adding a small piece of middleware, that can track the request instead of the standard HttpModule that is normally instantiated, but not allowed in a Mobile app.
So the only thing I needed to do is create a middleware component like the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
public class ApplicationInsightsMobileAppRequestHandler : OwinMiddleware { private readonly TelemetryClient telemetryClient; public ApplicationInsightsMobileAppRequestHandler(OwinMiddleware next) : base(next) { try { // The call initializes TelemetryConfiguration that will create and Intialize modules TelemetryConfiguration configuration = TelemetryConfiguration.Active; telemetryClient = new TelemetryClient(configuration); } catch (Exception exc) { Trace.WriteLine("Error initializing Handler"); Trace.WriteLine(exc.Message); } } public override async Task Invoke(IOwinContext context) { var operation = telemetryClient.StartOperation<RequestTelemetry>(context.Request.Path.Value); try { var requestTelemetry = operation.Telemetry; await this.Next.Invoke(context); requestTelemetry.HttpMethod = context.Request.Method; requestTelemetry.Url = context.Request.Uri; requestTelemetry.ResponseCode = context.Response.StatusCode.ToString(); requestTelemetry.Success = context.Response.StatusCode >= 200 && context.Response.StatusCode < 300; } catch (Exception exc) { var telemetry = new ExceptionTelemetry(exc); telemetry.HandledAt = ExceptionHandledAt.Unhandled; telemetryClient.TrackException(telemetry); } finally { telemetryClient.StopOperation(operation); } } } |
And an extension method to register the middleware in the request pipeline at startup in the Startup class:
1 2 3 4 5 6 7 |
public static class AppBuilderExtensions { public static IAppBuilder UseMobileAppRequestHandler(this IAppBuilder app) { return app.Use<ApplicationInsightsMobileAppRequestHandler>(); } } |
In the application startup class, ensure that you register this handler as the first as follows:
1 2 3 4 5 6 7 |
public static void ConfigureMobileApp(IAppBuilder app) { HttpConfiguration config = new HttpConfiguration(); app.UseMobileAppRequestHandler(); app.UseWebApi(config); ConfigureSwagger(config); } |
And that is it!
When you now deploy tot the azure mobile app, you will see the live metrics as we expect. We still don’t have the memory consumption and CPU usage stats, but this now at least shows all incoming requests in real time
Hope this helps!
Marcel
Thank you Marcelo for your excellent post!
I have the same problem, but using a Web API in MVC 5, and implementing the request handler solved my problem.
Good work!
Marcel, great article!
Was this an Azure mobile App or an Azure Mobile Service? I recently migrated my Azure mobile service using the migrate button on the portable. I am able to see my custom event tracking but no live stream. Is this related to having been an AMS originally or does AI just not support live streaming for Azure mobile “anything”?
-Bob
Integrating the owin mobile app inside asp.net core should be possible and by simply adding the appinsights configuration in the root of your app.