Skip to content

ILogger integration - part 2#1315

Merged
cijothomas merged 12 commits into
masterfrom
reyang/ilogger
Oct 5, 2020
Merged

ILogger integration - part 2#1315
cijothomas merged 12 commits into
masterfrom
reyang/ilogger

Conversation

@reyang

@reyang reyang commented Sep 29, 2020

Copy link
Copy Markdown
Member

This PR follows #1308.

Changes

  • Added LogProcessor interface and plumbing.
  • Added LogRecord struct.
  • Updated the getting-started demo to show how it works (The demo is now becoming complicated, will do the cleanup in another PR).

Here goes the output from ./docs/logs/getting-started $ dotnet run:

2020-09-29T22:51:22.4971101Z Program(Information, Id=0): Hello, World!
2020-09-29T22:51:22.5049270Z Program(Information, Id=0): Hello from potato 0.99.
2020-09-29T22:51:22.5069823Z Program(Information, Id=0):
    name: tomato
    price: 2.99
    $format: Hello from {name} {price}.
2020-09-29T22:51:22.5098499Z Program(Information, Id=LogEx):
    obj: Program+Food
    $format: LogEx({obj}).
2020-09-29T22:51:22.5109950Z Program(Information, Id=LogEx):
    obj: { Name = pumpkin, Price = 5.99 }
    $format: LogEx({obj}).
