Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Diagnostics #213

Merged
merged 15 commits into from
May 13, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -196,5 +196,7 @@ FakesAssemblies/

# Visual Studio 6 workspace options file
*.opt

samples/MigratingFromMvc5/NewMvc6Project/src/NewMvc6Project/wwwroot/lib/
samples/AngularSample/src/AngularSample/wwwroot/lib
project.lock.json
6 changes: 6 additions & 0 deletions docs/fundamentals/application-insights.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Application Insights
====================

.. note::

This topic hasn't been written yet! You can track the status of this `issue <https://github.com/aspnet/Docs/issues/212>`_ through our public GitHub issue tracker. Learn how you can `contribute <https://github.com/aspnet/Docs/blob/master/CONTRIBUTING.md>`_ on GitHub.
149 changes: 143 additions & 6 deletions docs/fundamentals/diagnostics.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,145 @@
.. include:: /stub-topic.txt
Diagnostics
===========

|stub-icon| Diagnostics
=======================
By :ref:`Steve Smith <diagnostics-author>` | Originally Published: 6 May 2015

.. include:: /stub-notice.txt

.. _issue: https://github.com/aspnet/Docs/issues/62
ASP.NET 5 includes a number of new features that can assist with diagnosing problems. Configuring different handlers for application errors or to display additional information about the application can easily be achieved in the application's startup class.

In this article:
- `Configuring an error handling page`_
- `Using the error page during development`_
- `The runtime info page`_
- `The welcome page`_

`Browse or download samples on GitHub <https://github.com/aspnet/Docs/tree/master/docs/fundamentals/diagnostics/sample>`_.

.. _configure-error-page

Configuring an error handling page
----------------------------------

In ASP.NET 5, you configure the pipeline for each request in the ``Startup`` class's ``Configure()`` method (learn more about `configuration <configuration>`_). You can add a simple error page, meant only for use during development, very easily. All that's required is to add a dependency on ``Microsoft.AspNet.Diagnostics`` to the project (and a ``using`` statement to ``Startup.cs``), and then add one line to ``Configure()`` in ``Startup.cs``:

.. _diag-startup:

.. literalinclude:: diagnostics/sample/src/DiagDemo/Startup.cs
:language: csharp
:linenos:
:emphasize-lines: 2,21

The above code, which is built from the ASP.NET 5 Empty template, includes a simple mechanism for creating an exception on line 36. If a request includes a non-empty querystring parameter for the variable ``throw`` (e.g. a path of ``/?throw=true``), an exception will be thrown. Line 21 makes the call to ``UseErrorPage()`` with `ErrorPageOptions <https://github.com/aspnet/Diagnostics/blob/dev/src/Microsoft.AspNet.Diagnostics/ErrorPageOptions.cs>`_ set to ``ShowAll``. Using ``ErrorPageOptions`` you can toggle the visibility of the following features of the error page:

- Exception details
- Source code
- Query
- Cookies
- Headers

To disable the display of cookies, for instance, you would pass in an options instance configured as follows:

.. code-block:: c#

var errorPageOptions = new ErrorPageOptions();
errorPageOptions.ShowCookies = false;
app.UseErrorPage(errorPageOptions);

Notice that the call to ``UseErrorPage()`` is wrapped inside an ``if`` condition that checks the current ``EnvironmentName``. This is a good practice, since you typically do not want to share detailed diagnostic information about your application publicly once it is in production. This check uses the ``ASPNET_ENV`` environment variable. If you are using Visual Studio 2015, you can customize the environment variables used when the application runs in the web application project's properties, under the Debug tab, as shown here:

.. image:: diagnostics/_static/project-properties-env-vars.png

Setting the ``ASPNET_ENV`` variable to anything other than Development (e.g. Production) will cause the application not to call ``UseErrorPage()``, and thus any exceptions will be handled by the underlying web server package(in this case, ``Microsoft.AspNet.Server.IIS``) as shown here:

.. image:: diagnostics/_static/oops-500.png
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This page comes from Microsoft.AspNet.Server.IIS, not IIS or IIS Express.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


We will cover the features provided by the error page in the next section (ensure ``ASPNET_ENV`` is reset to Development if you are following along).

Using the error page during development
---------------------------------------

The default error page will display some useful diagnostics information when an unhandled exception occurs within the web processing pipeline. The error page includes several tabs with information about the exception that was triggered and the request that was made. The first tab shows the stack trace:

.. image:: diagnostics/_static/errorpage-stack.png

