I'm using Serilog to log to a SEQ server via a custom sink in my C# application. Many functionalities, including RPC server implementations, are derived from a company library, .Tools.
I'm encountering an issue where Serilog incorrectly identifies the SourceContext for log messages originating from an abstract base class.
The Problem:
I have an abstract class, ARpcServer, and an implementing class, RpcNcCreator. When Log.Information messages are emitted from within ARpcServer, Serilog's SourceContext property incorrectly shows the implementing class (RpcNcCreator) as the origin, instead of ARpcServer.
This is problematic because I want to suppress Information level logs specifically from ARpcServer (e.g., setting its minimum level to Warning), while still allowing Information logs from RpcNcCreator to be processed. If I try to suppress logs based on the RpcNcCreator namespace, I lose all Information level logs from that implementation, which is not desired.
Question:
Is there a way to configure Serilog, or modify the logging approach, so that it accurately captures the SourceContext based on the actual class where the Log.Information call is made (i.e., ARpcServer in the example above), rather than the concrete implementing class?
APP-Code:
namespace PPS.Kommunikation.Rpc
public class RpcNcCreator : ARpcServer<TriggerUebergabeProdDaten, TriggerErgebnisNCDaten>
{
/// <summary>
/// Liefert ein fertig konfiguriertes <see cref="RpcNcCreator"/>-Objekt.
/// </summary>
/// <param name="loggerSingleton">Log-Objekt.</param>
/// <param name="iOptions">Options-Objekt.</param>
public RpcNcCreator(ILogger<RpcNcCreator> loggerSingleton, IOptions<RpcNcCreatorOptions> iOptions)
: base(loggerSingleton)
{
Debug.Assert(iOptions != null);
Debug.Assert(iOptions.Value != null);
this.AnfrageExchange = iOptions.Value.AnfrageExchange;
}
//here are methodes that call eg.
private void DocumentStatus()
=> logger.LogInformation("...");
}
Library-Code:
namespace SpeedMaster.Tools.Kommunikation.RPC.Server;
public abstract class ARpcServer<TArbeit, TErgebnis> : ARpcServer<TErgebnis>, IDisposable
{
public ARpcServer(ILogger<ARpcServer<TArbeit, TErgebnis>> loggerSingleton)
{
_logger = loggerSingleton;
}
//Here in the BaseClass also are logs made eg.
private Task SendeStatusAnfrage(bool nurWennArbeitDaIst)
{
this._logger.LogInformation("Sende Status-Anfrage an alle Clients.");
}
AppSettings.json
//Sample from the
"Serilog": {
"Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.Seq", "SpeedMaster.Tools", "PPS" ],
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Error",
"Microsoft.AspNetCore": "Warning",
"System.Net.Http.HttpClient": "Warning",
"SpeedMaster.Tools.Kommunikation.RPC.Server.Internal.ClientStatusChecker": "Warning"
}
},
"WriteTo": [
{
"Name": "Seq",
"Args": {
"restrictedToMinimumLevel": "Information",
"serverUrl": "https://at02-logsammler.speed.intern:45341",
"apiKey": null
}
},
{
"Name": "Console",
"Args": {
"theme": "PPS.Models.SerilogThemes.SpeedMasterThemes::Speedy, PPS",
"outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss} {Level:u3}] ({SourceContext:l}) {Message:lj}{NewLine}{Exception}"
}
}
]
},
Update for Panagiotis Kanavos:
I extendet the code with the constructor, what a college explaint to me that the logger from RpcNcCreator is given to the Base.
The differenz from logger and _logger lies in that ARpcServer uses a Tradtional constructor with field assignment while the RpcNcCreator uses a primary constructor where its not recommendet to use a '_' as prefix for the variable name.

RpcNcCreator, the context isRpcNcCreator. If you want to use a different context use.ForContext<ARpcServer>(). This is shown in the docs as well. How are the loggers created? How areloggerand_loggerrelated?ARpcServer._loggeris initialized fromRpcNcCreator.loggerin the constructor, you could use_logger=logger.ForContext<ARpcServer>();logger.ForContext<ARpcServer>()i dont know how i should yous the only ForContext i found is Serilog.Log.ForContext what creates a Serilog instance but i work with ILogger<> instancesILoggeris a Serilog interface. Unless you mean the Microsoft.Extensions.Logging interface, in which case what you ask has little if anything to do with Serilog.