Appending arrays in from appsettings.{Environment}.json to appsettings.json - asp.net-core

This is very similar to this question except its about appending arrays between two different JSON files.
I have an ASP.NET Core application
I have the following in appsettings.Development.Json
"Serilog": {
"WriteTo": [
{
"Name": "ApplicationInsightsTraces",
"Args": { "instrumentationKey": "XXXXXXXX" }
}
]
}
And in appsettings.json:
"Serilog": {
// . . . Rest of Serilog configs
"WriteTo": [
{
"Name": "Console",
"Args": {
"theme": "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Code, Serilog.Sinks.Console",
"outputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}] {RequestId}-{SourceContext} {$Scope:lj}: {Message:lj}{NewLine}{Exception}"
},
"restrictedToMinimumLevel": "Information"
},
}
Because Keys overwrite other keys in Appsettings.json I end up with the Console sink being overridden. Is there a syntax to allow it to be appended?

The answer is to use WriteTo:1 and make it an object not an array in appsettings.Development.json like so:
"Serilog": {
"WriteTo:1":
{
"Name": "ApplicationInsightsTraces",
"Args": { "instrumentationKey": "d95066c9-0b17-4e0a-84d4-bb2a4f111016" }
}
}

Related

how can I solve error 'The handle is invalid' in serilog

I have an Asp.net core web api using .net core 6.
I use Serilog to store the app log in a text file.
sometimes I get this error:
Caught exception while emitting to sink Serilog.Sinks.SystemConsole.ConsoleSink: System.IO.IOException: The handle is invalid.
at System.ConsolePal.WindowsConsoleStream.Write(ReadOnlySpan`1 buffer)
at System.IO.StreamWriter.Flush(Boolean flushStream, Boolean flushEncoder)
at System.IO.StreamWriter.Write(String value)
at System.IO.TextWriter.SyncTextWriter.Write(String value)
at Serilog.Sinks.SystemConsole.ConsoleSink.Emit(LogEvent logEvent)
at Serilog.Core.Sinks.SafeAggregateSink.Emit(LogEvent logEvent)
could you please help me how can I solve this issue?
this is my appsetting:
"Serilog": {
"Using": [
"Serilog.Sinks.Console",
"Serilog.Sinks.File"
],
"MinimumLevel": "Information",
"WriteTo": [
{
"Name": "File",
"Args": {
"path": "AppLogs/bckLog-.log",
"rollingInterval": "Day",
"restrictedToMinimumLevel": "Warning"
}
},
{
"Name": "Console"
}
],
"Enrich": [
"FromLogContext"
]
}
and this is my program.cs
Serilog.Debugging.SelfLog.Enable(message => { Log.Logger?.Error(message); Console.WriteLine(message); });
Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(builder.Configuration).CreateLogger();
builder.Host.UseSerilog();

How to make Serilog pick up both the expression template and a console (color) theme from appsettings.json

I'm trying to configure Serilog for my ASP.NET app using appsettings.json and am following the instructions from the GitHub Serilog.Settings.Configuration project readme. I cannot get the Console output format expression working from appsettings.json when I also set a theme. When both are configured directly in code it works just fine.
This is the Serilog section of appsettings.json. Note the full template is more complex, it uses Substring(SourceContext, LastIndexOf(SourceContext, '.') + 1) amonst others, but this is how I am testing for now:
{
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft.AspNetCore": "Warning",
"Microsoft.EntityFrameworkCore.Database.Command": "Warning"
}
},
"WriteTo": [
{
"Name": "Console",
"Args": {
"formatter": {
"type": "Serilog.Templates.ExpressionTemplate, Serilog.Expressions",
"template": "[{#t:HH:mm:ss:fff} {#l:u3}] {SourceContext,48} : {#m}\n{#x}"
},
"theme": "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Code, Serilog.Sinks.Console"
}
}
],
"Enrich": [ "FromLogContext" ]
}
}
And this is the resulting output (with theme colors):
[17:13:38 INF] Configure
[17:13:38 INF] Now listening on: https://localhost:5001
[17:13:38 INF] Now listening on: http://localhost:5000
[17:13:38 INF] Application started. Press Ctrl+C to shut down.
Which appears to be the default format (note the msec field in the timestamp and the Source Context field are missing).
When I omit the theme setting from the json, the output looks like this, i.e. with the correct expression template applied (e.g. source context) but without any color:
[17:13:37:498 INF] App.Web.Server.Program : Server started
[17:13:37:797 INF] App.Web.Server.Startup : ConfigureServices
This is the same format I get when I configure the logger in code, but then I get the theme color too!
I also tried to use this format from the project's samples:
"WriteTo": [
{
"Name": "Console",
"Args": {
"outputTemplate": "[{Timestamp:HH:mm:ss} {SourceContext} [{Level}] {Message}{NewLine}{Exception}",
"theme": "Serilog.Sinks.SystemConsole.Themes.SystemConsoleTheme::Grayscale, Serilog.Sinks.Console"
}
}
]
This is without the format expression, just the format (and a slight variation on the format itself) and, as expected, results in:
[14:35:11 Microsoft.Hosting.Lifetime [Information] Now listening on: "https://localhost:5001"
[14:35:11 Microsoft.Hosting.Lifetime [Information] Now listening on: "http://localhost:5000"
I tried umpteen variations and combinations without any success. So it seems that using appsettings.json I can either get the expression template working, or the theme working, but not both at the same time.
Again: when configured directly in code it "just works" ...
Suggestion are welcome.
I tried as below:
Packages:
in appsettings.json:
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft.AspNetCore": "Warning",
"Microsoft.EntityFrameworkCore.Database.Command": "Warning"
}
},
"WriteTo": [
{
"Name": "Console",
"Args": {
"theme": "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Code, Serilog.Sinks.Console",
"outputTemplate": "Time:{Timestamp: HH:mm:ss.fff} Level:{Level} DetailedInfo:{Message}{NewLine}{Exception}"
}
}
],
"Enrich": ["FromLogContext"]
}
In program.cs:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.UseSerilog((context, logger) =>
{
logger.ReadFrom.Configuration(context.Configuration);
});
Result:
and with
"theme": "Serilog.Sinks.SystemConsole.Themes.SystemConsoleTheme::Grayscale, Serilog.Sinks.Console"

How to change/override FilePath when creating logger using Serilog

I want to change/override the filename declared appsettings.json with whatever I provide when I setup the logger while keeping all the other settings as is.
I have serilog settings declared in the appsettings.json
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Information",
"System": "Information"
}
},
"WriteTo": [
{ "Name": "Console" },
{
"Name": "File",
"Args": {
"path":"MyAppName_.log"
"rollOnFileSizeLimit": "true",
"fileSizeLimitBytes": 1000000,
"rollingInterval": "Day",
"flushToDiskInterval": 1,
"outputTemplate": "{Timestamp:o} [{Level:u3}] ({Application}/{MachineName}/{ThreadId}) {Message:lj}{NewLine}{Exception}"
}
}
],
"Enrich": [ "FromLogContext", "%COMPUTERNAME%", "WithThreadId", "USERNAME","USERDOMAIN" ],
"Properties": { "Application": "MyAppName" }
}
The below code is in ConfigureServices method in Startup.cs
var appName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
var fileName = #$"C://Logs/{MyAppName}\{MyAppName}-{DateTime.Today.ToString("MM-dd-yyyy")}.log";
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(Configuration)
.WriteTo.File(fileName)
.CreateLogger();
Is it possible?
I am using ASP.NET Core 3.1 and Serilog.AspNetCore 3.2.0

How to fix: AtlassianHostUser is null in Jira cloud plugin

How to fix: AtlassianHostUser is null in Jira cloud plugin.
My controller looks like this
#Controller
#IgnoreJwt
public class MainController {
private final StorageService storageService;
#Autowired
public MainController(StorageService storageService) {
this.storageService = storageService;
}
.
.
.
#RequestMapping(value = "/upload", method = RequestMethod.POST)
public String handleFileUpload(#AuthenticationPrincipal
AtlassianHostUser hostUser,
#RequestParam("file") MultipartFile file,
RedirectAttributes redirectAttributes) {
hostUser.getUserKey(); // Causing NPE because hostUser is null
}
My descriptor is shown below
{
"key": "copy-paste-plugin",
"baseUrl": "${addon.base-url}",
"name": "Copy Paste (Spring Boot)",
"authentication": {
"type": "jwt"
},
"lifecycle": {
"installed": "/installed",
"uninstalled": "/uninstalled"
},
"scopes": [
"READ",
"ACT_AS_USER"
],
"modules": {
"generalPages": [
{
"url": "/upload",
"key": "upload",
"location": "none",
"name": {
"value": "Attach a file"
},
"conditions": [
{
"condition": "user_is_logged_in"
}
]
}
]
}
}
This is Jira cloud plugin. I am not sure what part of it I am missing.
Looking for your help/pointer on this.
Thank you!

logging with Serilog Concurrently to AzureTableStorage

Logging to AzureTableStorage is causing an overhead that blocks next calls, compared to when logging into a file, is there a way to make this process faster (batch or async option)?
My code in appsetttings.josn:
"Serilog": {
"MinimumLevel": "Information",
"WriteTo": [
{
"Name": "AzureTableStorage",
"Args": {
"storageTableName": "tbl",
"connectionString": "DefaultEndpointsProtocol=http;AccountName=xxx;AccountKey=/xxxxxxxx"
}
}
]
}
I ended up using https://github.com/serilog/serilog-sinks-async and the batch option in AzureTableStorage, similar to:
"WriteTo": [
{
"Name": "Async",
"Args": {
"configure": [
{
"Name": "AzureTableStorage",
"Args": {
"storageTableName": "tbl",
"connectionString": "DefaultEndpointsProtocol=http;AccountName=xxx;AccountKey=xxx"
}
}
]
}
}
]