Cannot turn off sampling of application insights - azure

I have a DotNet 6 application ASP.NET Web API application that is running as an App Service in Azure.
I do not have fixed sampling enabled. I also do not have applicationinsights.json file in my application.
I have code to disable Adaptive Sampling in the ConfigureServices method. The code snippet is below:
if (!string.IsNullOrEmpty(configuration["ApplicationInsights:InstrumentationKey"]))
{
services.AddApplicationInsightsTelemetry(options =>
{
if (webHostEnvironment.IsDevelopment())
{
options.DeveloperMode = true;
options.EnableDebugLogger = false;
}
options.EnableAdaptiveSampling = false;
options.InstrumentationKey = configuration["ApplicationInsights:InstrumentationKey"];
});
services.AddApplicationInsightsTelemetryProcessor<FilterProcessor>();
services.AddSingleton<ITelemetryInitializer, NopContextInitializer>();
}
My Azure settings for application insights is as follows for ingestion sampling
I continue to see sampling happening when I run the below query:
union requests,dependencies,pageViews,browserTimings,exceptions,traces
| where timestamp > ago(1d)
| summarize RetainedPercentage = 100/avg(itemCount) by bin(timestamp, 1h), itemType
My application was a .NET Core 3.1 a few weeks back and could not get sampling to be turned off. Even after upgrading to DotNet 6, I am not able to turn off sampling.
Any pointers on why this may be happening ?

I also do not have applicationinsights.json file in my application.
When we add Application Insights Telemetry from Visual Studio => Project Root Folder, by default ApplicationInsights.config used to be generated automatically.
I have Added Application Insights Telemetry from Project Root Folder, even I didn't find ApplicationInsights.config added in the application.
There might be some latest changes in Adding the ApplicationInsights Telemetry.
We can disable sampling from either ApplicationInsights.config or from code.
As we don't have ApplicationInsights.config file, will try to disable the sampling from Code.
As mentioned in the MSDoc,
Only ASP.NET server-side telemetry currently supports adaptive sampling.
In Program.cs, add the below lines of code
var aiOptions = new Microsoft.ApplicationInsights.AspNetCore.Extensions.ApplicationInsightsServiceOptions();
aiOptions.EnableAdaptiveSampling = false;
builder.Services.AddApplicationInsightsTelemetry(aiOptions);
This code works only for the Production Environment(Deployed Application).
For .NET Core 6
My Program.cs
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel;
using Microsoft.ApplicationInsights.Extensibility;
var builder = WebApplication.CreateBuilder(args);
var aiOptions = new Microsoft.ApplicationInsights.AspNetCore.Extensions.ApplicationInsightsServiceOptions();
aiOptions.EnableAdaptiveSampling = false;
builder.Services.AddApplicationInsightsTelemetry(aiOptions);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
My appsettings.json file
{
"Logging": {
"ApplicationInsights": {
"LogLevel": {
"Default": "Debug",
"Microsoft": "Error"
}
},
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ApplicationInsights": {
"ConnectionString": "InstrumentationKey=********;IngestionEndpoint=https://****.in.applicationinsights.azure.com/;LiveEndpoint=https://****.livediagnostics.monitor.azure.com/",
"EnableAdaptiveSampling": false,
"EnablePerformanceCounterCollectionModule": false
}
}
Re-deploy the App, Access the URL and check the traces/Logs.
References taken from MSDoc

Related

Azure AD and Redirect Uri with infinite login loop

