Skip to content

Conversation

IanYates
Copy link
Contributor

What issue does this PR address?
Addresses issue #1105. Replaces PR #1108

Does this PR introduce a breaking change?
No

Please check if the PR fulfills these requirements

  • The commit follows our guidelines
  • Unit Tests for the changes have been added (for bug fixes / features)

Other information:
Sorry for the new PR. Given the changes in the old PR were in the completely wrong file, it seemed easier to just close that PR and open a new one.

Issue #1105 asked for an easy way to get at a constant instance of a SilentLogger. The original PR added this on the Log class and slightly adjusted that class' internals to make use of this instance.
This new PR instead modifies the Logger class to add a static Logger.None property that returns the same SilentLogger.

One new allocation overall. I suspect we can live with that (?). Former PR didn't have that issue. A lazy init sounds like overkill for this but I'm happy to be told I'm wrong.

Only one new unit test - verifying that the property is a silent logger. There's not a lot of machinery or moving parts to verify anymore compared with the earlier PR.

Feedback most welcome. Thanks 💯

…exposing a constant SilentLogger instance
Copy link
Member

@nblumhardt nblumhardt left a comment

Choose a reason for hiding this comment

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

Looks good! Just a couple of nitpicky items from me.

/// <summary>
/// An <see cref="ILogger"/> instance that efficiently ignores all method calls
/// </summary>
public static ILogger None
Copy link
Member

Choose a reason for hiding this comment

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

We could get away without a backing property by declaring this as:

public static ILogger None { get; } = new SilentLogger();

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No worries - wasn't sure if you were happy with newer syntax

static readonly ILogger _noneLogger = new SilentLogger();

/// <summary>
/// An <see cref="ILogger"/> instance that efficiently ignores all method calls
Copy link
Member

Choose a reason for hiding this comment

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

Nitpick - missing ..

@nblumhardt
Copy link
Member

Not sure why the AppVeyor CI build has started producing flaky results around LogContext - will keep an eye on it, but pretty sure it's not related to this PR 👍

@tsimbalar
Copy link
Member

Maybe some unit tests to add :

  • Asking for Logger.None twice returns the same instance (i.e. it's not a neweach time)
  • the result of new LoggerConfiguration().CreateLogger() is Logger.None

@IanYates
Copy link
Contributor Author

IanYates commented Feb 20, 2018

@tsimbalar - I've addressed your first suggestion.
The second though is a little more work and may warrant some discussion with @nblumhardt first.

This test


        [Fact]
        public void EmptyLoggerConfigurationCreatesNoneLogger()
        {
            var emptyConfigLogger = new LoggerConfiguration().CreateLogger();
            var noneLongger = Logger.None;

            Assert.Equal(emptyConfigLogger, noneLongger);
        }

fails.

We could modify CreateLogger() to see that there's zero configuration and thus deliberately return Logger.None. It doesn't do that now. SilentLogger itself is barely used in the Serilog codebase (apart from the tests). Certainly there's no way you could get one from CreateLogger() as the code stands now (which surprised me given the chat in issue #1105)

@nblumhardt - should we do this at all? If so, want it in a separate PR? I've only had a cursory look at LoggerConfiguration.cs and I can think of a couple of approaches - one to check for any methods/setters being called and set a flag so we know not to short-circuit return Logger.None. The other, which is less invasive but may not be quite correct, would be to have CreateLogger() see if everything is still at the defaults (empty sinks list, etc), and if so, just return Logger.None.

Con against doing it... If you really want a silent logger, use the .None property rather than the hacky 'empty configuraton' approach.

@tsimbalar
Copy link
Member

@IanYates oh my bad, I thought that was the actual behavior ... I may be mixed up ... The test that should pass as of now, though, is that Log.Logger should be a SilentLogger by default, if not assigned otherwise ... should it actually be Logger.None ?

@nblumhardt
Copy link
Member

Great suggestions @tsimbalar 👍

In v1.x, CreateLogger() did return the SilentLogger. But, in v2, we switched the return type of CreateLogger from ILogger to Logger so that the need to dispose the result was communicated by the API.

I think this is ready to go; no idea why the CI build is suddenly unhappy, but guess that's something to figure out another day :-)

@nblumhardt nblumhardt merged commit 96bfe61 into serilog:dev Feb 20, 2018
@IanYates IanYates deleted the issue-1105-b branch February 20, 2018 23:13
@nblumhardt nblumhardt mentioned this pull request May 17, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants