-
Notifications
You must be signed in to change notification settings - Fork 44
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
editoast: setup tracing with opentelemetry for TestApp
#10122
base: dev
Are you sure you want to change the base?
editoast: setup tracing with opentelemetry for TestApp
#10122
Conversation
TestApp
Codecov ReportAttention: Patch coverage is
❗ Your organization needs to install the Codecov GitHub app to enable full functionality. Additional details and impacted files@@ Coverage Diff @@
## dev #10122 +/- ##
==========================================
+ Coverage 79.93% 81.45% +1.51%
==========================================
Files 1057 1058 +1
Lines 106302 104318 -1984
Branches 724 724
==========================================
- Hits 84977 84971 -6
+ Misses 21283 19305 -1978
Partials 42 42
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
c5b5f96
to
8a7a2ad
Compare
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.
Thank you for the PR. Let's see if we can improve it.
8a7a2ad
to
c361ea8
Compare
c361ea8
to
b5ff13b
Compare
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.
Thanks for this PR. A few comments about architecture and test isolation. Besides, with the context of what you're working on I suppose this is about collecting logs for unit testing, but it's not clear to me how that would work. Why does printing logs on stdout help? Do you plan to capture the stream? A bit more context in the PR description or in the related issue would help.
editoast/src/views/test_app.rs
Outdated
client::{TelemetryConfig, TelemetryKind}, | ||
core::{mocking::MockingClient, CoreClient}, | ||
generated_data::speed_limit_tags_config::SpeedLimitTagIds, | ||
infra_cache::InfraCache, | ||
map::MapLayers, | ||
try_init_tracing, | ||
valkey_utils::ValkeyConfig, | ||
AppState, ValkeyClient, | ||
AppState, EditoastMode, ValkeyClient, |
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.
Wrong dependency order. We want client
and bin editoast
to depend on views
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.
Got it, but I need these structs for init_tracing
in test_app
:
let telemetry_config = TelemetryConfig {
telemetry_kind: TelemetryKind::Opentelemetry,
..Default::default()
};
let sub = init_tracing(EditoastMode::Webservice, &telemetry_config, exporter);
let tracing_guard = tracing::subscriber::set_default(sub);
Any suggestions on how to better isolate 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.
You could move init_tracing
in editoast_common
, but EditoastMode
and the telemetry_config
do not make sense there. You'll need some kind of mapping.
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’ve updated the function signature for create_tracing_subscriber
to the following:
pub fn create_tracing_subscriber<T: SpanExporter + 'static>(
mode: Option<EditoastMode>,
telemetry_config: Option<TelemetryConfig>,
exporter: T,
) -> impl tracing::Subscriber
I believe it adds more flexibility. what do you think?
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'm not entirely convinced 😕
- This does not solves the dependency problem: the function is still imported in
views
from thecrate
level. - We have two calls to that function and we know each time which mode and config we want. So there's no need for flexibility when 100% of our usage do not require that.
- I'd argue that hiding a parameter behind a
None
degrades readability: now we have to look inside the function to find the actual values of the parameters, both of them not having an obvious default value.
Wdyt?
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’ve updated the code based on your feedback. Please verify if the changes align with your suggestions. @leovalais
Apologies for that. I've added more details in the description, and I hope it helps clarify things. |
Thanks for adding some context. So if I get it right, the point is not to necessarily print on stdout, but rather to setup OpenTelemetry so that the request header can be read. The fact that it prints on stdout is irrelevant, or am I missing smth? I'm surely lacking OpenTelemetry and tracing knowledge, but I still don't understand what setting up a span exporter has to do with reading the HTTP request headers? Especially since the middleware |
You're right, printing to |
@leovalais From what I understand, But as said by @hamz2a, one of the main idea of this PR is to have a similar setup of the subscriber for tests and for production code. We had a hard time debugging what was not working and part of it was that it was working well with a |
b5ff13b
to
4492eb8
Compare
4492eb8
to
112a5c5
Compare
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 believe it's in a much better state now 🚀. Thank you 🎉
9d9e553
to
373cf12
Compare
373cf12
to
45217d4
Compare
033cbc3
to
5c49d18
Compare
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.
Almost there, thanks for the changes! There's still a dependency order issue, but apart from that, lgtm.
editoast/src/views/test_app.rs
Outdated
use serde::de::DeserializeOwned; | ||
use tower_http::trace::TraceLayer; | ||
use url::Url; | ||
|
||
use crate::{ | ||
core::{mocking::MockingClient, CoreClient}, | ||
create_tracing_subscriber, |
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.
This is the import that breaks the dependency order. views
cannot use
something from the crate
or client
level. I'd suggest moving create_tracing_subscriber
to editoast_common
.
Yes, but struct TracingConfig {
stream: enum { Stderr, Stdout },
telemetry: Option<struct {
service_name: String,
telemetry_endpoint: Url
}>
} Wdyt? |
5c49d18
to
4418d21
Compare
Signed-off-by: hamz2a <[email protected]>
4418d21
to
72ae856
Compare
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.
LGTM, thanks for all the modifications!
@@ -66,61 +58,18 @@ pub use valkey_utils::ValkeyConnection; | |||
/// - we *expect* a webserver to output logging information, so since it's an expected | |||
/// output (and not extra information), it should be on stdout | |||
#[derive(Debug, PartialEq)] | |||
enum EditoastMode { | |||
pub enum EditoastMode { |
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.
pub enum EditoastMode { | |
enum EditoastMode { |
@@ -22,7 +22,7 @@ pub mod train_schedule; | |||
pub mod work_schedules; | |||
|
|||
#[cfg(test)] | |||
mod test_app; | |||
pub mod test_app; |
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.
pub mod test_app; | |
mod test_app; |
) | ||
.with_span_events(tracing_subscriber::fmt::format::FmtSpan::CLOSE) | ||
.finish(); | ||
let sub = create_tracing_subscriber(TracingConfig::default(), NoopSpanExporter); |
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.
let sub = create_tracing_subscriber(TracingConfig::default(), NoopSpanExporter); | |
let sub = create_tracing_subscriber(TracingConfig { | |
... | |
}, NoopSpanExporter); |
Could the default value be built here? This way we gather all default test constants here instead of having them scattered across different crates. The impl Default
and derive(Derivative)
from common::tracing
can be removed.
closes #10123
I added the
OpenTelemetry
layer inTestApp
to capture thetrace_id
set in the header, so we can test the endpoint we'll add in the ticket.init_tracing
to accept a customSpanExporter
for better flexibility, including support for testing scenarios.main.rs
to configure and initialize tracing.test_app.rs
to use opentelemetry layer.