Good morning,
I created a Blazor Server Side application in .NET5 with the standard VS2019 template and I want to authenticate via Azure OpenId.
The app must be deployed under IIS in HTTP mode and a reverse proxy will give users an HTTPS url: the final url given by the reverse proxy is https://myapp-test.domain.it.
My problem is that both when I debug the application in VS both when I publish it under IIS the application reload in loops the authentication page and the the login fails.
My Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
services.AddControllersWithViews()
.AddMicrosoftIdentityUI();
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost;
});
string redirectUri = Configuration.GetSection("AzureAd:RedirectUri").Value;
string clientSecret = Configuration.GetSection("AzureAd:ClientSecret").Value;
if (!string.IsNullOrWhiteSpace(redirectUri))
{
services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.SaveTokens = true;
var redirectToIdpHandler = options.Events.OnRedirectToIdentityProvider;
options.Events.OnRedirectToIdentityProvider = async context =>
{
await redirectToIdpHandler(context);
context.ProtocolMessage.RedirectUri = redirectUri;
};
});
}
//...
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseForwardedHeaders();
//...
}
My appsettings.json:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "XXXXXXX",
"TenantId": "XXXXXXX",
"ClientId": "XXXXXXX",
"ClientSecret": "XXXXXXX",
"RedirectUri": "https://myapp-test.domain.it",
"CallbackPath": "/signin-oidc"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
In the redirect URIs on Azure I setted:
https://myapp-test.domain.it/
https://myapp-test.domain.it/signin-oidc
I run the application (or I hosted it under IIS) with the following url: http://localhost:39146; but as I said calling the app with http://localhost:39146 or with https://myapp-test.domain.it produces and "infinite" login loop that fails at the end.
Initially you can try with latest versions of Microsoft packages ,
which may fix the issue.
This problem may occur if website uses http protocol.Please check if the reverse proxy listen HTTPS request but forward the request to the app as HTTP.See forward-the-scheme-for-linux-and-non-iis-reverse-proxies.Note that the cookie is only sent for secure https request.
One way is to force https navigation to the site.
You can customize the Cookies Authentication middleware to allow the authentication AspNet cookie for both http and https scheme by setting the CookieSecure attribute to CookieSecureOption.Never as followed in the Startup.Auth.cs file but not recommended in certain cases.
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
CookieSecure = CookieSecureOption.Never
});
So some cases of owin middleware please try to update app’s Microsoft.Owin.Host.SystemWeb package be at least version 3.1.0.0
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies",
CookieManager = new Microsoft.Owin.Host.SystemWeb.SystemWebChunkingCookieManager()
});
Also you can check this way OWIN and Azure AD HTTPS to HTTP Redirect Loop - Stack Overflow
References:
infinite redirect loop between Azure AD and MVC Asp.net app (aaddevsup.xyz)

Unable to read Azure SignalR Connection String from Azure App Service Configuration Application Settings

I am working on an Azure SignalR application and everything is working fine on my local machine when I set the following section in my appsettings.json:
"Azure": {
"SignalR": {
"ConnectionString": "XXXXX"
}
}
And then initialize in my startup.cs as follows:
services.AddSignalR().AddAzureSignalR();
However when I create the same environment variable in my Azure App Service using App Service>Configration>ApplicationSettings:
My application is unable to start and I get the following application error:
System.ArgumentException: Connection string missing required properties endpoint and accesskey. (Parameter 'connectionString')
at Microsoft.Azure.SignalR.ConnectionStringParser.Parse(String connectionString)
at Microsoft.Azure.SignalR.ServiceEndpoint..ctor(String connectionString, EndpointType type, String name)
When I hardcore my connection string onto the AddAzureSignalR() connectionstring parameter and deploy everything works fine.
It would seem that azuresignalR is unable to pickup this environment variable, despite also being able to see it via the Kudo Appsettings page as Azure:SginalR:ConnectionString.
You need to initiate like this,
string azureSignalrConnectionString = configuration["Azure:SignalR:ConnectionString"];
services.AddSignalR().AddNewtonsoftJsonProtocol().AddAzureSignalR(options =>
{
options.ConnectionString = azureSignalrConnectionString;
});
So I asked this same question on the Azure SignalR github page and below was the answer I got:
EnvironmentVariablesConfigurationProvider automatically replaces __
with : . So when you configures connection string via environment
variables, you should use Azure__SignalR__ConnectionString as the key.
When you configures it via JSON file, you should use the origin key
Azure:SignalR:ConnectionString.
Once I changed it to the double underscores all worked
For net core 5, use:
string azureSignalrConnectionString = Configuration["Azure:SignalR:ConnectionString"];
services.AddSignalR()
.AddAzureSignalR(options =>
{
options.ConnectionString = azureSignalrConnectionString;
});
appsettings.json, like:
{
"Azure": {
"SignalR": {
"ConnectionString": "<your-connection-string>"
}
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}

Load an SSL certificate from appsettings.json

I built a .NET core 2.2 application, that I am loading onto a raspberry pi. I am hosting the web service using Kestrel. On the pi, I have created a self-assigned certificate.pfx. If I hard code into the application a .UseHttps with the certificate name and password, the browser can find it.
However, if I comment it out of the code and use the appsettings.json file instead (I would like it in the appsettings.json, so clients can upload their own certificates), the redirect to Https will work, but the certificate is not loading and the page fails to connect.
This is the document I have been using to configure my appsettings.json file:
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-2.2
The certificate is located in the application folder.
Currently I have this code commented out of the application, but it does work when the code is not commented. I am hoping to set up these same settings through the appsettings.json file instead.
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureKestrel((context, options) =>
{
/*options.Listen(IPAddress.Any, 80);*/ // http:*:80
//options.Listen(IPAddress.Any, 5001, listenOptions =>
//{
// listenOptions.UseHttps("certificate.pfx", "password");
//});
});
here is the appsettings.json file:
{
"https_port": 5001,
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*",
"AllowInvalid": true,
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://*:80"
}
},
"Https": {
"Url": "https://*:5001",
"Certificate": {
"Path": "certificate.pfx",
"Password": "password"
}
}
}
}
This article ended up having the solution I needed:
https://www.humankode.com/asp-net-core/develop-locally-with-https-self-signed-certificates-and-asp-net-core
To be more precise its the part of the article titled "Configuring HTTPS in ASP.NET Core 2.0"
Instead of using appsettings.json, I created a new json file called certificate.json.
I then pull in the certificate name and password from the certificate.json into the program.cs code.

How to set environment variables or inputs in timerTrigger Azure Functions?

I am trying to setup a timerTrigger azure function
My function.json:
{
"disabled": false,
"bindings": [
{
"type": "timerTrigger",
"direction": "in",
"name": "sampleCronTrigger",
"schedule": "*/5 * * * * *",
}
],
"entryPoint": "sampleCron",
"scriptFile": "index.js"
}
In this I need to set an environment variable, but I am not able to do so. I tried looking for some documentation but couldn't find anything which doesn't require some setup on the Azure console?
I can I define environment variables? Or If here is any way I can pass an input to the function, that works too.
App settings in a function app contain global configuration options that affect all functions for that function app. When you run locally, these settings are accessed as local environment variables.
Local settings file
The file local.settings.json stores app settings, connection strings, and settings for Azure Functions Core Tools. Settings in the local.settings.json file are only used by Functions tools when running locally. By default, these settings are not migrated automatically when the project is published to Azure. Use the --publish-local-settings switch when you publish to make sure these settings are added to the function app in Azure.
In Functions, app settings, such as service connection strings, are exposed as environment variables during execution. You can access these settings using process.env, as shown here in the GetEnvironmentVariable function:
module.exports = function (context, myTimer) {
var timeStamp = new Date().toISOString();
context.log('Node.js timer trigger function ran!', timeStamp);
context.log(GetEnvironmentVariable("AzureWebJobsStorage"));
context.log(GetEnvironmentVariable("WEBSITE_SITE_NAME"));
context.done();
};
function GetEnvironmentVariable(name)
{
return name + ": " + process.env[name];
}
There are several ways that you can add, update, and delete function app settings:
From Azure portal.
By using the Azure CLI.
When running locally, app settings are read from the local.settings.json project file.
References:
https://learn.microsoft.com/en-us/azure/azure-functions/functions-app-settings
https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-node#environment-variables
https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-node#environment-variables
Additionally for retrieving values from local.settings.json, another way is to create an IConfigurationRoot object using ExecutionContext executionContext.
ExecutionContext can be added to function definition:
[FunctionName("FunctionName")]
public static async Task Run(
[ServiceBusTrigger(...)]
SomeMessage msg,
ILogger log,
ExecutionContext executionContext)
{
}
After that, you can instantiate an IConfigurationRoot instance, which you instruct to optionally load local.appsettings.json.
var configurationRoot = new ConfigurationBuilder()
.SetBasePath(executionContext.FunctionAppDirectory)
.AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
With the configurationRoot object, you can retrieve configuration values:
var value = configurationRoot["SomeKey"];
Example local.settings.json:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "...",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"SomeKey": "Value",
},
"Host": {
"LocalHttpPort": "7071"
}
}

