-
Notifications
You must be signed in to change notification settings - Fork 271
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
feat: add json log format as an option #500
Conversation
@naseemkullah this is a type alias --- we are assigning a shorter name to a long, complicated type. Here's the section on type aliases in the Rust book. In this case, the This code will probably have to be changed up a bit if we want to allow conditionally using the |
Current status @hawkw : • Replaced the aforementioned type alias with en enum consisting of Json and Plain Subscriber types. • Now trying to decipher and deal with the following errors introduced by the change regarding mismatched types and unsatisfied trait bounds (tips, links, references are all most welcome): pub fn reload_handle(&self) -> crate::reload::Handle<crate::EnvFilter, Formatter<N, E, W>>
Returns a Handle that may be used to reload the constructed subscriber's filter.
mismatched types
expected enum `trace::Subscriber`, found struct `tracing_subscriber::layer::Layered`
note: expected struct `tracing_subscriber::reload::Handle<_, trace::Subscriber>`
found struct `tracing_subscriber::reload::Handle<_, tracing_subscriber::layer::Layered<tracing_subscriber::fmt::fmt_layer::Layer<tracing_subscriber::registry::sharded::Registry, tracing_subscriber::fmt::format::DefaultFields, tracing_subscriber::fmt::format::Format<tracing_subscriber::fmt::format::Full, trace::Uptime>>, tracing_subscriber::registry::sharded::Registry>>`rustc(E0308)
trace.rs(53, 16): expected enum `trace::Subscriber`, found struct `tracing_subscriber::layer::Layered` pub fn reload(&self, new_layer: impl Into<L>) -> Result<(), Error>
Replace the current layer with the provided new_layer.
no method named `reload` found for struct `tracing_subscriber::reload::Handle<tracing_subscriber::filter::env::EnvFilter, trace::Subscriber>` in the current scope
method not found in `tracing_subscriber::reload::Handle<tracing_subscriber::filter::env::EnvFilter, trace::Subscriber>`
note: the method `reload` exists but the following trait bounds were not satisfied:
`trace::Subscriber : tracing_core::subscriber::Subscriber`
`tracing_subscriber::filter::env::EnvFilter : tracing_subscriber::layer::Layer<trace::Subscriber>`rustc(E0599)
trace.rs(84, 20): method not found in `tracing_subscriber::reload::Handle<tracing_subscriber::filter::env::EnvFilter, trace::Subscriber>` pub fn with_current<T>(&self, f: impl FnOnce(&L) -> T) -> Result<T, Error>
Invokes a closure with a borrowed reference to the current layer, returning the result (or an error if the subscriber no longer exists).
no method named `with_current` found for struct `tracing_subscriber::reload::Handle<tracing_subscriber::filter::env::EnvFilter, trace::Subscriber>` in the current scope
method not found in `tracing_subscriber::reload::Handle<tracing_subscriber::filter::env::EnvFilter, trace::Subscriber>`
note: the method `with_current` exists but the following trait bounds were not satisfied:
`trace::Subscriber : tracing_core::subscriber::Subscriber`
`tracing_subscriber::filter::env::EnvFilter : tracing_subscriber::layer::Layer<trace::Subscriber>`rustc(E0599)
trace.rs(91, 14): method not found in `tracing_subscriber::reload::Handle<tracing_subscriber::filter::env::EnvFilter, trace::Subscriber>` |
Hi Naseem, sorry it took me a bit to reply to your comments, I've been quite busy. The reason your approach of adding an enum isn't working is because the enum you've created doesn't inherit the trait implementations of its two variants. If you wanted to implement the feature this way, you would need to write an implementation of the impl tracing::Subscriber for Subscriber {
fn new_span(&self, span: &tracing::span::Attributes<'_>) -> tracing::span::Id {
match self {
Subscriber::Json(s) => s.new_span(span),
Subscriber::Plain(s) => s.new_span(span),
}
}
// ... and do the same thing for all the other trait methods on
// the `Subscriber` trait ...
} However, I don't know if this is the best approach. Adding the enum introduces a layer of indirection to every subscriber method call, which is not ideal, and it requires writing a bunch of additional code to forward the The other error you're running into is due to the
Here, I think changing the linkerd2-proxy/linkerd/app/core/src/trace.rs Lines 81 to 93 in 1d1eabd
I think the Does that all make sense? Let me know if you have any additional questions! |
Hi @hawkw ,not at all, I'm sorry for being somewhat of a burden as I am a little out of my depth!
Yes, thanks for thoroughly explaining all that! Stay tuned for my attempt at implementing this (or another question 😅 )! |
Hi @hawkw, there is probably room for stylistic improvement, refactoring and deduplicating so please let me know. But I think this is ready for a first review.
Also, sorry for the forced pushes, just wanted to clean the history. |
The proxy integration tests use the same tracing configuration as the proxy binary: linkerd2-proxy/linkerd/app/integration/src/lib.rs Lines 40 to 51 in cb161a1
(note the call to app::core::trace::with_filter )
So, you should be able to run the integration tests with
If you look in
Yup, that's correct. I believe it would be necessary to add it to the proxy-injector control plane component, and to the CLI. Both of those live in the I'll take a closer look at the code changes here soon, but it's great that everything is working! |
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.
The overall approach looks right to me! I had a couple suggestions.
linkerd/app/core/src/trace.rs
Outdated
Json { | ||
inner: reload::Handle< | ||
EnvFilter, | ||
Formatter<format::JsonFields, format::Format<format::Json, Uptime>>, |
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.
Take it or leave it: I might consider adding JsonFormatter
and PlainFormatter
type aliases for these, because this is a bit wordy; not a blocker though.
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 would increase readability. I am confused as to wether these are Formatters or Subscribers, originally when there was only the Plain version it was type aliased as Subscriber. Going with the term Formatter now but please advise.
edit: Just too clarify, what was once:
type Subscriber = Formatter<format::DefaultFields, format::Format<format::Full, Uptime>>;
is now
type PlainFormatter = Formatter<format::DefaultFields, format::Format<format::Full, Uptime>>;
hence the confusion around if it is a Subscriber or a Formatter.
Seems like locally the following integration tests fail with or without the added env vars:
|
These same tests fail when I try |
Sorry I haven't had a chance to give this another review yet, I've been quite busy. I'll try to take a look today. |
What operating system are you running the tests on? I believe the error you're seeing may be due to those tests expecting Unix error code names in the metrics. |
As have I! No worries nor rush @hawkw but thanks! |
Ah that could explain it, I am running these on MacOS. |
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.
Overall, this looks good to me. I had a few minor suggestions, but nothing blocking.
We'll need a second approval from someone else in the @linkerd/proxy-maintainers team before we can merge this.
@naseemkullah, thanks again for working on this, and for your patience waiting for a review!
(dispatch, handle) | ||
.with_env_filter(filter); | ||
|
||
match format.as_ref().to_uppercase().as_ref() { |
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.
We could also do this using the str::eq_ignore_ascii_case
method in an if
-statement.
Try running them in a Linux docker container? IIRC there were some issues in the past where BSD (macOS) returned a different error code than Linux in some socket operations, but I thought we had configured it to skip tests effected by this on Macs? Could've been accidentally re-enabled. |
Create an enum for LevelHandle to handle json and plaintext cases. Since reloading the filter is not in the hot path, it's okay to introduce the overhead of having to match on two enum variants. Also remove Subscriber type alias as it is no longer used. Signed-off-by: Naseem <naseem@transit.app>
Although only used in one place atm, they are rather wordy and defining them increases code readability. Signed-off-by: Naseem <naseem@transit.app>
the .with_ansi option doesn't actually do anything with the JSON formatter --- it doesn't support ANSI colors Signed-off-by: Naseem <naseem@transit.app>
Signed-off-by: Naseem <naseem@transit.app>
…nd plain Signed-off-by: Naseem <naseem@transit.app>
Signed-off-by: Naseem <naseem@transit.app>
Create an enum for LevelHandle to handle json and plaintext cases. Since reloading the filter is not in the hot path, it's okay to introduce the overhead of having to match on two enum variants. Also remove Subscriber type alias as it is no longer used. Signed-off-by: Naseem <naseem@transit.app>
Signed-off-by: Naseem <naseem@transit.app>
It is more concise to use tuple-like enum variants here rather than struct-like ones. Co-authored-by: Eliza Weisman <eliza@buoyant.io> Signed-off-by: Naseem <naseem@transit.app>
Signed-off-by: Naseem <naseem@transit.app>
Thanks so much for your patience and guidance @hawkw , I may have broke it trying to implement code review: fd21ce6 could please take a look 😅 I did weird things to get it to compile. |
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 so much for your patience and guidance @hawkw , I may have broke it trying to implement code review: fd21ce6 could please take a look sweat_smile I did weird things to get it to compile.
I don't see anything weird here --- it looks like you're using the tuple-like enum correctly :) This still looks good to me!
Co-authored-by: Eliza Weisman <eliza@buoyant.io> Signed-off-by: Naseem <naseem@transit.app>
Alright thanks, really was not sure (it looks a lot better with the renamed inner values to |
Json log formatting has been added via linkerd/linkerd2-proxy#500 but wiring the option through as an annotation/CLI flag is still necessary. This PR adds the annotation and cli flag to configure log format. Signed-off-by: Naseem <naseem@transit.app>
Json log formatting has been added via linkerd/linkerd2-proxy#500 but wiring the option through as an annotation/CLI flag is still necessary. This PR adds the annotation and cli flag to configure log format. Closes linkerd#2491 Signed-off-by: Naseem <naseem@transit.app>
Json log formatting has been added via linkerd/linkerd2-proxy#500 but wiring the option through as an annotation/CLI flag is still necessary. This PR adds the annotation and cli flag to configure log format. Closes linkerd#2491 Signed-off-by: Naseem <naseem@transit.app>
Json log formatting has been added via linkerd/linkerd2-proxy#500 but wiring the option through as an annotation/CLI flag is still necessary. This PR adds the annotation and cli flag to configure log format. Closes linkerd#2491 Signed-off-by: Naseem <naseem@transit.app>
Json log formatting has been added via linkerd/linkerd2-proxy#500 but wiring the option through as an annotation/CLI flag is still necessary. This PR adds the annotation and cli flag to configure log format. Closes linkerd#2491 Signed-off-by: Naseem <naseem@transit.app>
Json log formatting has been added via linkerd/linkerd2-proxy#500 but wiring the option through as an annotation/helm value is still necessary. This PR adds the annotation and helm value to configure log format. Closes linkerd#2491 Signed-off-by: Naseem <naseem@transit.app>
Json log formatting has been added via linkerd/linkerd2-proxy#500 but wiring the option through as an annotation/helm value is still necessary. This PR adds the annotation and helm value to configure log format. Closes linkerd#2491 Signed-off-by: Naseem <naseem@transit.app>
Json log formatting has been added via linkerd/linkerd2-proxy#500 but wiring the option through as an annotation/helm value is still necessary. This PR adds the annotation and helm value to configure log format. Closes linkerd#2491 Signed-off-by: Naseem <naseem@transit.app>
This release primarily features an upgrade of the proxy's underlying Tokio runtime and its related libraries. We've observed lower latencies in initial benchmarks, but further testing and burn-in is warranted. Also, the proxy now honors the `LINKERD_PROXY_LOG_FORMAT=json` configuration to enable JSON-formatted logging. --- * Add a CODEOWNERS (linkerd/linkerd2-proxy#558) * Fix shellcheck issues in shell scripts (linkerd/linkerd2-proxy#554) * update the proxy to use std::future and Tokio 0.2 (linkerd/linkerd2-proxy#568) * Prune unused dependencies (linkerd/linkerd2-proxy#569) * Support LINKERD_PROXY_LOG_FORMAT=json (linkerd/linkerd2-proxy#500) * Change docs references from "master" to "main" (linkerd/linkerd2-proxy#571) * Upgrade tokio-rustls & webpki. (linkerd/linkerd2-proxy#570) * Makefile: Add shellcheck recipe (linkerd/linkerd2-proxy#555) * Update proxy-api dependencies (linkerd/linkerd2-proxy#573) * integration: fix missing traces (linkerd/linkerd2-proxy#572) * Update Rust to 1.44.0 (linkerd/linkerd2-proxy#574) * Use async/await to simplify connection-accept task (linkerd/linkerd2-proxy#575) * Update Rust to 1.44.1 (linkerd/linkerd2-proxy#576) * outbound: Split HTTP endpoint builder (linkerd/linkerd2-proxy#578) * Simplify protocol detection with async/await (linkerd/linkerd2-proxy#577) * Pin proxy-api at v0.1.13 (linkerd/linkerd2-proxy#579)
This release primarily features an upgrade of the proxy's underlying Tokio runtime and its related libraries. We've observed lower latencies in initial benchmarks, but further testing and burn-in is warranted. Also, the proxy now honors the `LINKERD_PROXY_LOG_FORMAT=json` configuration to enable JSON-formatted logging. --- * Add a CODEOWNERS (linkerd/linkerd2-proxy#558) * Fix shellcheck issues in shell scripts (linkerd/linkerd2-proxy#554) * update the proxy to use std::future and Tokio 0.2 (linkerd/linkerd2-proxy#568) * Prune unused dependencies (linkerd/linkerd2-proxy#569) * Support LINKERD_PROXY_LOG_FORMAT=json (linkerd/linkerd2-proxy#500) * Change docs references from "master" to "main" (linkerd/linkerd2-proxy#571) * Upgrade tokio-rustls & webpki. (linkerd/linkerd2-proxy#570) * Makefile: Add shellcheck recipe (linkerd/linkerd2-proxy#555) * Update proxy-api dependencies (linkerd/linkerd2-proxy#573) * integration: fix missing traces (linkerd/linkerd2-proxy#572) * Update Rust to 1.44.0 (linkerd/linkerd2-proxy#574) * Use async/await to simplify connection-accept task (linkerd/linkerd2-proxy#575) * Update Rust to 1.44.1 (linkerd/linkerd2-proxy#576) * outbound: Split HTTP endpoint builder (linkerd/linkerd2-proxy#578) * Simplify protocol detection with async/await (linkerd/linkerd2-proxy#577) * Pin proxy-api at v0.1.13 (linkerd/linkerd2-proxy#579)
Json log formatting has been added via linkerd/linkerd2-proxy#500 but wiring the option through as an annotation/helm value is still necessary. This PR adds the annotation and helm value to configure log format. Closes linkerd#2491 Signed-off-by: Naseem <naseem@transit.app>
Json log formatting has been added via linkerd/linkerd2-proxy#500 but wiring the option through as an annotation/helm value is still necessary. This PR adds the annotation and helm value to configure log format. Closes linkerd#2491 Signed-off-by: Naseem <naseem@transit.app>
* feat: add log format annotation and helm value Json log formatting has been added via linkerd/linkerd2-proxy#500 but wiring the option through as an annotation/helm value is still necessary. This PR adds the annotation and helm value to configure log format. Closes #2491 Signed-off-by: Naseem <naseem@transit.app>
JSON logs can be easily parsed in logging sinks such as Elasticsearch.
resolves linkerd/linkerd2#2491
cc @hawkw
Please bare with me as this is my first PR in Rust, unless you count a message change. :)
Could you please break down the anatomy of the following line:
linkerd2-proxy/linkerd/app/core/src/trace.rs
Line 12 in 610309e