2020-09-29T22:51:22.5115810Z Program(Information, Id=LogEx):
    obj: System.Collections.Generic.Dictionary`2[System.String,System.Object]
    $format: LogEx({obj}).
MyProcessor.OnShutdown(5000)
MyProcessor.Dispose(True)

For significant contributions please make sure you have completed the following items:

  • CHANGELOG.md updated for non-trivial changes
  • Design discussion issue #
  • Changes in public API reviewed

@reyang reyang requested a review from a team September 29, 2020 22:56
Comment thread src/OpenTelemetry.Api/CHANGELOG.md
Comment thread src/OpenTelemetry/Logs/CompositeLogProcessor.cs
Comment thread src/OpenTelemetry/Logs/OpenTelemetryLogger.cs Outdated
Comment thread src/OpenTelemetry/Logs/OpenTelemetryLogger.cs
@codecov

codecov Bot commented Sep 29, 2020

Copy link
Copy Markdown

Codecov Report

Merging #1315 into master will decrease coverage by 1.44%.
The diff coverage is 0.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1315      +/-   ##
==========================================
- Coverage   78.62%   77.17%   -1.45%     
==========================================
  Files         219      223       +4     
  Lines        6265     6384     +119     
==========================================
+ Hits         4926     4927       +1     
- Misses       1339     1457     +118     
Impacted Files Coverage Δ
src/OpenTelemetry/Logs/CompositeLogProcessor.cs 0.00% <0.00%> (ø)
src/OpenTelemetry/Logs/LogProcessor.cs 0.00% <0.00%> (ø)
src/OpenTelemetry/Logs/LogRecord.cs 0.00% <0.00%> (ø)
src/OpenTelemetry/Logs/OpenTelemetryLogger.cs 0.00% <0.00%> (ø)
...c/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs 0.00% <0.00%> (ø)
.../OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs 0.00% <0.00%> (ø)
... and 1 more

Comment thread src/OpenTelemetry/Logs/LogRecord.cs Outdated
Comment thread src/OpenTelemetry/Logs/LogRecord.cs Outdated
Comment thread src/OpenTelemetry/Logs/LogProcessor.cs
Comment thread src/OpenTelemetry/Logs/LogProcessor.cs
Comment thread docs/logs/getting-started/Program.cs Outdated
public static void Main()
{
/*
The OpenTelemetry style:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Though this style puts logging more aligned with Otel Tracing setup, this distances us from general ILogger guidelines.
Some thoughts:
If we go with this route, then users will have to rewire their entire logging plumbing, if they ever chose to move away from OpenTelemetry. If we stick to the existing ILogger style, then adding/removing OpenTelemetry is adding/removing one line - builder.AddOtel..(). The way user obtain ilogger instances (from logger factory or DI) does not have to change at all.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@alanwest @CodeBlanch please share your thoughts on the approaches, when you get a chance!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@cijothomas Good callout! We definitely want to fit into the standard .net core/extensions patterns. I think the code is actually fine. The only weird thing is the build-up pattern in this example project. I took a stab at fitting it into a more standard approach:

reyang/ilogger...CodeBlanch:reyang/ilogger

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@CodeBlanch Thanks. The code from you branch is fitting the pattern where there is a host and/or DI . We want to provide pure console app example. Its not possible in .netcore2.1 as only way to setup ilogger requires DI, but for other versions, its possible without Hosting/DI.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I suppose then I don't understand your issue with the design 😄 LoggerProvider is registered with the Factory. The Factory creates ILogger using all registered providers. What do you see that is deviating from the ILogger guidelines?

Regarding the pattern in the sample, makes sense. BUT I think it might be more confusing than useful to people. The official guide uses the host. So our example should too IMO. If we want to provide another example, that shows how to do it without the host, OK with that, but it feels like the exception, not the rule.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@reyang Agree. we can iterate on this and reach the right balance.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@cijothomas Gotcha. Agree with you we want to promote creating a logger through the LoggerFactory. Maybe we shouldn't even provide Sdk.CreateLoggerProviderBuilder and only have the ILoggingBuilder pattern?

@reyang Sounds good to me.

@alanwest alanwest Oct 3, 2020

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Sorry, coming to this conversation late... I agree that loggerProvider.CreateLogger is not ideal and it's best to conform to using the LoggerFactory.CreateLogger() in the context of this console application.

I think I agree with @CodeBlanch that Sdk.CreateLoggerProviderBuilder may not be required. If I'm following everyone's comments I think we'd want an extension method off of ILoggingBuilder like:

        public static ILoggingBuilder AddOpenTelemetry(this ILoggingBuilder builder, Action<OpenTelemetryLoggerOptions> configure)
        {
                   ...
        }

Posting in case you haven't read this. I find Stephen Cleary's explanation of ILogger and friends more consumable than some of the Microsoft documentation 😄. From his blog:

ILoggerFactory is a collection of ILoggerProviders that creates composite ILogger/ILogger loggers.
ILoggerProvider ia a provider for a specific logging system. It provides ILogger loggers to the ILoggerFactory.

That is, it is expected that someone configure all of their logging related concerns through the ILoggingBuilder and then use ILoggerFactory to get ILogger instances. It would be very unusual for someone to use an ILoggerProvider directly.

Also agree that we can iterate on this.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I've removed Sdk.CreateLoggerProviderBuilder based on the feedback here.

#endif
{
builder.AddOpenTelemetry();
builder.AddOpenTelemetry(options => options.AddProcessor(new MyProcessor()));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Duplicate builder.AddOpenTelemetry() to the above #if/#else/#endif, so we don't need another #if/#else/#endif below might make the code more friendly to new comer?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

As I've explained in #1315 (comment), have a simple tutorial/demo is not in this PR's scope.

Comment thread src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs Outdated
/// Adds processor to the provider.
/// </summary>
/// <param name="processor">Log processor to add.</param>
/// <returns>Returns <see cref="LoggerProviderBuilder"/> for chaining.</returns>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

comment is outdated now. This is returning OpenTelemetryLoggerOptions

/// <summary>
/// Build OpenTelemetryLoggerProvider with Processors.
/// </summary>
public class LoggerProviderBuilder

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We can remove this class now?

@cijothomas cijothomas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM - left couple of small comments.

@cijothomas cijothomas merged commit d1a3f53 into master Oct 5, 2020
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.

6 participants