The next tab shows the contents of the Querystring collection, if any:

.. image:: diagnostics/_static/errorpage-query.png
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Crop the bottom of the image to remove unneeded whitespace.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


In this case, you can see the value of the ``throw`` parameter that was passed to this request. This request didn't have any cookies, but if it did, they would appear on the Cookies tab. You can see the headers that were passed, here:

.. image:: diagnostics/_static/errorpage-headers.png
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Crop the bottom of the image to remove unneeded whitespace.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


.. note:: In the current pre-release build, the Cookies section of ErrorPage is not yet enabled. `View ErrorPage Source <https://github.com/aspnet/Diagnostics/blob/dev/src/Microsoft.AspNet.Diagnostics/Views/ErrorPage.cshtml>`_.

The runtime info page
---------------------

In addition to `configuring and displaying an error page <configure-error-page>`_, you can also add a runtime info page by simply calling an extension method in ``Startup.cs``. The following line, is used to enable this feature:

.. code-block:: c#

app.UseRuntimeInfoPage(); // default path is /runtimeinfo

Once this is added to your ASP.NET application, you can browse to the specified path (``/runtimeinfo``) to see information about the runtime that is being used and the packages that are included in the application, as shown below:

.. image:: diagnostics/_static/runtimeinfo-page.png

The path for this page can be optionally specified in the call to ``UseRuntimeInfoPage()``. It accepts a `RuntimeInfoPageOptions <https://github.com/aspnet/Diagnostics/blob/dev/src/Microsoft.AspNet.Diagnostics/RuntimeInfoPageOptions.cs>`_ instance as a parameter, which has a ``Path`` property. For example, to specify a path of ``/info`` you would call ``UseRuntimeInfoPage()`` as shown here:

.. code-block:: c#

app.UseRuntimeInfoPage("/info");

As with ``UseErrorPage()``, it is a good idea to limit public access to diagnostic information about your application. As such, in our sample we are only implementing ``UseRuntimeInfoPage()`` when the EnvironmentName is set to Development.

.. note:: Remember that the ``Configure()`` method in ``Startup.cs`` is defining the pipeline that will be used by all requests to your application, which means the order is important. If for example you move the call to ``UseRuntimeInfoPage()`` after the call to ``app.Run()`` in the examples shown here, it will never be called because ``app.Run()`` will handle the request before it reaches the call to ``UseRuntimeInfoPage``.

.. TODO: Link to UseErrorHandler article.

The welcome page
----------------

Another extension method you may find useful, especially when you're first spinning up a new ASP.NET 5 application, is the ``UseWelcomePage()`` method. Add it to ``Configure()`` like so:

.. code-block:: c#

app.UseWelcomePage();

Once included, this will handle all requests (by default) with a cool hello world page that uses embedded images and fonts to display a rich view, as shown here:

.. image:: diagnostics/_static/welcome-page.png

You can optionally configure the welcome page to only respond to certain paths. The code shown below will configure the page to only be displayed for the ``/welcome`` path (other paths will be ignored, and will fall through to other handlers):

.. code-block:: c#

app.UseWelcomePage("/welcome"));

Configured in this manner, the :ref:`startup.cs <diag-startup>` shown above will respond to requests as follows:

.. list-table:: Requests
:header-rows: 1

* - Path
- Result
* - /runtimeinfo
- ``UseRuntimeInfoPage`` will handle and display runtime info page
* - /welcome
- ``UseWelcomePage`` will handle and display welcome page
* - paths without ``?throw=``
- ``app.Run()`` will respond with "Hello World!"
* - paths with ``?throw=``
- ``app.Run()`` throws an exception; ``UseErrorPage`` handles, displays an error page

Summary
-------

In ASP.NET 5, you can easily add error pages, view diagnostic information, or respond to requests with a simple welcome page by adding just one line to your app's ``Startup.cs`` class.

Additional Resources
--------------------

- `Using Application Insights <application-insights>`_ Collect detailed usage and diagnostic data for your application.

.. _diagnostics-author:

