On the node.js version of mobile services, logging was done mostly via the node’s console object. In any of the server scripts you could call console.[log|warn|error] and when that script was executed you could go to the “logs” tab in the portal to see them. In the .NET backend you still have the same capabilities, but there are some new features and quirks which one should be aware to get the best logging experience in that new backend. Let’s go over them here.
Logging when running locally
This is a very simple example of logging in the .NET backend. If we write this controller class, we can use the
Log property in the
Services member of the
TableController<T> class to write to the Azure logs. Notice that the
Info method in the
Log property used below is an extension method and you need to add a ‘
using System.Web.Http;’ statement to see it (same for the
When we publish the application to Azure and insert an item, we can see the log in the “logs” tab in the azure portal.
However, when we’re running the backend locally, there is no portal where we can see the logs, so where can we find them. As one user in Stack Overflow had this question, I imagine that others may have the same problem. And there’s nothing really fancy here – the logging is implemented (by default, see more advanced topics later) using the standard System.Diagnostics tracing system, so we can add a new listener in the web.config and send the log output to some file where you can read:
If we send the same request to the local service, we can now find it out the traces.
iisexpress.exe Information: 0 : Message='[PostItem] Inserting new item: 01234567-89ab-cdef-0123-456789abcdef-1′, Id=00000000-0000-0000-0000-000000000000, Category=’PostItem’
Another alternative, if you’re running the local .NET backend under the debugger, you can look at the “Output” window, selecting “Show output from: Debug”, and the traces will be shown in the window. If that’s the case you don’t even need to add a trace listener, as when running under the debugger VS will add one listener by default that writes to its output/debug window. There will be some noise on other information which is traced to the debug window, but that may be an acceptable solution as well.
The traces does not have the same format as we find in the portal, but that’s a quick way to get the information you want.
But what if you really want a better formatted traces? Not a problem. The .NET backend uses the same system as its underlying framework, ASP.NET Web API. All traces are written via the
ITraceWriter interface, and you can supply your own implementation of that interface, like in the code below, which uses a format very similar to the one displayed in the portal. The “category” parameter by default has the name of the member (typically method or property) where the log method was called, but it can be customized for anything that makes sense for your application.
And to use it we can replace the trace writer service with our own implementation in the
HttpConfiguration object returned by the
The document Tracing in ASP.NET Web API has a good introduction on the tracing system used by Web API (and the .NET backend of the mobile service). Now, everything works fine when we run locally, but if we publish the service to Azure and invoke the operations in the controller again, we won’t see the traces in the portal anymore. The problem is that while we’re tracing to the System.Diagnostic subsystem, that is not hooked up to the tracing in the service running in Azure. We can fix that by passing the original trace writer (which can trace within Azure) to our trace writer implementation:
And when creating our trace writer we can pass the original writer if the service is running in Azure (which you can access via the extension method
GetIsHosted – you’ll need to add a
"using System.Web.Http" statement if you don’t have already to see that method).
Notice that for the case of a better local logging you could also only replace the trace writer if the service was running locally (i.e., if it was not hosted). But that organization will be useful in the next section.
Changing logs destination
Looking at the traces in the portal is fine during development, but as the service goes into production and if your mobile application is successful, you can expect thousands of traces being generated, and going through them via the portal isn’t the ideal way to analyze your logs. But since we can own completely the logging implementation, nothing prevents us from redirecting the logs to some external source – for example, table storage, where you can fetch and analyze them easier with several of the existing tools. Let’s change our trace listener implementation to send the logs to a table in Azure Storage if the service is running in the cloud.
You’ll need to add a reference to the “Windows Azure Storage” package if you haven’t done it yet to be able to use the classes shown in the code above. The
TableTraceRecord class is defined as a subclass of TableEntity, which is required to insert items into the tables. In this example I’m using the timestamp as the row key to make it easier to sort based on the trace order (and adding a random set of characters to disambiguate in case multiple trace requests come at the exact same instant).
We now need to pass the connection string and mobile service name to the trace writer class. The recommended way to store the connection string is via the app settings, so I’ll add the connection string fro my account there:
And on the
Register method we retrieve the values we need from the application settings.
Now when the trace is executed, it will write to the table storage.
More logging please!
So far we’re looking at how to look at the logs which our application writes out. But the .NET backend also exposes other kinds of logs which you can see as well. When we’re initializing the service configuration, we can pass a set of configuration options. One of them is the list of trace categories which are excluded from the traces. By default, internal traces are excluded, but we can remove those by clearing the
ExcludedTraceCategories list in the config options passed to the initializer, as shown below.
Try it out – you’ll see more information about the inner workings of the backend. Definitely some information that the majority of the users won’t need, but a good way to get a better view of what’s happening behind the scenes.
Another thing which we can do in the traces is change the log level. By default only traces with level of
Info and higher are logged. If you use
Services.Log.Debug in one of your controllers that log will not be written to the logs. You can use the
MinimumTraceLevel property in the
ConfigOptions object to change what will show up in the logs.
With this change, now all traces, from debug to error, are written out to the logs.
I hope this post will help you understand how to better use the logging subsystems in the .NET backend for mobile services. As usual, feel free to submit questions or comments to this post, the MSDN forums or contact us via Twitter @AzureMobile.