Adding Configuration to Application Insights - c#

So I recently installed Application Insights to my project through Visual Studio and it says that it is 100% configured, but there is no added code in my Startup.cs. Do I need to add anything to get it fully functional or is that it?

There are 2 ways to add application insights to an ASP.NET Core site.
In the Program.cs file:
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.UseApplicationInsights() // Here
.Build();
host.Run();
}
Or in the ConfigureServices method:
public void ConfigureServices(IServiceCollection services)
{
services.AddApplicationInsightsTelemetry(Configuration); // here
var builder = services.AddMvc();
}
You need to add the instrumentation key in the appsettings.json file:
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Information"
}
},
"ApplicationInsights": {
"InstrumentationKey": "4bbb7b98-78f8-49c3-8ede-da3215b75f43"
}
}

Related

Serilog not writing to file

Setting up Serilog for my .net core app, everything compiles and runs but not writing to the file. How can I pinpoint the problem?
I am only use Serilog package - but there seems to be a multitude of others, and I'd be happy to use another one.
In my startup.cs I have
using Serilog;
public Startup(IConfiguration configuration)
{
Configuration = configuration;
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.ReadFrom.Configuration(configuration)
.CreateLogger();
}
in my appsettings.json I have
{
"AllowedHosts": "*",
"Serilog": {
"MinimumLevel": "Debug",
"Override": {
"Microsoft.AspNetCore": "Warning"
},
"WriteTo": [
{
"Name": "Console"
},
{
"Name": "File",
"Args": {
"path": "C:\\log\\Batching\\apptest.log"
}
}
]
}
}
in my Program.cs I have
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSerilog()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
And finally I use this statement to test the writing:
Log.Information("write something to file");
It is not working. What can I try next?
Just as mentioned in the document:
To use the file sink with Microsoft.Extensions.Configuration, for example with ASP.NET Core or .NET Core, use the Serilog.Settings.Configuration package
And you could find introduction to different packages in this page:
https://github.com/serilog
I tried with the packages:
Set as below in program.cs:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.UseSerilog((context, configuration) =>
{
var config = context.Configuration;
configuration.ReadFrom.Configuration(config);
});
It works well in my case:
Update:
I configured as below in appsettings.json:
I also tried with the absolute path of my desktop, it worked either

Unable to show debug messages ILogger.LogDebug and how to enable for Serilog

Using ILogger interface I am unable to see any output from LogDebug even when I have set:
"Logging": {
"LogLevel": {
"Default": "Debug",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
And I use to register:
public static void Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
.Enrich.FromLogContext()
.WriteTo.Console()
.WriteTo.File("logging.log")
.CreateLogger();
var host = CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.Configure<HostOptions>(option =>
{
option.ShutdownTimeout = System.TimeSpan.FromSeconds(20);
});
services.AddLogging();
// services.AddLocalization(options => options.ResourcesPath = "Resources");
services.AddSimpleInjector(container, options =>
{
// Hooks hosted services into the Generic Host pipeline while resolving them through Simple Injector
options.AddHostedService<Worker>();
// Allows injection of ILogger & IStringLocalizer dependencies into application components
options.AddLogging();
// options.AddLocalization();
});
})
.Build()
.UseSimpleInjector(container);
config.Build();
host.Run();
}
public static IHostBuilder CreateDefaultBuilder(string[] args)
{
var builder = Host.CreateDefaultBuilder(args);
builder
.ConfigureLogging((hostingContext, logging) =>
{
logging.ClearProviders();
logging.AddConsole();
if (hostingContext.HostingEnvironment.IsDevelopment() == true)
logging.AddDebug();
})
.ConfigureHostConfiguration(configurationBuilder =>
{
configurationBuilder.AddCommandLine(args);
})
.ConfigureAppConfiguration((hostingContext, configApp) =>
{
var env = hostingContext.HostingEnvironment;
})
.UseConsoleLifetime();
return builder;
}
Any ideas what i am doing wrong please or missing?
I am now planning to use Serilog for all my logging and for legacy libs to use the ILogger interface, anything that i would need to change to enable (or remove any conflicting settings)?

Serilog : RollingFile is not working in asp.net core with 'appsettings.json'