.. include:: /_authors/steve-smith.txt
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 32 additions & 0 deletions docs/fundamentals/diagnostics/sample/DiagDemo.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.22823.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{EFF50CE4-DDB2-40C0-9874-A9AE264FB253}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{460855EB-C77A-4D17-9C43-F2551F7B6CDE}"
ProjectSection(SolutionItems) = preProject
global.json = global.json
EndProjectSection
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "DiagDemo", "src\DiagDemo\DiagDemo.xproj", "{21C3A258-F988-4B75-9D81-C94E28F2480C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{21C3A258-F988-4B75-9D81-C94E28F2480C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{21C3A258-F988-4B75-9D81-C94E28F2480C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{21C3A258-F988-4B75-9D81-C94E28F2480C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{21C3A258-F988-4B75-9D81-C94E28F2480C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{21C3A258-F988-4B75-9D81-C94E28F2480C} = {EFF50CE4-DDB2-40C0-9874-A9AE264FB253}
EndGlobalSection
EndGlobal
6 changes: 6 additions & 0 deletions docs/fundamentals/diagnostics/sample/global.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"projects": [ "src", "test" ],
"sdk": {
"version": "1.0.0-beta4"
}
}
5 changes: 5 additions & 0 deletions docs/fundamentals/diagnostics/sample/src/DiagDemo/Config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"ApplicationInsights": {
"InstrumentationKey" : "b3917205-9414-49bb-8648-3b7e52612fe5"
}
}
19 changes: 19 additions & 0 deletions docs/fundamentals/diagnostics/sample/src/DiagDemo/DiagDemo.xproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>21c3a258-f988-4b75-9d81-c94e28f2480c</ProjectGuid>
<RootNamespace>DiagDemo</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
<DevelopmentServerPort>1593</DevelopmentServerPort>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also enable launchBrowser for web and kestrel

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

launchBrowser is still missing for both kestrel and web, and there should also be a URL field.

"environmentVariables": {
"ASPNET_ENV": "Development"
}
},
"kestrel": {
"commandName": "kestrel",
"launchBrowser": true,
"launchUrl": "http://localhost:12333",
"environmentVariables": {
"ASPNET_ENV": "Development"
}
},
"web": {
"commandName": "web",
"launchBrowser": true,
"launchUrl": "http://localhost:12334",
"environmentVariables": {
"ASPNET_ENV": "Development"
}
}
}
}
47 changes: 47 additions & 0 deletions docs/fundamentals/diagnostics/sample/src/DiagDemo/Startup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Diagnostics;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Http;
using Microsoft.Framework.DependencyInjection;
using System;

namespace DiagDemo
{
public class Startup
{
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (string.Equals(env.EnvironmentName, "Development", StringComparison.OrdinalIgnoreCase))
{
app.UseErrorPage(ErrorPageOptions.ShowAll);

app.UseRuntimeInfoPage(); // default path is /runtimeinfo
}
else
{
// specify production behavior for error handling, for example:
// app.UseErrorHandler("/Home/Error");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this commented out? You could send it to the welcome page for demo purposes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It wouldn't make sense to show /welcome here as the error page, and for demo purposes this isn't running anything in a non-dev environment. We will have a separate article on UseErrorHandler and I added a TODO to link to it when it exists.

// if nothing is set here, web server error page will be displayed
}

app.UseWelcomePage("/welcome");

app.Run(async (context) =>
{
if(context.Request.Query.ContainsKey("throw")) throw new Exception("Exception triggered!");
context.Response.ContentType = "text/html";
await context.Response.WriteAsync("<html><body>Hello World!");
await context.Response.WriteAsync("<ul>");
await context.Response.WriteAsync("<li><a href=\"/welcome\">Welcome Page</a></li>");
await context.Response.WriteAsync("<li><a href=\"/?throw=true\">Throw Exception</a></li>");
await context.Response.WriteAsync("</ul>");
await context.Response.WriteAsync("</body></html>");
});
}
}
}
34 changes: 34 additions & 0 deletions docs/fundamentals/diagnostics/sample/src/DiagDemo/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"webroot": "wwwroot",
"version": "1.0.0-*",

"dependencies": {
"Microsoft.AspNet.Server.IIS": "1.0.0-beta4",
"Microsoft.AspNet.Server.WebListener": "1.0.0-beta4",
"Microsoft.AspNet.Diagnostics": "1.0.0-beta4",
"Kestrel": "1.0.0-beta4"
},

"commands": {
"web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:12334",
"kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:12333"
},

"frameworks": {
"dnx451": { },
"dnxcore50": { }
},

"publishExclude": [
"node_modules",
"bower_components",
"**.xproj",
"**.user",
"**.vspscc"
],
"exclude": [
"wwwroot",
"node_modules",
"bower_components"
]
}
1 change: 1 addition & 0 deletions docs/fundamentals/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Fundamentals
dependency-injection
options
diagnostics
application-insights
logging
app-state
environments
Expand Down