AspNetCore Httpsys configure useURLS from webapi Appsettings file

I am building a AspNetCore webapi application for internal corporate use and I need to enable Windows Authentication.
So I am creating a httpsys server to listen at a specific endpoint:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseHttpSys(options =>
{
options.Authentication.Schemes =
AuthenticationSchemes.NTLM | AuthenticationSchemes.Negotiate;
options.Authentication.AllowAnonymous = true;
options.UrlPrefixes.Add("http://localhost:16000");
}).UseUrls("http://localhost:16000");
so while this obviously works fine, I want to be able to configure it in the config file.
Earlier in the project I was using Kestrel, so I just added these settings to the application config:
"Kestrel": {
"EndPoints": {
"HttpsInlineCertStore": {
"Url": "https://*:16000",
"Certificate": {
"Subject": "localhost",
"Store": "My",
"Location": "LocalMachine",
"AllowInvalid": "true"
}
} ...
Now I understand perfectly that HttpSYS can be configured by the registry etc, so I am not interested in those kinds of responses.
My Specific question is: For a NetCoreApi web api application, is it possible to use the IConfiguration inside the (static) CreateWebHostBuilder method?
I am injecting the IConfiguration into the startup class, but it appears the limitation is in the framework preventing access to it in the CreateWebHostBuilder method. Have I missed something?
For a NetCoreApi web api application, is it possible to use the
IConfiguration inside the (static) CreateWebHostBuilder method?
Yes, you will be able to access it inside ConfigureServices, which is enough to make your configurations. The overloaded of UseHttpSys actually does the exact same thing.
So basically you just have to configure your HttpSysOptions.
For netcoreapp2.1 :
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseHttpSys()
.ConfigureServices((context, services) =>
{
// Option 1. Set options manually.
services.Configure<HttpSysOptions>(options =>
{
// Use context.Configuration to access your config.
var url = context.Configuration.GetSection("MySection")["Url"];
options.UrlPrefixes.Add(url);
});
// Option 2. Build options from settings.
services.Configure<HttpSysOptions>(context.Configuration.GetSection("WebSys"));
});
For netcoreapp3.1:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
webBuilder.ConfigureServices((context, services) =>
{
// Option 1. Set options manually.
services.Configure<HttpSysOptions>(options =>
{
// Use context.Configuration to access your config.
var url = context.Configuration.GetSection("MySection")["Url"];
options.UrlPrefixes.Add(url);
});
// Option 2. Build options from settings.
services.Configure<HttpSysOptions>(context.Configuration.GetSection("HttpSys"));
});
webBuilder.UseHttpSys(options =>
{
// Verify that your options is correct here.
});
});
In case you want to use option 2, your appsettings.json should look something like this:
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"HttpSys": {
"AllowSynchronousIO": false,
"RequestQueueLimit": 2,
"MaxAccepts": 3
},
"AllowedHosts": "*"
}
Note that the property UrlPrefixes in HttpSysOptions is a rather complex object, so I'm not sure if you will be able to serialize it correctly from appsettings. However, you can simply set the field as urls in your config, as mentioned here. Then HttpSys will pick it up as long as your Configuration is correct.
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"urls": "http://*:5005;",
"HttpSys": {
"AllowSynchronousIO": false,
"RequestQueueLimit": 2,
"MaxAccepts": 3
},
"AllowedHosts": "*"
}

Resources