How to use ReadFrom.AppSettings in Serilog - c#

I just discovered Serilog and I love it. However, I'm struggling to get it to read from app.config.
Code Configuration:
ILogger logger = new LoggerConfiguration()
.ReadFrom.AppSettings()
//.MinimumLevel.Verbose()
.Enrich.WithProcessId()
.Enrich.WithThreadId()
.Enrich.WithMachineName()
.Destructure.UsingAttributes()
//.WriteTo.MSSqlServer(#"Server=EVDVWADBV1;Database=AppLog;Trusted_Connection=True;", "Logs")
.CreateLogger();
Log.Logger = logger;
The commented out sections are the configuration values I want to read from a config file.
The config file contains:
<appSettings>
<add key="serilog:minimum-level" value="Verbose"/>
<add key="serilog:using" value="Serilog.Sinks.MSSqlServer"/>
<add key="serilog:write-to:MSSqlServer.connectionString" value="Server=EVDVWADBV1;Database=AppLog;Trusted_Connection=True;"/>
<add key="serilog:writeto:MSSqlServer.tableName" value="Logs"/>
<add key="serilog:write-to:RollingFile.pathFormat" value="C:\Logs\myapp-{Date}.txt" />
<add key="serilog:write-to:RollingFile.retainedFileCountLimit" value="10" />
</appSettings>
I'm using the following Serilog packages.
<package id="Serilog" version="1.5.14" targetFramework="net452" />
<package id="Serilog.Sinks.MSSqlServer" version="3.0.41" targetFramework="net452" />
I also added this as the first line of my console app. I'm not seeing any errors on the console.
Serilog.Debugging.SelfLog.Out = Console.Out;
What am I missing?

It looks like you may have a typo in the configuration:
serilog:writeto:MSSqlServer.tableName
Missing the dash:
serilog:write-to:MSSqlServer.tableName

Related

How to configure App.config to remove Serilog.Sinks.MSSqlServer standard columns?

I use Serilog for logging. I need to configure App.config as to remove 2 standard columns from Logs table (StandardColumn.Properties and StandardColumn.MessageTemplate). I've searched for it in Serilog docs and other resources but can't find how to do it. This is what I got so far:
<configuration>
<appSettings>
<add key="serilog:using:MSSqlServer" value="Serilog.Sinks.MSSqlServer" />
<add key="serilog:write-to:MSSqlServer.connectionString" value="Data Source=SomeServer;initial catalog=DB; integrated security=True" />
<add key="serilog:write-to:MSSqlServer.tableName" value="Logs" />
<add key="serilog:minimum-level" value="Debug" />
</appSettings>
</configuration>
I guess I would have to add this line:
<add key="serilog:write-to:MSSqlServer.columnOptions" value="someColOptions" />
but how should I define someColOptions? For example, I removed columns using this kind of code:
var colOptions = new Serilog.Sinks.MSSqlServer.ColumnOptions();
colOptions.Store.Remove(StandardColumn.Properties);
colOptions.Store.Remove(StandardColumn.MessageTemplate);
Log.Logger = new LoggerConfiguration()
.WriteTo
.MSSqlServer(
connectionString: conn_string,
sinkOptions: new MSSqlServerSinkOptions { TableName = "Logs" },
columnOptions: colOptions)
.MinimumLevel.Debug()
.CreateLogger();
and now I want to do the same in App.config
I had a similar question, I've been able to find out that by adding the following, the configSections has to be first section after
that this will:
create a Logs table in the specified Database (from the connection string)
Use the Serilog database account (from the connection string)
Remove the column called Properties from the Logs table
Add a new column called RunId that declared as an int
<configuration>
<configSections>
<section name="MSSqlServerSettingsSection" type="Serilog.Configuration.MSSqlServerConfigurationSection, Serilog.Sinks.MSSqlServer"/>
</configSections>
<MSSqlServerSettingsSection DisableTriggers="false" ClusteredColumnstoreIndex="false" PrimaryKeyColumnName="Id">
<!-- SinkOptions parameters -->
<TableName Value="Logs"/>
<BatchPeriod Value="00:00:15"/>
<RemoveStandardColumns>
<remove Name="Properties"/>
</RemoveStandardColumns>
<Columns>
<add ColumnName="RunId" DataType="int"/>
</Columns>
</MSSqlServerSettingsSection>
<appSettings>
<!-- Serilog Settings -->
<add key="serilog:minimum-level" value="Verbose" />
<add key="serilog:using:Console" value="Serilog.Sinks.Console"/>
<add key="serilog:write-to:Console"/>
<add key="serilog:using:File" value="Serilog.Sinks.File" />
<add key="serilog:write-to:File"/>
<add key="serilog:write-to:File.path" value="{PATH}" />
<add key="serilog:write-to:File.rollingInterval" value="Day"/>
<add key="serilog:using:MSSqlServer" value="Serilog.Sinks.MSSqlServer" />
<add key="serilog:write-to:MSSqlServer.connectionString" value="Server=[SERVER];Database=[DATABASE];User Id=Serilog;Password=[PASSWORD];"/>
<add key="serilog:write-to:MSSqlServer.tableName" value="Logs"/>
<add key="serilog:write-to:MSSqlServer.autoCreateSqlTable" value="true"/>
</appSettings>
</configuration>
Calling Log.("{RunId}{Message}", _runId, _messageToShow) causes my File, Console AND MSSqlServer sinks to execute writing to these, if it doesn't exist the Logs table will be created, removing the Properties column and adding the RunId column. (If the table exists it doesn't do anything but write the data, still trying to work out how to handle that).
I'm still playing around with this (my next thing is to work out how to write {RunId} but not have it appear in the log, only written to the corresponding database field).
HTH,
Phil

Serilog ReadFrom.Configuration is not working in .net framework web Api with configuration stored in web.config

I am using serilog in a web api in .net framework with the serilog config added in the Web.Config file as below
<appSettings>
<add key="serilog:minimum-level" value="Information" />
<add key="serilog:using:File" value="Serilog.Sinks.File" />
<add key="serilog:write-to:File.path" value="C:\api\logs\api_log.log" />
<add key="serilog:write-to:File.formatter" value="Serilog.Formatting.Json.JsonFormatter, Serilog" />
<add key="serilog:write-to:File.rollingInterval" value="Day" />
<add key="serilog:write-to:File.fileSizeLimitBytes" value="5242880" />
<add key="serilog:write-to:File.rollOnFileSizeLimit" value="true" />
<add key="serilog:write-to:File.shared" value="true" />
</appSettings>
I have registered the logger in the startup file as below
private static ILogger ConfigureSerilog()
{
IConfigurationRoot configuration = new ConfigurationBuilder()
.Add(new XmlConfigurationProvider())
.Build();
LoggerConfiguration loggerConfiguration = new LoggerConfiguration().Enrich.With(new SerilogClaimValueEnricher())
.Enrich.WithDemystifiedStackTraces()
.ReadFrom.Configuration(configuration);
Logger rootLogger = loggerConfiguration.CreateLogger();
Log.Logger = rootLogger;
return rootLogger;
}
The configuration object is getting all the values that we are given in the web.config but the logging is not working. But instead of ReadFrom.Configuration(configuration) if I use ReadFrom.AppSettings() the logging is working corectly. But I need make use of IConfigurationRoot here. Did I missed anything?
Please not XmlConfigurationProvider is a custom class to read keys from web.config
Below is the screenshot of debug mode states of the configuration.

Config reads value from another config

