[Dotnet Monitor Experimental] Add getting started for metrics usage using dotnet-monitor (#3318)

* getting-started-dotnet-monitor-metrics

* fix markdownlint

* Raname NextGen.AutoInstrumentation to just next-gen

* Remove logger code.
This commit is contained in:
Rajkumar Rangaraj 2024-03-15 20:27:39 -07:00 committed by GitHub
parent 90f347f38e
commit 0a3cb6e8b0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 282 additions and 0 deletions

View File

@ -221,6 +221,10 @@ Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "TestApplication.ContinuousP
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestApplication.ContinuousProfiler.ContextTracking", "test\test-applications\integrations\TestApplication.ContinuousProfiler.ContextTracking\TestApplication.ContinuousProfiler.ContextTracking.csproj", "{B74CB036-10F5-449D-8CBA-44F77E68D042}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "next-gen", "next-gen", "{3F051815-8E0D-4356-BC36-55CA642DDF18}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "getting-started-dotnet-monitor-metrics", "next-gen\docs\getting-started-dotnet-monitor-metrics\getting-started-dotnet-monitor-metrics.csproj", "{022A03CE-DD7A-4326-847E-3B750E660845}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -1377,6 +1381,22 @@ Global
{B74CB036-10F5-449D-8CBA-44F77E68D042}.Release|x64.Build.0 = Release|x64
{B74CB036-10F5-449D-8CBA-44F77E68D042}.Release|x86.ActiveCfg = Release|x86
{B74CB036-10F5-449D-8CBA-44F77E68D042}.Release|x86.Build.0 = Release|x86
{022A03CE-DD7A-4326-847E-3B750E660845}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{022A03CE-DD7A-4326-847E-3B750E660845}.Debug|Any CPU.Build.0 = Debug|Any CPU
{022A03CE-DD7A-4326-847E-3B750E660845}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{022A03CE-DD7A-4326-847E-3B750E660845}.Debug|ARM64.Build.0 = Debug|Any CPU
{022A03CE-DD7A-4326-847E-3B750E660845}.Debug|x64.ActiveCfg = Debug|Any CPU
{022A03CE-DD7A-4326-847E-3B750E660845}.Debug|x64.Build.0 = Debug|Any CPU
{022A03CE-DD7A-4326-847E-3B750E660845}.Debug|x86.ActiveCfg = Debug|Any CPU
{022A03CE-DD7A-4326-847E-3B750E660845}.Debug|x86.Build.0 = Debug|Any CPU
{022A03CE-DD7A-4326-847E-3B750E660845}.Release|Any CPU.ActiveCfg = Release|Any CPU
{022A03CE-DD7A-4326-847E-3B750E660845}.Release|Any CPU.Build.0 = Release|Any CPU
{022A03CE-DD7A-4326-847E-3B750E660845}.Release|ARM64.ActiveCfg = Release|Any CPU
{022A03CE-DD7A-4326-847E-3B750E660845}.Release|ARM64.Build.0 = Release|Any CPU
{022A03CE-DD7A-4326-847E-3B750E660845}.Release|x64.ActiveCfg = Release|Any CPU
{022A03CE-DD7A-4326-847E-3B750E660845}.Release|x64.Build.0 = Release|Any CPU
{022A03CE-DD7A-4326-847E-3B750E660845}.Release|x86.ActiveCfg = Release|Any CPU
{022A03CE-DD7A-4326-847E-3B750E660845}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -1459,6 +1479,7 @@ Global
{6D35660B-8EFD-4DB6-BE13-46F98BFB626E} = {82A3CE96-0935-45E5-A9AA-A93A5B63500B}
{F10D863B-397D-410E-96AF-D9A749876616} = {82A3CE96-0935-45E5-A9AA-A93A5B63500B}
{B74CB036-10F5-449D-8CBA-44F77E68D042} = {E409ADD3-9574-465C-AB09-4324D205CC7C}
{022A03CE-DD7A-4326-847E-3B750E660845} = {3F051815-8E0D-4356-BC36-55CA642DDF18}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {160A1D00-1F5B-40F8-A155-621B4459D78F}

View File

@ -0,0 +1,2 @@
<Project>
</Project>

View File

@ -0,0 +1,27 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
using System.Diagnostics.Metrics;
public class Program
{
private static readonly Meter MyMeter = new("MyCompany.MyProduct.MyLibrary", "1.0");
private static readonly Counter<long> MyFruitCounter = MyMeter.CreateCounter<long>("MyFruitCounter");
public static void Main()
{
Console.WriteLine("Press any key to exit");
while (!Console.KeyAvailable)
{
MyFruitCounter.Add(1, new("name", "apple"), new("color", "red"));
MyFruitCounter.Add(2, new("name", "lemon"), new("color", "yellow"));
MyFruitCounter.Add(1, new("name", "lemon"), new("color", "yellow"));
MyFruitCounter.Add(2, new("name", "apple"), new("color", "green"));
MyFruitCounter.Add(5, new("name", "apple"), new("color", "red"));
MyFruitCounter.Add(4, new("name", "lemon"), new("color", "yellow"));
Thread.Sleep(300);
}
}
}

View File

@ -0,0 +1,221 @@
# Getting Started with dotnet-monitor, Prometheus and Grafana
- [Produce metrics from the application](#produce-metrics-from-the-application)
- [Collect metrics using dotnet-monitor](#collect-metrics-using-dotnet-monitor)
- [Configuration](#configuration)
- [Running dotnet-monitor](#running-dotnet-monitor)
- [Access and validate the metrics](#access-and-validate-the-metrics)
- [Collect metrics using Prometheus](#collect-metrics-using-prometheus)
- [Prometheus Configuration](#prometheus-configuration)
- [Start Prometheus](#start-prometheus)
- [View results in Prometheus](#view-results-in-prometheus)
- [Explore metrics using Grafana](#explore-metrics-using-grafana)
## Produce metrics from the application
Create a new console application and run it:
```sh
dotnet new console --output getting-started-dotnet-monitor-metrics
cd getting-started-dotnet-monitor-metrics
dotnet run
```
Now copy the code from [Program.cs](./Program.cs) and run the application again.
For our learning purpose, use a while-loop to keep increasing the counter value
until any key is pressed.
```csharp
Console.WriteLine("Press any key to exit");
while (!Console.KeyAvailable)
{
Thread.Sleep(1000);
MyFruitCounter.Add(1, new("name", "apple"), new("color", "red"));
MyFruitCounter.Add(2, new("name", "lemon"), new("color", "yellow"));
MyFruitCounter.Add(1, new("name", "lemon"), new("color", "yellow"));
...
...
...
}
```
## Collect metrics using dotnet-monitor
Follow the [install
steps](https://learn.microsoft.com/en-us/dotnet/core/diagnostics/dotnet-monitor#install)
to download the dotnet-monitor.
### Configuration
1. **Configure dotnet-monitor API key**: To secure access to the dotnet-monitor
endpoints, you can set up an API key authentication by following the steps
outlined in [Configuring API Key
Authentication](https://github.com/dotnet/dotnet-monitor/blob/main/documentation/api-key-setup.md#configuring-api-key-authentication).
If your use case is limited to a test environment, you might opt to bypass API
key configuration by using the `--no-auth` switch when running dotnet-monitor.
Learn more about dotnet-monitor authentication
[here](https://github.com/dotnet/dotnet-monitor/blob/1beca4d497da1e60985394fe7d1195c0663f7095/documentation/authentication.md?plain=1#L115).
2. **Set a default process and customize metrics collection**: To monitor a
specific local process and capture custom metrics, use a settings.json file.
This file defines both the default process to monitor and the specific meters
to collect metrics. For instance, to monitor a
`getting-started-dotnet-monitor-metrics` process and collect metrics from the
"MyCompany.MyProduct.MyLibrary" meter, create a settings.json file with the
following content:
```json
{
"$schema": "https://aka.ms/dotnet-monitor-schema",
"DefaultProcess": {
"Filters": [{
"Key": "ProcessName",
"Value": "getting-started-dotnet-monitor-metrics"
}]
},
"Metrics": {
"Meters": [
{
"MeterName": "MyCompany.MyProduct.MyLibrary"
}
]
}
}
```
When starting dotnet-monitor, specify the path to this settings.json file using
the `--configuration-file-path` switch.
### Running dotnet-monitor
Run dotnet-monitor in a command prompt or terminal. If you have configured an
API key, ensure to use it. If you are running in a test environment and prefer
not to use authentication, you can start dotnet-monitor with the `--no-auth`
switch:
```bash
dotnet-monitor collect --no-auth --configuration-file-path path/to/settings.json
```
Or, if you have set up an API key:
```bash
dotnet-monitor collect --configuration-file-path path/to/settings.json
```
This command starts the collection process. By default, dotnet-monitor listens
on [http://localhost:52325/](http://localhost:52325/).
### Access and validate the metrics
Access the metrics endpoint. Once dotnet-monitor is running, you can access the
metrics endpoint using a web browser or a tool like curl. The default URL for
metrics is [http://localhost:52325/metrics](http://localhost:52325/metrics). If
you are using authentication, include the API key in your request header. For
example, using curl with an API key:
```bash
curl -H "Authorization: Bearer <Your-API-Key>" http://localhost:52325/metrics
```
Without authentication (in test environments):
```bash
curl http://localhost:52325/metrics
```
![Browser UI](images/dotnet-monitor-metrics.jpg)
Now, we understand how we can configure dotnet-monitor to collect metrics. Next,
we are going to learn about how to use Prometheus to capture metrics from
dotnet-monitor.
## Collect metrics using Prometheus
Follow the [first steps](https://prometheus.io/docs/introduction/first_steps/)
to download the [latest release](https://prometheus.io/download/) of Prometheus.
### Prometheus Configuration
After finished downloading, extract it to a local location that's easy to
access. We will find the default Prometheus configuration YAML file in the
folder, named `prometheus.yml`.
Let's create a new file in the same location as where `prometheus.yml` locates,
and named the new file as `otel.yml` for this exercise. Then, copy and paste the
entire content below into the `otel.yml` file we have created just now.
```yaml
global:
scrape_interval: 10s
evaluation_interval: 10s
scrape_configs:
- job_name: "otel"
static_configs:
- targets: ["localhost:52325"]
```
### Start Prometheus
Follow the instructions from
[starting-prometheus](https://prometheus.io/docs/introduction/first_steps/#starting-prometheus)
to start the Prometheus server and verify it has been started successfully.
Please note that we will need pass in `otel.yml` file as the argument:
```console
./prometheus --config.file=otel.yml
```
### View results in Prometheus
To use the graphical interface for viewing our metrics with Prometheus, navigate
to [http://localhost:9090/graph](http://localhost:9090/graph), and type
`mycompanymyproductmylibrary_MyFruitCounter` in the expression bar of the UI;
finally, click the execute button.
We should be able to see the following chart from the browser:
![Prometheus UI](images/prometheus.jpg)
From the legend, we can see that the `instance` name and the `job` name are the
values we have set in `otel.yml`.
Congratulations!
Now we know how to configure Prometheus server and collect our metrics using
dotnet-monitor. Next, we are going to explore a tool called Grafana, which has
powerful visualizations for the metrics.
### Explore metrics using Grafana
[Install Grafana](https://grafana.com/docs/grafana/latest/installation/).
Start the standalone Grafana server (`grafana-server.exe` or
`./bin/grafana-server`, depending on the operating system). Then, use the
browser to navigate to [http://localhost:3000/](http://localhost:3000/).
Follow the instructions in the Grafana getting started
[doc](https://grafana.com/docs/grafana/latest/getting-started/getting-started/#step-2-log-in)
to log in.
After successfully logging in, click on the explore option on the left panel of
the website - we should be able to write some queries to explore our metrics
now!
Feel free to find some handy PromQL
[here](https://promlabs.com/promql-cheat-sheet/).
In the below example, the query targets to find out what is the per-second rate
of increase of myFruitCounter over the past 5 minutes:
![Grafana UI](images/grafana.jpg)
## Learn more
- [What is Prometheus?](https://prometheus.io/docs/introduction/overview/)
- [Prometheus now supports OpenTelemetry
Metrics](https://horovits.medium.com/prometheus-now-supports-opentelemetry-metrics-83f85878e46a)
- [Grafana support for
Prometheus](https://prometheus.io/docs/visualization/grafana/#creating-a-prometheus-graph)

View File

@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>getting_started_dotnet_monitor_metrics</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 KiB