Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NLog.LogManager.Setup() - Introduced LoadConfiguration and friends for ISetupBuilder #3871

Merged
merged 1 commit into from
Apr 28, 2020

Conversation

snakefoot
Copy link
Contributor

@snakefoot snakefoot commented Mar 31, 2020

Very small dive into the idea of fluent-api for setup of NLog-LoggingConfiguration:

LogManager.Setup().LoadConfigurationFromFile();
LogManager.Setup().LoadConfigurationFromFile("NLog.config", optional: false);
LogManager.Setup().LoadConfigurationFromXml("<nlog></nlog>");
LogManager.Setup().LoadConfiguration(nlogConfig);
LogManager.Setup().LoadConfiguration(builder => 
  // Targets where to log to: File and Console
  var logfile = new NLog.Targets.FileTarget("logfile") { FileName = "file.txt" };
  var logconsole = new NLog.Targets.ConsoleTarget("logconsole");
            
  // Rules for mapping loggers to targets            
  builder.Configuration.AddRule(LogLevel.Info, LogLevel.Fatal, logconsole);
  builder.Configuration.AddRule(LogLevel.Debug, LogLevel.Fatal, logfile);
);

This will match the PRs here:

NLog/NLog.Extensions.Logging#418
NLog/NLog.Web#540

This allows one to setup a fallback configuration, if no NLog.config file was found:

LogManager.Setup().LoadConfigurationFromFile().LoadConfiguration(builder =>{
  var config = builder.LogFactory.Configuration;
  if (config != null)
        return;   // Config already assigned and loaded

  // Targets where to log to: File and Console
  var logconsole = new NLog.Targets.ConsoleTarget("logconsole");
            
  // Rules for mapping loggers to targets            
  builder.Configuration.AddRule(LogLevel.Info, LogLevel.Fatal, logconsole);
}));

Or one can so this (Resolves almost #1429, but without autoReload=true support)

LogManager.Setup().LoadConfigurationFromFile().LoadConfiguration(builder => {
   // Dynamically adds the console-target after having loaded from NLog.config
   var consoleTarget = new ColoredConsoleTarget("console");
   builder.Configuration.AddRule(LogLevel.Info, LogLevel.Fatal, consoleTarget);
}));

One can also setup support for loading NLog.config first in Process-Directory (Before NLog5 is released)

var processDir = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
LogManager.Setup().
   LoadConfigurationFromFile(Path.Combine(processDir, "NLog.config"), optional: true).
   LoadConfigurationFromFile();  // Skips loading of default NLog.config if config already loaded

@snakefoot
Copy link
Contributor Author

snakefoot commented Mar 31, 2020

Notice no unit-tests yet, because I'm guessing we are entering discussion mode first.

@snakefoot snakefoot added this to the 4.7.1 milestone Mar 31, 2020
@snakefoot snakefoot added the enhancement Improvement on existing feature label Mar 31, 2020
@snakefoot snakefoot force-pushed the SetupBuilderLoadNLogConfig branch from e019da5 to 80204a8 Compare March 31, 2020 18:13
@snakefoot snakefoot force-pushed the SetupBuilderLoadNLogConfig branch from 80204a8 to 36a65b6 Compare March 31, 2020 18:27
@304NotModified 304NotModified self-assigned this Mar 31, 2020
@snakefoot snakefoot force-pushed the SetupBuilderLoadNLogConfig branch from 36a65b6 to 501d5c2 Compare March 31, 2020 18:31
@snakefoot snakefoot force-pushed the SetupBuilderLoadNLogConfig branch 5 times, most recently from e725aa2 to 0a04748 Compare March 31, 2020 20:59
@snakefoot snakefoot force-pushed the SetupBuilderLoadNLogConfig branch 5 times, most recently from 1c6b161 to 833b721 Compare April 3, 2020 04:37
@304NotModified
Copy link
Member

304NotModified commented Apr 9, 2020

This allows one to setup a fallback configuration, if no NLog.config file was found:

LogManager.Setup().LoadNLogConfigFromFile().LoadNLogConfig(builder =>{
var config = builder.LogFactory.Configuration;
if (config != null)
        return;   // Config already assigned and loaded

// Targets where to log to: File and Console
var logconsole = new NLog.Targets.ConsoleTarget("logconsole");

// Rules for mapping loggers to targets            
builder.Configuration.AddRule(LogLevel.Info, LogLevel.Fatal, logconsole);
}));