I am using asp.net core(website) and Serilog for logging.
Nuget packages installed are
Serilog
Serilog.AspNetCore
Serilog.Extensions.Logging
Serilog.Extensions.Logging.File
Serilog.Settings.Configuration
Serilog.Sinks.File
Serilog.Sinks.RollingFile
Microsoft.Extensions.Logging
Settings in Main.cs file are :
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((WebHostBuilderContext, configurationBuilder) =>
{
configurationBuilder.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
configurationBuilder.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true);
configurationBuilder.AddEnvironmentVariables();
})
.ConfigureLogging((hostingContext, loggingBuilder) =>
{
loggingBuilder.ClearProviders();
loggingBuilder.AddSerilog();
})
.UseStartup<Startup>();
}
What is working :
In Startup.cs file if I write following code the logging file is getting created. Here I am specifying the configurations in code itself.
public void Configure(IApplicationBuilder app,
IHostingEnvironment env,
ILoggerFactory loggerFactory)
{
string logFilePath = Path.Combine(env.ContentRootPath, "Logs/ImportManager2-{Date}.txt");
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.RollingFile(logFilePath)
.CreateLogger();
loggerFactory.AddSerilog();
--
--
}
When I am using appsettings.json file with following content
{
"Logging": {
"LogLevel": {
"Default": "Information"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"MyDatabaseLocal": "Server=_;Database=_;MultipleActiveResultSets=true;Connection Timeout=333;Integrated Security=SSPI",
"OtherDatabaseLocal": "Server=_;Database=_;MultipleActiveResultSets=true;Connection Timeout=333;Integrated Security=SSPI"
},
"Serilog": {
"MinimumLevel": "Debug",
"Override": {
"Microsoft": "Warning"
},
"Using": [
"Serilog.Sinks.Console",
"Serilog.Sinks.File"
],
"WriteTo": [
{
"Name": "RollingFile",
"Args": {
"path": "Logs/MyProject.txt"
}
}
]
}
}
and changed the startup.cs file like
public void Configure(IApplicationBuilder app,
IHostingEnvironment env,
ILoggerFactory loggerFactory)
{
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(Configuration.GetSection("Serilog"))
.CreateLogger();
loggerFactory.AddSerilog();
--
--
}
After this there is not file created. What could be the problem.
The following call is not quite working how you're expecting:
.ReadFrom.Configuration(Configuration.GetSection("Serilog"))
When using this extension method, Serilog expects that there will be a section named Serilog within the configuration that you pass through. In your example, you're passing the Serilog section itself, but then it's looking for another Serilog section within that.
Update the call to just pass through Configuration, like this:
.ReadFrom.Configuration(Configuration)
Serilog will find your Serilog section and consume the settings from that.

Reload Serilog JSON Configuration on changes in .NET Core 2.1

I'm currently working on a ASP.NET Core 2.1 application and I use Serilog for logging. I want to reload the application settings file for my Serilog implementation during runtime.
My goal is to change the log level at runtime e.g. I write into minimumLevel Debug instead of Information and I save the file. I want to trigger a live reload of the settings. My appsettings.json looks like this:
{
"serilog": {
"using": [ "Serilog.Sinks.File", "Serilog.Sinks.Console" ],
"minimumLevel": "Information",
"writeTo": [
{
"name": "File",
"args": {
"fileSizeLimitBytes": 256000000,
"retainedFileCountLimit": 62,
"rollingInterval": "Day",
"rollOnFileSizeLimit": true,
},
{
"name": "Console",
}
]
}
}
In my Program.cs I load the settings with the flag reloadOnChange: true.
public class Program
{
public static readonly ServiceSettings Settings = new ServiceSettings();
public static void Main(string[] args)
{
//...
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile(Path.GetFullPath(CoreServiceBase.Instance.ConfigFilePath), optional: false, reloadOnChange: true)
.AddCommandLine(args)
.Build();
config.Bind(Settings);
return WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseSerilog((hostingContext, loggerConfiguration) =>
loggerConfiguration.ReadFrom.Configuration(hostingContext.Configuration))
.UseConfiguration(config);
}
}
My Startup looks like this:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
// ...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
// Custom application logging
ApplicationLogging.LoggerFactory = loggerFactory;
// ...
}
}
Do you know how to reload the Serilog configuration during runtime, if I somehow the appsettings.json gets changed. => Live reload for the appsettings.json.
Thank you!!
You can use Serilog.Settings.Reloader
I don't have ASP example, but on console program you can do this:
// Service collection
IServiceCollection serviceCollection = new ServiceCollection()
.AddLogging(loggingBuilder =>
loggingBuilder
.AddSerilog(SwitchableLogger.Instance, true)
.AddSerilogConfigurationLoader(configuration, SwitchableLogger.Instance)
);
// Services
using (var services = serviceCollection.BuildServiceProvider())
{
// Create logger
Microsoft.Extensions.Logging.ILogger logger = services.GetService<Microsoft.Extensions.Logging.ILogger<Program>>();
// Write
logger.LogInformation("Hello World");
// Modify config
config.Set("Serilog:WriteTo:0:Args:OutputTemplate", "[{SourceContext}] {Message:lj}{NewLine}{Exception}");
configuration.Reload();
// Write with the previous logger instance, but with different settings
logger.LogInformation("Hello world again");
}
For clarification, the singleton "SwitchableLogger.Instance" is only for demonstration, a new instance "new SwitchableLogger()" can also be created.
You can change the loglevel using LoggingLevelSwitch. You can read about it here
You can use the IOptionsSnapshot<> interface to reload the configuration. You can read more about that here
The current Serilog implementation (2.9.0) is such that it is unable to fully reload settings. To work around this issue without introducing additional dependencies, avoid creating static loggers and follow the example provided here: https://github.com/akovac35/Logging/blob/v1.0.4/src/com.github.akovac35.Logging.Serilog/SerilogHelper.cs
public static void CreateLogger()
{
CreateLogger(configure =>
{
configure.AddJsonFile("serilog.json", optional: false, reloadOnChange: true);
});
}
public static void CreateLogger(Action<IConfigurationBuilder> configure)
{
if (configure == null) throw new ArgumentNullException(nameof(configure));
UpdateLogger(configure);
}
public static void UpdateLogger(Action<IConfigurationBuilder> configure)
{
if (configure == null) throw new ArgumentNullException(nameof(configure));
// The following pattern fires the reload token only once per settings change
var configurationBuilder = new ConfigurationBuilder();
try
{
configure(configurationBuilder);
IConfiguration configuration = configurationBuilder.Build();
// Release previous callback - will be released only if this line is reached, allowing for another reload
_changeCallback?.Dispose();
_changeCallback = null;
// .NET will not trigger a reload for invalid config file format, so reaching this line signals Json is OK
_changeCallback = configuration.GetReloadToken().RegisterChangeCallback(state =>
{
UpdateLogger(configure);
}, null);
// Reading configuration will fail for invalid properties, that is why reload registration must happen
// before this line or subsequent file updates may not be detected
global::Serilog.ILogger newLogger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.Enrich.FromLogContext()
.CreateLogger();
Log.Logger = newLogger;
GetLogger().Here(l => l.LogInformation("Updated logger: {#configuration}", configuration));
}
catch (Exception ex)
{
GetLogger().Here(l => l.LogError(ex, ex.Message));
}
}
Or you can simply use the Logging.Serilog library which provides utility functions for just that.

Configure Kestrel using hosting.json and appsettings.json in dotnet core v2

I need to setup a project in dotnet core on a Ubuntu 16.04 LTS server with a database connected to it. I followed this tutorial and I managed it to get it online on a certain domain name/ip.
Tutorial I used:
https://www.hanselman.com/blog/PublishingAnASPNETCoreWebsiteToACheapLinuxVMHost.aspx
At this point, my plain, clean mvc-project is running. However, I need to make a connection with a database. I have one running on a different server (I have the correct credentials). But I have a problem with the hosting .json file. It seems to conflict with the regular appsettings.json file.
hosting.json
{
"server.urls": "http://localhost:5123"
}
Program.cs v1 (works online but without db connection)
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("hosting.json", optional: true)
.Build();
var host = new WebHostBuilder()
.UseKestrel()
.UseConfiguration(config)
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.Build();
host.Run();
Program.cs v2 (works offline with db, not online)
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
appsettings.json
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Warning"
}
},
"ConnectionStrings": {
"correctdb": "Server=correctip;Database=correctdb;Uid=SA;Pwd=correctpass",
"providerName": "Sql.Data.SqlClient"
}
}
This is my error msg: error
My main issue, is that I have a feeling it's conflicting with the Kestrel-settings in dotnet core v2 using that hosting.json like the tutorial says.
Whenever I use Program.cs v2 is only runs offline with database connection. Whenever I use Program.cs v1 it runs online, but without the connection.
Is there another way to configure Kestrel without using the hosting.json?
Help is much appreciated.
edit 1
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("hosting.json", optional: true)
.AddJsonFile("appsettings.json", optional: true)
.Build();
edit 2
at Newtonsoft.Json.Linq.JObject.Load(JsonReader reader, JsonLoadSettings settings)
at Newtonsoft.Json.Linq.JObject.Load(JsonReader reader)
at Microsoft.Extensions.Configuration.Json.JsonConfigurationFileParser.Parse(Stream input)
at Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider.Load(Stream stream)
--- End of inner exception stack trace ---
at Microsoft.Extensions.Configuration.FileConfigurationProvider.Load(Boolean reload)
at Microsoft.Extensions.Configuration.FileConfigurationProvider.Load()
at Microsoft.Extensions.Configuration.ConfigurationRoot..ctor(IList`1 providers)
at Microsoft.Extensions.Configuration.ConfigurationBuilder.Build()
at webapp.Program.Main(String[] args) in /home/ubuntu/webapp/Program.cs:line 30
edit 3
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<WebappContext>(options => options.UseSqlServer(Configuration.GetConnectionString("correctdb")));
services.AddMvc();
}
edit 4
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args)
{
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true)
.AddCommandLine(args)
.Build();
return WebHost.CreateDefaultBuilder(args)
.UseConfiguration(config)
.UseStartup<Startup>()
.Build();
}
Are you sure you uploaded the appsettings.json?
Also, the v1 isn't loading the appsettings.json file, what the CreateDefaultBuilder does is load the standard things, so it will load appsettings.json when it exists.

Categories