-
Notifications
You must be signed in to change notification settings - Fork 453
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
Flush fix for SimpleLogProcessor #1308
Flush fix for SimpleLogProcessor #1308
Conversation
The approach used in #1305 was used here as well. Its proving very useful to catch issues quickly, so irrespective of the actual fix, expect a bunch of new tests based on |
If this approach is good enough, that can remove the "crossbeam-channel = { version = "0.5", optional = true }" dependency from sdk completely as well? |
Codecov ReportAttention:
... and 9 files with indirect coverage changes 📢 Thoughts on this report? Let us know! |
Thanks for picking this up, and the InMemoryExporter tests :) So there are two options here Option 1: Keep the existing queue based approach, and fix the SimpleLogProcessor::force_flush to process the queue (as done for spans). Which mean Option 2: The approach in this PR to do a export from application thread, and so a mutex lock is required to ensure that While most of the language implementation (probably all) go with Option 2, I don't have strong opinion against Option 1 if we address the flushing issue. Nothing wrong with the performance gain even for non-production usage :) |
I want to use Option 2 only, unless there is a strong reason not to.
|
that's a good point. Good to get feedback on the reason behind original implementation :) |
Pub-sub based approach first introduced in #502 to address the performance issue of simple span processors. One thing worth noting is currently users who don't use async runtime in Rust cannot use |
@@ -42,62 +42,32 @@ pub trait LogProcessor: Send + Sync + Debug { | |||
/// emitted. If you find this limiting, consider the batch processor instead. | |||
#[derive(Debug)] | |||
pub struct SimpleLogProcessor { | |||
sender: crossbeam_channel::Sender<Option<LogData>>, | |||
shutdown: crossbeam_channel::Receiver<()>, | |||
exporter: Mutex<Box<dyn LogExporter>>, |
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.
Why does this need to be wrapped in a Mutex
? It seems a processor owns its exporter and the methods to call on it are &mut self
, so who is thing shared with that requires the Mutex
?
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.
Can I table this, and come back to this after this PR?
Thanks for sharing the background! "Some downstream SpanProcessors and subsequent SpanExporters called from this operation may be used for testing, proof-of-concept ideas, or debugging and may not be designed for production use themselves. They are not in the scope of this requirement and recommendation." @jtescher Can you comment on any actual use cases on having a performant simple span processor? Or we did that just for spec compliance? If that is the case, would you be okay to revert that change, as spec does not require that from us. |
This is something we need to address separately, anyways, do you agree? i.e We want to support users who do not use aync runtimes. (not just traces, but metrics too) |
Not sure I would assume that. |
Can you share some user needs around SimpleProcessor? The linked PR talks mostly about spec compliance... |
@jtescher Could you comment on #1308 (comment), when you get a chance ? I am mostly looking to ensure we agree (or disagree) on the direction, which is:
In the absence of any real user needs for high-performing SimpleProcessor, we should strive to keep it simple! Happy to change my views, if there are actual use cases I am not aware of! |
Yeah I don't think it needs to be as performant 👍 . The simple case should be for scripts / jobs / other sync activities which shouldn't produce a volume of spans where it is impactful. |
@TommyCpp @jtescher Please re-review. I have fixed handling the lock poisoning in latest commits. The question from @shaun-cox about the very need of Mutex - Let me get back to it after this PR. This PR now makes it easy to write semi-integration tests for Logging using in-memory-exporter, and I want to add more of that. |
@hdost Can you re-review as well as you have previously reviewed? |
SimpleLogProcessor's force_flush was incorrectly implemented as it did not do anything assuming there was nothing to flush. But the
SimpleLogProcessor
uses a queue with pub-sub mechanism to operate, so flush is not a no-op. This is handled correctly forSimpleSpanProcessor
.Instead of borrowing the approach from
SimpleSpanProcessor
, I have refactored theSimpleLogProcessor
to use no queue and instead use a simple Mutex protected exporter/shutdown. I feel this is sufficient (and want to port this toSimpleSpanProcessor
as well), but would like to get feedback on the approach - was there some scenario which prompted the queue/pub-sub for SimpleProcessors? Or this approach is sufficient?There should not be any perf concerns as SimpleProcessors are used for learning/dev scenarios, and not for production. (Except when you are exporting to operating system native tracing like etw, user_events, but for them we have written RentrantProcessor separately.)
Note: I temporarily added some extra dependencies to test this out. If the direction is okay, I'll do a cleanup and modify the tests to not rely on tracing and friends.