I am trying to setup configs so it is easy to switch from dev to production with out constantly having to copy config settings from one place to another.
What I am trying to do is to setup a singe config that contains usernames, passwords and other access strings that I want to omit from source control for obvious reasons.
I could then reference those keys in other configs.
An example of what I am thinking
Content of a config that stores keys:
<keys>
<add key="username" value="1forest1" />
<add key="password" value="life-is-like-a-box-of-chocolates" />
<add key="url" value="http://www.example.com" />
</keys>
Content of a config that requires keys:
<service name="SomeService">
<settings>
<setting key="Container" value="MyContainer" />
<setting key="MaxBytes" value="12582912" />
<setting key="Timeout" value="30000" />
<setting key="Host" value=[url value from keys config] />
<setting key="username" value=[username value from keys config] />
<setting key="password" value=[password value from keys config] />
</settings>
</service>
I am not to optimistic that this is possible due to reasons, but any patterns that might point towards a solution/workaround for this would greatly appreciated.
Check out the Microsoft.Extensions.Configuration tools. Adding json files.
IConfiguration configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("Secrets/values.json")
.Build();
Inject the Configuration then get the values:
var section = configuration.GetSection("Settings");
string connectionString = section["ConnectionString"]
json example:
{
"Settings": {
"ConnectionString": "Server=tcp.....",
"SomeOtherValue": "SomeValue"
},
"MoreStuff": {
"foo": "bar"
}
}
Have an appsettings file:
Web.config:
<appSettings file="AppSettingsSecrets.config">
<add key="Container" value="MyContainer" />
<add key="MaxBytes" value="12582912" />
<add key="Timeout" value="30000" />
<add key="Host" value="" />
<add key="username" value="" />
<add key="password" value="" />
</appSettings>
AppSettingsSecrets.config :
<?xml version="1.0"?>
<appSettings>
<add key="Host" value="SecretHost" />
<add key="username" value="MyUname" />
<add key="password" value="S3cr3t" />
</appSettings>
Give the location/name of the second config file as one setting in first config file, and read it dynamically.

Serilog - path to log file

i am trying to start working with serilog. The normal RollingFile doesn't fit my needs (i need the counting like logs\20160701-00002.txt), so i want to use the RollingFileAlternate as a sink.
When using RollingFile i added
loggerInstance = new LoggerConfiguration()
.ReadFrom.AppSettings()
and was able to get the path from the App.config file with using:
<add key="serilog:minimum-level" value="Debug" />
<add key="serilog:using:RollingFile" value="Serilog.Sinks.RollingFile" />
<add key="serilog:write-to:RollingFile.pathFormat" value="..\Log\MyLOG.LOG" />
Now i switched to RollingFileAlternate :
<add key="serilog:minimum-level" value="Debug" />
<add key="serilog:using:RollingFileAlternate" value="Serilog.Sinks.RollingFileAlternate" />
<add key="serilog:write-to:RollingFileAlternate.logsDirectory" value="..\Log\test.log" />
<add key="serilog:write-to:RollingFileALternate.logsFolder" value="..\Log" />
I tried using logsDirectory and logsFolder since both are described in the examples of https://github.com/BedeGaming/sinks-rollingfile
but my program won't create a file.
if I add to the Loggerconfiguration:
loggerInstance = new LoggerConfiguration()
.ReadFrom.AppSettings()
.WriteTo.RollingFileAlternate("..\\log")
the foldername will be used and the logfiles are put in this folder.
Can some one help me and tell me what i am missing?
There may be a problem with the documentation; the argument is called logDirectory, not logsDirectory. So, you need:
<add key="serilog:write-to:RollingFileAlternate.logDirectory" value="..\Log" />

Define multiple sinks with different outputTemplates based on logging level in xml config for Serilog

Is there any way to define multiple sinks in the XML config for serilog that will allow the outputTemplate to change based on the level of log?
I currently have:
<add key="serilog:minimum-level" value="Verbose" />
<add key="serilog:write-to:ColoredConsole" />
<add key="serilog:write-to:RollingFile.pathFormat" value="C:\Logs\AdapterService-{Date}.txt" />
<add key="serilog:write-to:RollingFile.retainedFileCountLimit" value="10" />
<add key="serilog:write-to:RollingFile.outputTemplate" value="[{Timestamp:G}] [{Level}] [{SourceContext:l}] {Message}{NewLine:l}{Exception:l}" />
However would like the Debug level logs to not include the SourceContext string as in:
<add key="serilog:write-to:RollingFile.outputTemplate" value="[{Timestamp:G}] [{Level}] {Message}{NewLine:l}{Exception:l}" />
I am aware you can set the restrictedToMinimumLevel: LogEventLevel.Verbose but I am unsure how to do this in the XML.

Categories

Resources