{"id":32764,"date":"2021-04-21T12:28:17","date_gmt":"2021-04-21T19:28:17","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/dotnet\/?p=32764"},"modified":"2022-10-10T21:32:36","modified_gmt":"2022-10-11T04:32:36","slug":"whats-new-in-dotnet-monitor","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/whats-new-in-dotnet-monitor\/","title":{"rendered":"What&#8217;s new in dotnet monitor"},"content":{"rendered":"<p>We&#8217;ve previously introduced <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/introducing-dotnet-monitor\/\"><code>dotnet monitor<\/code> as an experimental tool<\/a> to access diagnostics information in a dotnet process. We&#8217;re now pleased to announce <code>dotnet monitor<\/code> has graduated to a supported tool in the .NET ecosystem. <code>dotnet monitor<\/code> will be fully supported beginning with our first stable release later this year.<\/p>\n<p>If you are new to <code>dotnet monitor<\/code> , we recommend checking out the <a href=\"https:\/\/github.com\/dotnet\/dotnet-monitor\/tree\/main\/documentation\">official documentation<\/a> which includes walkthroughs on using <code>dotnet monitor<\/code> on a local machine, with Docker, and Kubernetes,<\/p>\n<p>This blog post details some of the new major features in the <strong><em>preview4<\/em><\/strong> release of <code>dotnet monitor<\/code>:<\/p>\n<ul>\n<li>Egress providers<\/li>\n<li>Custom metrics<\/li>\n<li>Security and Hardening<\/li>\n<\/ul>\n<h2>Getting Started<\/h2>\n<p><code>dotnet monitor<\/code> is available via two different distribution mechanisms:<\/p>\n<ul>\n<li>As .NET global tool; and<\/li>\n<li>As a container image available via the Microsoft Container Registry (MCR)<\/li>\n<\/ul>\n<h3>.NET global tool<\/h3>\n<p>The\u00a0<code>dotnet monitor<\/code>\u00a0global tool requires a .NET 3.1 or newer SDK installed as a pre-requisite. If you do not have a new enough SDK, you can install a new one from the\u00a0<a href=\"https:\/\/dotnet.microsoft.com\/download\" rel=\"nofollow\">Download .NET webpage<\/a>.<\/p>\n<p>The latest public preview of\u00a0<code>dotnet monitor<\/code>\u00a0is available on Nuget. You can download the latest version using the following command:<\/p>\n<div class=\"highlight highlight-source-batchfile\">\n<pre>dotnet tool install -g dotnet-monitor --version 5.0.0-preview.4.*<\/pre>\n<\/div>\n<p>If you already have\u00a0<code>dotnet monitor<\/code>\u00a0installed and want to update:<\/p>\n<div class=\"highlight highlight-source-batchfile\">\n<pre>dotnet tool update -g dotnet-monitor --version 5.0.0-preview.4.*<\/pre>\n<\/div>\n<h3><a id=\"user-content-container-image\" class=\"anchor\" href=\"https:\/\/github.com\/dotnet\/dotnet-monitor\/blob\/main\/documentation\/setup.md#container-image\" aria-hidden=\"true\"><\/a>Container image<\/h3>\n<p>The latest public preview of the\u00a0<code>dotnet monitor<\/code> container image is available on MCR. You can pull the latest image using the following command:<\/p>\n<div class=\"highlight highlight-source-batchfile\">\n<pre>docker pull mcr.microsoft.com\/dotnet\/monitor:5.0.0-preview.4<\/pre>\n<\/div>\n<h2>Egress providers<\/h2>\n<p>In previous previews, the only way to egress diagnostic artifacts from <code>dotnet monitor<\/code> was via the HTTP response stream. While this works well over reliable connections, this becomes increasingly challenging for very large artifacts and less reliable connections.<\/p>\n<p>In <strong><em>preview4<\/em><\/strong>, you can configure <code>dotnet monitor<\/code> to egress artifacts to other destinations: Azure Blob Storage and the local filesystem. It is possible to specify multiple egress providers via configuration as shown in the example below:<\/p>\n<pre><code class=\"language-json\">{\r\n    \"Egress\": {\r\n        \"Providers\": {\r\n            \"sampleBlobStorageEgressProvider\": {\r\n                \"type\": \"azureBlobStorage\",\r\n                \"accountUri\": \"https:\/\/contoso.blob.core.windows.net\",\r\n                \"containerName\": \"dotnet-monitor\",\r\n                \"blobPrefix\": \"artifacts\",\r\n                \"accountKeyName\": \"MonitorBlobAccountKey\"\r\n            }\r\n        },\r\n        \"Properties\": {\r\n            \"MonitorBlobAccountKey\": \"accountKey\"\r\n        }\r\n    }\r\n}<\/code><\/pre>\n<p>Once configured, at the time of triggering the artifact collection via an HTTP request, you can now specify which egress provider to use. With the configuration above, you can now make the following request:<\/p>\n<pre><code class=\"language-http\">GET \/dump\/?egressProvider=sampleBlobStorageEgressProvider HTTP\/1.1<\/code><\/pre>\n<p>For more detailed instructions on configuring egress providers, look at the <a href=\"https:\/\/github.com\/dotnet\/dotnet-monitor\/blob\/main\/documentation\/configuration.md#egress-configuration\">egress configuration documentation<\/a><\/p>\n<h2>Custom metrics<\/h2>\n<p>In addition to the collection of <code>System.Runtime<\/code> and <code>Microsoft.AspNetCore.Hosting<\/code> metrics, it is now possible to collect additional metrics (emitted via <a href=\"https:\/\/docs.microsoft.com\/dotnet\/core\/diagnostics\/event-counters\">EventCounters<\/a>) for exporting in the <a href=\"https:\/\/github.com\/dotnet\/dotnet-monitor\/blob\/main\/documentation\/api\/metrics.md#sample-request\">Prometheus exposition format<\/a>.<\/p>\n<p>You can configure <code>dotnet monitor<\/code> to collect additional metrics as shown in the example below:<\/p>\n<pre><code class=\"language-json\">{\r\n  \"Metrics\": {\r\n    \"Providers\": [\r\n      {\r\n        \"ProviderName\": \"Microsoft-AspNetCore-Server-Kestrel\"\r\n      }\r\n    ]\r\n  }\r\n}<\/code><\/pre>\n<p>For more detailed instructions on collecting custom metric, look at the <a href=\"https:\/\/github.com\/dotnet\/dotnet-monitor\/blob\/main\/documentation\/configuration.md#metrics-configuration\">metrics configuration documentation<\/a><\/p>\n<h2>Security and Hardening<\/h2>\n<p>Requiring authentication is part of the work that&#8217;s gone into hardening <code>dotnet monitor<\/code> to make it suitable for deployment in production environments. Additionally, to protect the credentials sent over the wire as part of authentication, <code>dotnet monitor<\/code> will also default to requiring that the underlying channel uses HTTPS.<\/p>\n<p>In <code>preview4<\/code> the <code>\/processes<\/code>, <code>\/dump<\/code>, <code>\/gcdump<\/code>, <code>\/trace<\/code>, and <code>\/logs<\/code> API endpoints will require authentication. The <code>\/metrics<\/code> endpoint will still be available without authentication on a separately configured <code>metricsUrl<\/code> for scraping via external tools like Prometheus.<\/p>\n<p>In the local machine scenario with .NET SDK already installed, <code>dotnet monitor<\/code> will default to using ASP.NET Core HTTPS development certificate. If running on Windows, we also enable Windows authentication for secure experience as an alternative to API token auth.<\/p>\n<blockquote><p>Some steps in configuring <code>dotnet monitor<\/code> securely have been omitted for brevity in the blog post. We recommend looking at the <strong><a href=\"https:\/\/github.com\/dotnet\/dotnet-monitor\/blob\/main\/documentation\/authentication.md\">official documentation<\/a> for detailed instructions<\/strong>.<\/p><\/blockquote>\n<p>To get started with <code>dotnet monitor<\/code> in production, you will require an SSL certificate and an API Token.<\/p>\n<h3><a href=\"https:\/\/github.com\/dotnet\/dotnet-monitor\/blob\/main\/documentation\/README.md\">Generating an SSL Certificate<\/a>.<\/h3>\n<p>To configure <code>dotnet monitor<\/code> to run securely, you will need to generate an SSL certificate with an EKU for server usage. You can either request this certificate from your certificate authority or generate a self-signed certificate.<\/p>\n<p>If you wish to generate another self-signed certificate for use on another machine you may do so by invoking the <code>dotnet dev-certs<\/code> tool:<\/p>\n<pre><code class=\"language-cmd\">dotnet dev-certs https -export-path self-signed-certificate.pfx -p &lt;your-cert-password&gt;<\/code><\/pre>\n<h3><a href=\"https:\/\/github.com\/dotnet\/dotnet-monitor\/blob\/main\/documentation\/authentication.md#api-key-authentication\">Generating an API token<\/a><\/h3>\n<p>You should generate a 32-byte cryptographically random secret to use an API token:<\/p>\n<pre><code class=\"language-bash\">dotnet monitor generatekey<\/code><\/pre>\n<p>That should produce an output that resembles this:<\/p>\n<pre><code class=\"language-cmd\">Authorization: MonitorApiKey H2O2yT1c9yLkbDnU9THxGSxje+RhGwhjjTGciRJ+cx8=\r\nApiKeyHash: B4D54269DB7D948A8C640DB65B46D2D705A516134DA61CD97E424AC08E5021ED\r\nApiKeyHashType: SHA256<\/code><\/pre>\n<p>Once you have both an SSL certificate and an API Token generated, you can configure <code>dotnet monitor<\/code> to respond to authenticated HTTP requests over a secure TLS channel using the following configuration:<\/p>\n<pre><code class=\"language-json\">{\r\n  \"ApiAuthentication\": {\r\n    \"ApiKeyHash\": \"&lt;HASHED-TOKEN&gt;\",\r\n    \"ApiKeyHashType\": \"SHA256\"\r\n  },\r\n  \"Kestrel\": {\r\n    \"Certificates\": {\r\n      \"Default\":{\r\n        \"Path\": \"&lt;path-to-cert.pfx&gt;\",\r\n        \"Password\": \"&lt;your-cert-password&gt;\"\r\n      }\r\n    }\r\n  }\r\n}<\/code><\/pre>\n<p>When using Windows Authentication, your browser will automatically handle the Windows authentication challenge. If you are using an API Key, you must specify it via the <code>Authorization<\/code> header on HTTP requests<\/p>\n<pre><code class=\"language-cmd\">curl.exe -H \"Authorization: MonitorApiKey H2O2yT1c9yLkbDnU9THxGSxje+RhGwhjjTGciRJ+cx8=\" https:\/\/localhost:52323\/processes<\/code><\/pre>\n<h2>Roadmap<\/h2>\n<p>We will continue to iterate on <code>dotnet monitor<\/code> with monthly updates until we&#8217;ll release a stable version later this year. <code>dotnet monitor<\/code> supports .NET Core 3.1 as well as .NET 5 and later.<\/p>\n<h2>Conclusion<\/h2>\n<p>We are excited to introduce this major update to <code>dotnet monitor<\/code> and want your feedback. Let us know what we can do to make it easier to diagnose what\u2019s wrong with your .NET application.<\/p>\n<p><a href=\"https:\/\/github.com\/dotnet\/dotnet-monitor\/issues\/new\/choose\">Let us know what you think!<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Learn about what&#8217;s new in dotnet monitor<\/p>\n","protected":false},"author":1233,"featured_media":32051,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[685,7237],"tags":[4],"class_list":["post-32764","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet","category-containers","tag-net"],"acf":[],"blog_post_summary":"<p>Learn about what&#8217;s new in dotnet monitor<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/32764","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/1233"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=32764"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/32764\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/32051"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=32764"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=32764"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=32764"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}