I'm using Serilog to log information on my app. I'm using an appsettings.json
file (see below) to setup the configuration settings of the logger. In that file, I have two configurations - one for writing to a file and another for writing to the console output. What I would like to be able to do is to only write to a file if my application is running in the IIS context. Otherwise, it should only output the log to the console. However, I'm a bit stuck on how to do this.
appsettings.json
{
"Serilog": {
"Using": [ "SeriLog.Sinks.Console", "Serilog.Sinks.File", "Serilog.Sinks.Async" ],
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Information",
"Microsoft.AspNetCore": "Warning",
"System": "Warning"
}
},
"WriteTo": [
{
"Name": "File",
"Args": {
"outputTemplate": "RC [{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}",
"path": "logs/mylog-.txt",
"rollingInterval": "Day"
}
},
{
"Name": "Console",
"Args": {
"outputTemplate": "RC [{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}"
}
}
],
"Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ],
"Properties": {
"Application": "MyApplication"
}
},
"AllowedHosts": "*"
}
Program.cs
public static IConfiguration Configuration { get; } = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
public static void Main(string[] args)
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
Config.Load();
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(Configuration)
.Filter.ByExcluding("RequestPath in ['/healthcheck', '/favicon.ico']")
.CreateLogger();
var host = Host.CreateDefaultBuilder(args)
.UseSerilog()
.ConfigureWebHostDefaults(webBuilder =>
{
var b = webBuilder.ConfigureKestrel((context, options) =>
{
// Handle requests up to 50 MB
options.Limits.MaxRequestBodySize = Config.MaxRequestSize;
})
.UseIISIntegration()
.UseStartup<Startup>()
.CaptureStartupErrors(true);
}).Build();
var logger = host.Services.GetRequiredService<ILogger<ReverseProxyModule>>();
ReverseProxyModule.InitializeConcurrentRequestLogging(logger);
host.Run();
}
I'm using Serilog to log information on my app. I'm using an appsettings.json
file (see below) to setup the configuration settings of the logger. In that file, I have two configurations - one for writing to a file and another for writing to the console output. What I would like to be able to do is to only write to a file if my application is running in the IIS context. Otherwise, it should only output the log to the console. However, I'm a bit stuck on how to do this.
appsettings.json
{
"Serilog": {
"Using": [ "SeriLog.Sinks.Console", "Serilog.Sinks.File", "Serilog.Sinks.Async" ],
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Information",
"Microsoft.AspNetCore": "Warning",
"System": "Warning"
}
},
"WriteTo": [
{
"Name": "File",
"Args": {
"outputTemplate": "RC [{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}",
"path": "logs/mylog-.txt",
"rollingInterval": "Day"
}
},
{
"Name": "Console",
"Args": {
"outputTemplate": "RC [{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}"
}
}
],
"Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ],
"Properties": {
"Application": "MyApplication"
}
},
"AllowedHosts": "*"
}
Program.cs
public static IConfiguration Configuration { get; } = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
public static void Main(string[] args)
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
Config.Load();
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(Configuration)
.Filter.ByExcluding("RequestPath in ['/healthcheck', '/favicon.ico']")
.CreateLogger();
var host = Host.CreateDefaultBuilder(args)
.UseSerilog()
.ConfigureWebHostDefaults(webBuilder =>
{
var b = webBuilder.ConfigureKestrel((context, options) =>
{
// Handle requests up to 50 MB
options.Limits.MaxRequestBodySize = Config.MaxRequestSize;
})
.UseIISIntegration()
.UseStartup<Startup>()
.CaptureStartupErrors(true);
}).Build();
var logger = host.Services.GetRequiredService<ILogger<ReverseProxyModule>>();
ReverseProxyModule.InitializeConcurrentRequestLogging(logger);
host.Run();
}
Share
Improve this question
asked Jan 31 at 15:57
andyopayneandyopayne
1,3683 gold badges24 silver badges53 bronze badges
2 Answers
Reset to default 0If you mean one sink for when it is live in production and one for when developing on your local computer, you could have an appsettings.production.json
and an appsettings.development.json
, and keep the appsettings.json
for configurations that should apply to both.
You could also try to use the is below code in the program.cs file to generate file logs for the iis environment only.
using Serilog;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
var builder = WebApplication.CreateBuilder(args);
// Load configuration
var configuration = builder.Configuration;
// Detect if running under IIS or Azure App Service
bool isRunningUnderIIS = Environment.GetEnvironmentVariable("ASPNETCORE_IIS_HTTPAUTH") != null
|| Environment.GetEnvironmentVariable("WEBSITE_INSTANCE_ID") != null; // Azure App Service support
// Debugging logs
Console.WriteLine($"Environment: {builder.Environment.EnvironmentName}");
Console.WriteLine($"ASPNETCORE_IIS_HTTPAUTH: {Environment.GetEnvironmentVariable("ASPNETCORE_IIS_HTTPAUTH")}");
Console.WriteLine($"WEBSITE_INSTANCE_ID: {Environment.GetEnvironmentVariable("WEBSITE_INSTANCE_ID")}");
Console.WriteLine($"Is running under IIS: {isRunningUnderIIS}");
// Configure Serilog dynamically and IGNORE `appsettings.json` for logging sinks
var loggerConfig = new LoggerConfiguration()
.Enrich.FromLogContext()
.Enrich.WithMachineName()
.Enrich.WithThreadId();
if (isRunningUnderIIS)
{
Console.WriteLine(" Running under IIS, enabling File logging...");
loggerConfig.WriteTo.File("logs/mylog-.txt", rollingInterval: RollingInterval.Day,
outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}");
}
else
{
Console.WriteLine(" Running Locally, enabling Console logging...");
loggerConfig.WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}");
}
// Apply Serilog
Log.Logger = loggerConfig.CreateLogger();
builder.Host.UseSerilog();
// Add services to the container
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline
if (app.Environment.IsDevelopment() || app.Environment.IsProduction())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseSerilogRequestLogging();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Result from visual studio:
Result after deploying on iis: