> For the complete documentation index, see [llms.txt](https://docs.umbraco.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.umbraco.com/umbraco-cms/develop-with-umbraco/testing-and-debugging.md).

# Testing and Debugging

During the development of your Umbraco site you can debug and profile the code you have written to analyse and discover bottlenecks in your code.

To perform proper debugging on your site you need to set your application to have debug enabled. This can be done by setting `Umbraco:CMS:Hosting:Debug="true"` for example in the `appsettings.json` file:

```json
{
  "Umbraco": {
    "CMS": {
      "Hosting": {
        "Debug": true
      }
    }
  }
}
```

{% hint style="warning" %}
Debug should always be set to false in production.
{% endhint %}

## Tracing

Tracing and trace logging are two names for the same technique. You need to configure which log messages you want to log.

### Enabling Trace Logging

{% hint style="warning" %}
Do not enable trace logging in your production environment! It reveals an awful lot of (sensitive) information about your production environment.
{% endhint %}

We recommend at least logging the following namespace at minimum (Verbose) level to enable valuable trace logging. Thereby you will have information about all endpoints that have been executed.

```json
{
  "Serilog": {
    "MinimumLevel": {
      "Override": {
        "Microsoft.AspNetCore.Mvc": "Verbose"
      }
    }
  }
}
```

The logged messages can as always be monitored in the log viewer in backoffice

## MiniProfiler

Umbraco includes the Mini Profiler project in its core (see <https://miniprofiler.com> for more details). The MiniProfiler profiles your code method calls, giving you a greater insight into code duration and query time for (for example) underlying SQL queries. It's great for tracking down performance issues in your site's implementation.

### Displaying the MiniProfiler

To display the profiler on the front end of your site:

* Set `Umbraco:CMS:Hosting:Debug` to `true` in `appsettings.json`.
* Sign in to the backoffice as a user who has access to the **Settings** section.
* Add `?umbDebug=true` to the request query string.

Instead of the query string, you can activate the profiler in either of these ways:

* Use the **Activate the profiler by default** toggle on the **Profiling** dashboard in the **Settings** section. The toggle sets a cookie, so it only works when the backoffice and website share the same domain. For more information, see the [Settings Dashboards](/umbraco-cms/model-your-content/content-types-and-structure/backoffice/settings-dashboards.md) article.
* Send an `X-UMB-DEBUG: true` header with the request. Use this option for cross-site setups.

The profiler is displayed on pages rendered by Razor views. For other requests, such as calls to the Content Delivery API, view the stored results at `/umbraco/profiler/results-index`. Only backoffice users with access to the **Settings** section can view these results.

{% hint style="info" %}
The results list relies on an inline script. If your site uses a Content Security Policy that blocks inline scripts, the list is displayed empty. For more information, see the [Content Security Policy (CSP)](/umbraco-cms/run-in-production/infrastructure-and-ops/health-check/guides/contentsecuritypolicy.md) article.
{% endhint %}

<figure><img src="https://1282852327-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbFfxUcTsPCzuMkpCkZsT%2Fuploads%2Fgit-blob-db39a3caab102f81e600a1707b012681bb0f5f09%2Fv8-miniprofiler-view.png?alt=media" alt=""><figcaption></figcaption></figure>

If you click 'Show Trivial' you can seen the kind of detail the MiniProfiler makes available to you about the execution path of your page:

<figure><img src="https://1282852327-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbFfxUcTsPCzuMkpCkZsT%2Fuploads%2Fgit-blob-7b36e615056c799fe8001d68c5a408a8e706cb13%2Fv8-miniprofiler-trivial.png?alt=media" alt=""><figcaption></figcaption></figure>

and any underlying SQL Statements that are being executed for a part of the execution:

<figure><img src="https://1282852327-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbFfxUcTsPCzuMkpCkZsT%2Fuploads%2Fgit-blob-ea1a4c208c187cf27558bf2083b1e66e1150b166%2Fv8-miniprofiler-sql-trigger.png?alt=media" alt=""><figcaption></figcaption></figure>

![Underlying SQL query details](https://1282852327-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbFfxUcTsPCzuMkpCkZsT%2Fuploads%2Fgit-blob-9535949c1e3293ab18b97ac1842fc29c13c5b228%2Fv8-miniprofiler-sql-details.png?alt=media)

### Profiling Views and Partials

Umbraco profiles SQL queries and the time spent locating views. The first profiled request after the site starts also includes the startup timings.

The time spent rendering a partial view is not recorded as a separate step. It is included in the timing of the view that renders the partial.

For each SQL query, the MiniProfiler shows a stack trace of the code that executed it. When partial views, view components, or services run asynchronously, this stack trace is less useful. It shows framework and compiler-generated methods rather than your own code, so you can't tell which partial view ran the query.

To see how long each part of a view takes, wrap it in the `<profile>` tag helper. The tag helper adds a named step to the profiler. The SQL queries executed inside the tag helper appear under that step.

The tag helper is part of the `MiniProfiler.AspNetCore.Mvc` package, which Umbraco already references. To use it, register the tag helper in `Views/_ViewImports.cshtml`:

{% code title="\_ViewImports.cshtml" %}

```csharp
@addTagHelper *, MiniProfiler.AspNetCore.Mvc
```

{% endcode %}

Then wrap the markup you want to profile:

{% code title="HomePage.cshtml" %}

```csharp
<profile name="Latest articles">
    <partial name="LatestArticles" />
</profile>

<profile name="Navigation">
    @await Html.PartialAsync("Navigation")
</profile>
```

{% endcode %}

When the profiler is not active, the `<profile>` tag helper renders its content without recording anything. You can leave the tag helper in your views when you deploy to production.

For more information, see the [MiniProfiler ASP.NET Core documentation](https://miniprofiler.com/dotnet/AspDotNetCore).

### Writing to the MiniProfiler

If you feel like a part of your application is slow you can use the MiniProfiler in your code to test the speed of it.

All you have to do is inject the IProfiler interface and add a step around your logic:

```csharp
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Microsoft.Extensions.Logging;
using Umbraco.Cms.Core.Logging;
using Umbraco.Cms.Core.Web;
using Umbraco.Cms.Web.Common.Controllers;

namespace MyCustomUmbracoProject;

public class RootController : RenderController
{
    private readonly IProfiler _profiler;

    public RootController(
        IProfiler profiler,
        ILogger<RenderController> logger,
        ICompositeViewEngine compositeViewEngine,
        IUmbracoContextAccessor umbracoContextAccessor)
        : base(logger, compositeViewEngine, umbracoContextAccessor)
    {
        _profiler = profiler;
    }

    public override IActionResult Index()
    {
        // Perform a step
        using (_profiler.Step("Sleep"))
        {
            System.Threading.Thread.Sleep(1000);
        }

        return base.Index();
    }
}
```

and now in the profiler you can see:

![Show Trivial](https://1282852327-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbFfxUcTsPCzuMkpCkZsT%2Fuploads%2Fgit-blob-cd40b9f107cf4aa8deb1f84205297aee253c52aa%2Fv8-miniprofiler-write.png?alt=media)

#### Using the MiniProfiler API

`IProfiler` is the Umbraco abstraction over the MiniProfiler and covers most profiling needs. Use `IProfiler` when a `Step` is enough. Your code then doesn't depend on the MiniProfiler package, and you can mock the profiler in unit tests.

`IProfiler` doesn't expose every MiniProfiler feature. For these features, use `MiniProfiler.Current` from the `StackExchange.Profiling` namespace. It provides methods such as:

* `StepIf`: records a step only when it takes longer than a given number of milliseconds.
* `CustomTiming`: records a timing in its own category, for example, calls to an external API.
* `Ignore`: excludes a block of code from the results.

The following example records calls to an external API in an `http` category. The MiniProfiler displays these timings in a separate column, next to the SQL timings.

{% code title="WeatherService.cs" %}

```csharp
using StackExchange.Profiling;

namespace MyCustomUmbracoProject;

public class WeatherService
{
    private readonly HttpClient _httpClient;

    public WeatherService(HttpClient httpClient) => _httpClient = httpClient;

    public async Task<string> GetForecastAsync(string city)
    {
        var url = $"https://api.example.com/forecast?city={city}";

        using (MiniProfiler.Current.CustomTiming("http", url, "GET"))
        {
            return await _httpClient.GetStringAsync(url);
        }
    }
}
```

{% endcode %}

The `MiniProfiler.Current` methods do nothing when the profiler is not active.

For details of these and other methods, see [Profile Code](https://miniprofiler.com/dotnet/HowTo/ProfileCode) in the MiniProfiler documentation.

## Umbraco Productivity Tool - Chrome Extension

If you are using the Google Chrome browser you can install this [Umbraco Productivity Tool Chrome Extension](https://chrome.google.com/webstore/detail/umbraco-productivity/kepkgaeokeknlghbiiipbhgclikjgkdp?hl=en).

This will allow you to quickly switch between debugging with the MiniProfiler, Trace viewer and normal mode.

![Umbraco Productivity Tool](https://1282852327-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbFfxUcTsPCzuMkpCkZsT%2Fuploads%2Fgit-blob-922074898af98704af5260847f33da828a5a5e36%2Fchrome-tool.png?alt=media)

## [Logging](/umbraco-cms/develop-with-umbraco/testing-and-debugging/logging.md)

Learn how Umbraco writes log files and how you can write to them.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.umbraco.com/umbraco-cms/develop-with-umbraco/testing-and-debugging.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