How does this works if we load from file and enhance it from API? (so it isn't a fallback). And if we do reload, does that work then?

Notice no unit-tests yet, because I'm guessing we are entering discussion mode first.

I think it's nice! Only some naming things I guess

@snakefoot
Copy link
Contributor Author

snakefoot commented Apr 9, 2020

How does this works if we load from file and enhance it from API? (so it isn't a fallback). And if we do reload, does that work then?

Notice that the two last code-examples are a little different (fallback when no config):

LogManager.Setup().LoadNLogConfigFromFile().LoadNLogConfig(builder =>{
var config = builder.LogFactory.Configuration;
if (config != null)
        return;   // Config already assigned and loaded (So no need to create fallback config

And the other (enhancing loaded config):

LogManager.Setup().LoadNLogConfigFromFile().LoadNLogConfig(builder =>{
  // Enhances the existing config (Automatically creates new Configuration if none loaded)
  builder.Configuration.AddRule(LogLevel.Info, LogLevel.Fatal, consoleTarget);

Ofcourse with autoReload="true" then all is lost, when enhancing loaded config (reload on file-change will not automatically apply runtime changes). I guess people who are into such exotic scenario will come with some great use-cases and suggestions for how to implement that logic. Much easier to work actual use-cases than trying to predict everything.

Like I said in my introduction of this. Then it is a very small dive into the fluent-setup of NLog-config.

@snakefoot
Copy link
Contributor Author

I think it's nice! Only some naming things I guess

Created some unit-tests that increases code-coverage.

@snakefoot snakefoot force-pushed the SetupBuilderLoadNLogConfig branch 3 times, most recently from 378f07e to cb39c21 Compare April 9, 2020 21:59
@snakefoot
Copy link
Contributor Author

Btw. happy to see that NLog 4.7.0 seems to be swimming nicely along without any major issues. Not like NLog 4.6.0 where my refactoring of XmlLoggingConfiguration (To load NLog.config from appsettings.json) caused all kind of bad experiences.

But maybe I have just jinxed it, and the radio-silence comes from the corona dance :)

@snakefoot snakefoot force-pushed the SetupBuilderLoadNLogConfig branch from cb39c21 to 5ec96ae Compare April 13, 2020 22:16
@snakefoot
Copy link
Contributor Author

snakefoot commented Apr 20, 2020

Should we include a CreateLogger() or GetCurrentClassLogger() / GetLogger() as extension-methods to ISetupBuilder ?

If you would like to remove the LogFactory-indirection ?

So this:

var logger = LogManager.Setup().LoadConfigurationFromAppSettings().LogFactory.GetCurrentClassLogger();

Becomes this:

var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();

@304NotModified
Copy link
Member

Should we include a CreateLogger() or GetCurrentClassLogger() / GetLogger() as extension-methods to ISetupBuilder ?

Sounds good! GetCurrentClassLogger() / GetLogger() sounds as the best option!

@snakefoot
Copy link
Contributor Author

Sounds good! GetCurrentClassLogger() / GetLogger() sounds as the best option!

Created PR #3909

@304NotModified
Copy link
Member

304NotModified commented Apr 20, 2020

One name thing, would it be easier? (So drop the NLog in the name)

LogManager.Setup().LoadConfigFromFile().LoadConfig(logBuilder =>{ ...

@snakefoot
Copy link
Contributor Author

snakefoot commented Apr 20, 2020

One name thing, would it be easier? (So drop the NLog in the name)

I did that on purpose, because there is both "NLog.config" and "appsettings.json" and "app.config". All of them are files.

NLog gives special love and attention to NLog.config so yes it is the favorite file, but not the only one.

@304NotModified
Copy link
Member

I did that on purpose, because there is both "NLog.config" and "appsettings.json" and "app.config". All of them are files.

Ah well I expected that "appsettings.json" and "app.config" would work (in the future) 👼

What about LoadConfig etc, and adding a optional "logFileType" parameter?

@304NotModified
Copy link
Member

What about LoadConfig etc, and adding a optional "logFileType" parameter?

Ow that won't scale nice between other packages.

I stil prefer LoadConfig, but I think "appsettings.json" should be named other, e.g. LoadConfigFromAppsettingsJson

@snakefoot
Copy link
Contributor Author

snakefoot commented Apr 20, 2020

Ah well I expected that "appsettings.json" and "app.config" would work (in the future)

Never going to happen, since all of them have different dependencies, so they would require different assemblies (and extension-methods). Just like you see is happening in NLog.Extension.Logging and Nlog.Web.

P.S. It was my dream when I introduced LogManager.LoadConfiguration but now see it was a mistake.

/// <summary>
/// Loads NLog config from filename <paramref name="configFile"/> if provided, else fallback to scanning for NLog.config
/// </summary>
public static ISetupBuilder LoadNLogConfigFromFile(this ISetupBuilder setupBuilder, string configFile = null, bool optional = true)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: configFilePath?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like one is only giving the candidate-path to the NLog.config file. Not sure it is an improvement.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well configFile sounds a bit like the content of the configFile.

@304NotModified
Copy link
Member

my dream

To what is this referring?

@snakefoot
Copy link
Contributor Author

snakefoot commented Apr 20, 2020

To what is this referring?

My dream that LogManager.LoadConfiguration should load all kind of files.

@304NotModified
Copy link
Member

304NotModified commented Apr 20, 2020

ow yes, that would be nice.

But you still prefer LoadNLogConfig over LoadConfig? I never saw the relation between "NLog" word and NLog.config (as dumb user is still would try LoadNLogConfig("appsettings.json"))

@snakefoot
Copy link
Contributor Author

snakefoot commented Apr 20, 2020

Yes to me LoadNLogConfig is better than LoadConfig. As it signals the file has to match the format of NLog.config. And the contents of the config is the NLog LoggingConfiguration, and not some other config.

@snakefoot
Copy link
Contributor Author

snakefoot commented Apr 20, 2020

I guess these two methods could have different name:

LogManager.Setup().LoadNLogConfig(nlogConfig);

LogManager.Setup().LoadNLogConfig(builder => )

Could also be called:

LogManager.Setup().LoadLoggingConfiguration(nlogConfig);

LogManager.Setup().LoadLoggingConfiguration(builder => )

@snakefoot
Copy link
Contributor Author

Changed builder-method from LogFactory to ISetupNLogConfigBuilder then one can create config-extension-methods for the interface instead of for LogFactory.

@304NotModified
Copy link
Member

I guess these two methods could have different name:

LogManager.Setup().LoadNLogConfig(nlogConfig);

LogManager.Setup().LoadNLogConfig(builder => )

Could also be called:

LogManager.Setup().LoadLoggingConfiguration(nlogConfig);

LogManager.Setup().LoadLoggingConfiguration(builder => )

That's IMO better. I don't think "NLog Should be in a method name, as we're already in a NLog context.

Why about LogManager.Setup().LoadConfiguration? It is consistent with LogManager.LoadConfiguration then.

@snakefoot snakefoot force-pushed the SetupBuilderLoadNLogConfig branch from 426c07b to cfe7104 Compare April 26, 2020 12:21
@snakefoot snakefoot force-pushed the SetupBuilderLoadNLogConfig branch from cfe7104 to 5f8f17f Compare April 26, 2020 12:21
@snakefoot
Copy link
Contributor Author

snakefoot commented Apr 26, 2020

Why about LogManager.Setup().LoadConfiguration?

Have updated the PR with the new names.

Some adjustment is needed for:

NLog/NLog.Extensions.Logging#412
NLog/NLog.Web#540

@sonarqubecloud
Copy link

Kudos, SonarCloud Quality Gate passed!

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities (and Security Hotspot 0 Security Hotspots to review)
Code Smell A 5 Code Smells

98.7% 98.7% Coverage
0.0% 0.0% Duplication

@snakefoot snakefoot changed the title NLog.LogManager.Setup() - Introduced LoadNLogConfig and friends for ISetupBuilder NLog.LogManager.Setup() - Introduced LoadConfiguration and friends for ISetupBuilder Apr 26, 2020
@304NotModified 304NotModified merged commit b21c64a into NLog:master Apr 28, 2020
@304NotModified
Copy link
Member

Cool! Thanks!

@snakefoot
Copy link
Contributor Author

@snakefoot snakefoot added the documentation done all docs done (wiki, api docs, lists on nlog-project.org, xmldocs) label Nov 23, 2021
@snakefoot snakefoot deleted the SetupBuilderLoadNLogConfig branch July 30, 2022 10:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation done all docs done (wiki, api docs, lists on nlog-project.org, xmldocs) enhancement Improvement on existing feature needs documentation on wiki size/L
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants