-
-
Notifications
You must be signed in to change notification settings - Fork 145
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(subscriber): support grpc-web and add
grpc-web
feature (#498)
## Description This pull request adds support for `grpc-web` to `console-subscriber`. Once you enable this feature by calling the `enable_grpc_web` function, you can connect the console-subscriber gRPC server using a browser client. ## Explanation of Changes 1. Added a new feature called `grpc-web` which requires the `tonic-web` crate as a dependency. 2. A new API named `serve_with_grpc_web` has been introduced. It appears to be similar to the `serve_with` API. However, if we were to use the same API with `serve_with`, it would result in a bound issue. We attempted to combine `serve_with_grpc_web` and `serve_with`, but it would create a very complex trait bound for the function. Therefore, we decided to introduce a new API to address this problem. 4. Added a new example named `grpc_web` to show how to use the `into_parts` API to customize the CORS layer. Ref #497 Signed-off-by: hi-rustin <rustin.liu@gmail.com> Co-authored-by: Hayden Stainsby <hds@caffeineconcepts.com>
- Loading branch information
1 parent
28a27fc
commit 4150253
Showing
5 changed files
with
345 additions
and
2 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
//! Example of using the console subscriber with tonic-web. | ||
//! This example requires the `grpc-web` feature to be enabled. | ||
//! Run with: | ||
//! ```sh | ||
//! cargo run --example grpc_web --features grpc-web | ||
//! ``` | ||
use std::{thread, time::Duration}; | ||
|
||
use console_subscriber::{ConsoleLayer, ServerParts}; | ||
use http::header::HeaderName; | ||
use tonic_web::GrpcWebLayer; | ||
use tower_http::cors::{AllowOrigin, CorsLayer}; | ||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; | ||
|
||
const DEFAULT_MAX_AGE: Duration = Duration::from_secs(24 * 60 * 60); | ||
const DEFAULT_EXPOSED_HEADERS: [&str; 3] = | ||
["grpc-status", "grpc-message", "grpc-status-details-bin"]; | ||
const DEFAULT_ALLOW_HEADERS: [&str; 5] = [ | ||
"x-grpc-web", | ||
"content-type", | ||
"x-user-agent", | ||
"grpc-timeout", | ||
"user-agent", | ||
]; | ||
|
||
#[tokio::main] | ||
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> { | ||
let (console_layer, server) = ConsoleLayer::builder().with_default_env().build(); | ||
thread::Builder::new() | ||
.name("subscriber".into()) | ||
.spawn(move || { | ||
// Do not trace anything in this thread. | ||
let _subscriber_guard = | ||
tracing::subscriber::set_default(tracing_core::subscriber::NoSubscriber::default()); | ||
// Custom CORS configuration. | ||
let cors = CorsLayer::new() | ||
.allow_origin(AllowOrigin::mirror_request()) | ||
.allow_credentials(true) | ||
.max_age(DEFAULT_MAX_AGE) | ||
.expose_headers( | ||
DEFAULT_EXPOSED_HEADERS | ||
.iter() | ||
.cloned() | ||
.map(HeaderName::from_static) | ||
.collect::<Vec<HeaderName>>(), | ||
) | ||
.allow_headers( | ||
DEFAULT_ALLOW_HEADERS | ||
.iter() | ||
.cloned() | ||
.map(HeaderName::from_static) | ||
.collect::<Vec<HeaderName>>(), | ||
); | ||
let runtime = tokio::runtime::Builder::new_current_thread() | ||
.enable_all() | ||
.build() | ||
.expect("console subscriber runtime initialization failed"); | ||
runtime.block_on(async move { | ||
let ServerParts { | ||
instrument_server, | ||
aggregator, | ||
.. | ||
} = server.into_parts(); | ||
tokio::spawn(aggregator.run()); | ||
let router = tonic::transport::Server::builder() | ||
// Accept gRPC-Web requests and enable CORS. | ||
.accept_http1(true) | ||
.layer(cors) | ||
.layer(GrpcWebLayer::new()) | ||
.add_service(instrument_server); | ||
let serve = router.serve(std::net::SocketAddr::new( | ||
std::net::IpAddr::V4(std::net::Ipv4Addr::new(127, 0, 0, 1)), | ||
// 6669 is a restricted port on Chrome, so we cannot use it. We use a different port instead. | ||
9999, | ||
)); | ||
serve.await.expect("console subscriber server failed"); | ||
}); | ||
}) | ||
.expect("console subscriber could not spawn thread"); | ||
tracing_subscriber::registry().with(console_layer).init(); | ||
|
||
let task1 = tokio::task::Builder::new() | ||
.name("task1") | ||
.spawn(spawn_tasks(1, 10)) | ||
.unwrap(); | ||
let task2 = tokio::task::Builder::new() | ||
.name("task2") | ||
.spawn(spawn_tasks(10, 30)) | ||
.unwrap(); | ||
|
||
let result = tokio::try_join! { | ||
task1, | ||
task2, | ||
}; | ||
result?; | ||
|
||
Ok(()) | ||
} | ||
|
||
#[tracing::instrument] | ||
async fn spawn_tasks(min: u64, max: u64) { | ||
loop { | ||
for i in min..max { | ||
tracing::trace!(i, "spawning wait task"); | ||
tokio::task::Builder::new() | ||
.name("wait") | ||
.spawn(wait(i)) | ||
.unwrap(); | ||
|
||
let sleep = Duration::from_secs(max) - Duration::from_secs(i); | ||
tracing::trace!(?sleep, "sleeping..."); | ||
tokio::time::sleep(sleep).await; | ||
} | ||
} | ||
} | ||
|
||
#[tracing::instrument] | ||
async fn wait(seconds: u64) { | ||
tracing::debug!("waiting..."); | ||
tokio::time::sleep(Duration::from_secs(seconds)).await; | ||
tracing::trace!("done!"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.