-
Notifications
You must be signed in to change notification settings - Fork 770
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
LogEmitter System.Diagnostics.Tracing extension project #3305
Conversation
Codecov Report
@@ Coverage Diff @@
## main #3305 +/- ##
==========================================
- Coverage 86.21% 86.17% -0.04%
==========================================
Files 265 263 -2
Lines 9598 9543 -55
==========================================
- Hits 8275 8224 -51
+ Misses 1323 1319 -4
|
/// Create a <see cref="LogEmitter"/>. | ||
/// </summary> | ||
/// <returns><see cref="LogEmitter"/>.</returns> | ||
public LogEmitter CreateEmitter() => new(this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you consider LogEmitter as a pub-sub model? (similar like ActivitySource - which can be subscribed by multiple listeners)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hadn't thought about that. There isn't much in the spec, but it seems mainly to be a way to just throw logs at a processor/exporter without using a log library. I think it would be nice/useful to do this, but should we pursue through the spec first?
This now also includes |
/// <summary> | ||
/// Manages a pool of <see cref="LogRecord"/> instances. | ||
/// </summary> | ||
public sealed class LogRecordPool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't spend a whole lot of time on this algorithm. Just wanted to get something workable in place that we can improve as we go. There is a fast-path using a [ThreadStatic]
for simple processors executing on the same thread. For the batch case there is a shared pool which is used after the [ThreadStatic]
.
/// Rent a <see cref="LogRecord"/> from the pool. | ||
/// </summary> | ||
/// <returns><see cref="LogRecord"/>.</returns> | ||
public static LogRecord Rent() => current.RentCore(clearIfReused: true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have a clear position right now - would we prefer to do the clean up here or earlier (e.g. when the ref count goes to zero)? There might be small perf differences (e.g. I imagine Rent()
is always called synchronously, while DecRef might be called asynchronously - from the exporter thread).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the new iteration there isn't much to clear, log data is set fully each time (overriding what was there before). There is a bit of cleanup for the new reusable tag/attribute storage which I put on the return to the pool.
This PR was marked stale due to lack of activity and will be closed in 7 days. Commenting or Pushing will instruct the bot to automatically remove the label. This bot runs once per day. |
This PR was marked stale due to lack of activity and will be closed in 7 days. Commenting or Pushing will instruct the bot to automatically remove the label. This bot runs once per day. |
public static LoggerConfiguration OpenTelemetry( | ||
this LoggerSinkConfiguration loggerConfiguration, | ||
OpenTelemetryLoggerProvider openTelemetryLoggerProvider) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For some of our other extension methods we've put the extension method in the same namespace as the class that's being extended. So, does it make sense to put this method in the Serilog.Configuration
namespace, or just the root Serilog
namespace? Is there an existing precedence for other Serilog extensions?
EndProject | ||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.Serilog", "src\OpenTelemetry.Extensions.Serilog\OpenTelemetry.Extensions.Serilog.csproj", "{F5062ED1-6B59-45FC-8E08-2F5D41A19864}" | ||
EndProject | ||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.Tracing", "src\OpenTelemetry.Extensions.Tracing\OpenTelemetry.Extensions.Tracing.csproj", "{F1C65913-81EC-4297-A666-A66280E3E1B6}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tracing is such a commonly used term. I get it comes from System.Diagnostics.Tracing, but is there a better name?
What about OpenTelemetry.Extensions.EventSource
? Or if that's too narrow of a name maybe OpenTelemetry.Extensions.EventTracing
? Or... ugh maybe even OpenTelemetry.Extensions.SystemDiagnosticsTracing
🥴?
/// <summary> | ||
/// Gets a value indicating whether or not formatted messages should be included on log messages. | ||
/// </summary> | ||
public bool IncludeFormattedMessage { get; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bugging you again with the "we sure we wanna expose this publicly, yet?" question 😆... I don't have a strong feeling that we shouldn't, just wanna raise it for discussion.
Brainstorming alternatives, would it make sense instead to expose this on the LogEmitter
class?
At the moment, both the extensions are instantiated with an instance of the logging provider and then
- store the
IncludeFormattedMessage
setting, then - call
CreateEmitter()
Would it make sense to just instantiate the extensions with an emitter instead of the provider? So like Serilog would look like
Log.Logger = new LoggerConfiguration()
.WriteTo.OpenTelemetry(openTelemetryLoggerProvider.CreateEmitter()) // <- Register OpenTelemetry Serilog sink
.CreateLogger();
Again, I don't have a strong sense that one option is better than the other at this point, just curious of your thoughts.
Closing this PR because everything it was doing has been moved to smaller PRs. |
Changes
Proposed Public API
namespace OpenTelemetry.Logs { public class OpenTelemetryLoggerProvider { + public bool IncludeFormattedMessage { get; } } }
TODOs
CHANGELOG.md
updated for non-trivial changes