Use Prometheus in .net core application - .net-core

I am doing POC using Prometheus in .net core app. I did not found sufficient information on Prometheus website to get started , I have following question if someone can answer that would be helpful
a) Do I need to write my own .net core client in order to use
prometheus in app?
b) What is best approach to use prometheus for metric recording such as
should I use in every client or add prometheus logging logic in
services method so that metrics is logged for each request and
response in pipeline ?
c) where to configure prometheus server in .net core app ?

Monitor .Net core web API using prometheus
Install the below packages
<PackageReference Include="App.Metrics.AspNetCore" Version="3.2.0" />
<PackageReference Include="App.Metrics.AspNetCore.Endpoints" Version="3.2.0" />
<PackageReference Include="App.Metrics.AspNetCore.Tracking" Version="3.2.0" />
<PackageReference Include="App.Metrics.Formatters.Prometheus" Version="3.2.0" />
Add the below code in Program.cs class to support prometheus
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseMetricsWebTracking()
.UseMetrics(option =>
{
option.EndpointOptions = endpointOptions =>
{
endpointOptions.MetricsTextEndpointOutputFormatter = new MetricsPrometheusTextOutputFormatter();
endpointOptions.MetricsEndpointOutputFormatter = new MetricsPrometheusProtobufOutputFormatter();
endpointOptions.EnvironmentInfoEndpointEnabled = false;
};
})
.UseStartup<Startup>();
Make sure these below endpoints are working after making all the above changes
http://<ip:port>/metrics
http://<ip:port>/metrics-text
Add a new job in prometheus.yml
- job_name: 'SampleWebAPi'
metrics_path: /metrics-text
static_configs:
- targets: ['<ip:port>']
Restart prometheus & then check targets page
http://localhost:9090/targets
Github Code

.net client for prometheus.io now supports.NET Core 2.0:
https://github.com/prometheus-net/prometheus-net
Client is suggested here: https://prometheus.io/docs/instrumenting/clientlibs/

We are using our own open source library because no other existing solution worked correctly at the time we started using Prometheus.
https://github.com/nexogen-international/Nexogen.Libraries.Metrics
This library can add a lot of metrics out-of-the box. I recommend measuring everything you can as you can never know what will be a bottleneck in production. At least measure everything that can be a key performance indicator, like number of visitors or the time it takes to do some long operation.
The library can be configured in your ASP.NET Core Startup. I recommend injecting your metrics through an interface containing your relevant metrics.
If you have a non ASP.NET app, then you can simply set it up in your main class.

Use the this nuget library if you are using dotnet core. This will give lot of metrics out of the box.
In Configure method of startup.cs.
add app.UseHttpMetrics() after app.UseRouting. Futhermore add endpoints.MapMetrics(); as end point which expose end point to scrap prometheus metrics
Sample project here:
Repo: https://github.com/CodeSam621/YT_DotNetCorePrometheusGrafana
app.UseRouting();
app.UseHttpMetrics();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapMetrics();
endpoints.MapControllers();
});
https://www.youtube.com/watch?v=cvt1Vrs3ajU

Related

How do I include multiple proto files in a .NetCore gRPC project?

I'm creating a .NetCore C# desktop app using gRPC.
I'm attempting to use the Orchestrator pattern (microservices).
The basic design is:
Client (requester) <--> Orchestrator <--> multiple different request handlers
Each RequestHandler will have it's own set of messages.
Is it possible to have "Client" GrpcServices within the same project file,
or do I need to include all my proto message definitions within a single file?
With the setup listed below, my projects fail to load.
Here is the related snippet from my .csproj file:
<ItemGroup>
<Protobuf Include="../Protos/linuxservice.proto" GrpcServices="Client" ProtoRoot="../Protos/">
<Link>Protos/linuxservice.proto</Link>
</Protobuf>
<Protobuf Include="../Protos/orchestrator.proto" GrpcServices="Server" ProtoRoot="../Protos/">
<Link>Protos/orchestrator.proto</Link>
</Protobuf>
<Protobuf Include="../Protos/service.proto" GrpcServices="Client" ProtoRoot="../Protos/">
<Link>Protos/service.proto</Link>
</Protobuf>
Protobuf Include="../Protos/windowsservice.proto" GrpcServices="Client" ProtoRoot="../Protos/">
<Link>Protos/windowsservice.proto</Link>
</Protobuf>
</ItemGroup>
Well after so much trial and error I managed to create several props and that each one of them is consumed by its respective service.
Create your proto file
Check the properties of the file.
Build Action => Protobuf, compiler grpc subclasses => server only,
Compile protobuf => yes
Recompile the project and this automatically generates the Base class
add your service in app.MapGrpcService
I put the link where he gave me a guide, I hope it helps you.
https://medium.com/#lukastosic/part-1-grpc-its-fairly-simple-c-example-d4b266c4c72e
Blessings

What is the .NET Core way of storing application settings?

I'm developing a cross-platform (win/mac/linux) application and I'm looking to store my application state. What is the .NET Core recommended way of doing this?
I've dug through the documentation and the closest thing I found was this, which is aimed at Visual Studio/.NET Framework (and I'm on VS Code).
There are 3 ways,
ONLY For Localhost
Simply stash them in your appsettings.json or as environment
variables.
For Staging / Production,
Azure Key Vault
By utilising Azure Key Vault and the Microsoft.Extensions.Configuration.AzureKeyVault NuGet Package, you will be able to stash configurations for your projects in the best way possible in the actual environment.
You then simply inject it in,
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((context, config) =>
{
var root = config.Build();
config.AddAzureKeyVault(
$”https://{root["KeyVault:Vault"]}.vault.azure.net/",
root[“KeyVault:ClientId”],
root[“KeyVault:ClientSecret”]);
})
.UseStartup<Startup>();
Although you still have to stash those 3 variables in, Azure has Azure AD to enforce access only to specified Applications. Thus, you need to register an application under the Azure AD in order for this to work. There are also restrictive features that will help you sandbox Azure Key Vault further.
Existing Vault Storages
Last but not least, the last way is to utilise existing vault storage options like HashiCorp. Libraries like https://github.com/rajanadar/VaultSharp will help you to implement it quickly and effectively. This is suitable for you if you primarily use a non-Azure provider for your servers.
As described here, you can use appsettings.json, which is generated and referenced within the new project template in dotnet new command
You can use the ConfigurationBuilder from the Microsoft.Extensions.Configuration nuget package
Although the docs are for ASP Core, you should be able to use them in your regular .Net Core app.
Create settings.json:
{
"mysetting": "value",
}
And use it:
var configuration = new ConfigurationBuilder()
.AddJsonFile("settings.json")
.Build();
// get the values from the settings.json
var mySetting = configuration["mysetting"];
Console.WriteLine(mySetting);

How environment variables configuration works in dotnet core?

In Enforce HTTPS with dotnet core, there needs to be a port specified for ssl. That port needs to be passed to the application.
See in this clear way to get a docker container to run dotnet core with ssl, one of the things we need to do is pass environment variables that the dotnet core application will use; as per the configuration system details here.
Also, in the same Enforce HTTPS with dotnet core article, you can pass something like
the useSetting()
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseSetting("HTTPS_PORT", "443")
.UseSetting("URLS", "http://+;https://+")
.UseStartup<Startup>();
Which is the same as passing ASPNETCORE_HTTPS_PORT=443 as an environment variable.
I'm really looking for where on earth I can find clear documentation on what each possible variable can be and what they do.
The settings for WebHost are well documented.

.NET Core, Parallel Run of the same application with different configuration possible?

I am trying to get my head around the .netcore way of configuring an application.
Szenario:
I am running the same rest api (application) for client1 and client2 on the same server in the DEV-Environment.
We have environment specific configurations as well as client specific configurations.
"Old" Way:
With web.config transformations, I created build configurations for dev-client1 and dev-client2 and set the values accordingly...this all worked fine.
"New" Way:
As the appsettings.json depends on the windows environment variable (one per server) and therefore run into troubles. I could not find a way so far to run the apps in parallel on the same server with different configurations.
I might have missunderstood the new way of configuring an application, therefore any help would be appreciated.
in a typical new .NET Core web app, you will see this code in the Startup.cs:
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{environment.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables()
.Build();
all you need to do is add another appsettings file with client-specific settings, like:
.AddJsonFile($"appsettings.client.json", optional: true)
then have your build script copy in the correct build configuration to appsettings.client.json. the ConfigurationBuilder will pick up the settings in all the sources and compile them into the configuration object.
also check out the full docs:
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration

Application Insights and Asp.Net core Configuration

I keep reading about the importance of configuring ApplicationInsights to reduce unwanted traffic and other things.
How do I do that in an Asp.Net Core application? There doesn't seem to be an applicationinsights.config XML file anymore.
I can see a ConnectService.json file in the Application Insights folder, but there isn't much in it?
How do I configure AI for an Asp.Net Core application?
Anyone have links to docs? I can't seem to find any...
TIA
All of this is now in code, and mostly documented on the application insights asp.net core github wiki.
for example, see https://github.com/Microsoft/ApplicationInsights-aspnetcore/wiki/Dependency-Tracking-and-Performance-Counter-Collection where it has
Disabling Telemetry Module Services
In order to disable the services,
you need to manually remove the modules from the existing list of
services in the method ConfigureServices. Please note that telemetry
modules should be removed only after adding Application Insights to
the services.
// Removing dependency tracking telemetry module - to disable default dependency tracking
var dependencyTrackingService = services.FirstOrDefault<ServiceDescriptor>(t => t.ImplementationType == typeof(DependencyTrackingTelemetryModule));
if (dependencyTrackingService!= null)
{
services.Remove(dependencyTrackingService);
}
// Removing performance collector module - to disable default performance counter collection
var performanceCounterService = services.FirstOrDefault<ServiceDescriptor>(t => t.ImplementationType> == typeof(PerformanceCollectorModule));
if (performanceCounterService != null)
{
services.Remove(performanceCounterService);
}

Resources