Skip to content

Commit cafa93d

Browse files
authored
tracing: Split HTML-formatting into admin module (#1025)
The tracing crate is fairly core to all of our functionality, and so it's preferable to avoid pulling in HTML-specific dependencies here. In order to keep the tracing crate limited to only tracing-related functionality, this change moves the HTTP handlers to the `app::core::admin`, which includes the rest of the HTTP serving logic used by the admin server. There is no functional change.
1 parent a9f4012 commit cafa93d

File tree

15 files changed

+183
-645
lines changed

15 files changed

+183
-645
lines changed

Cargo.lock

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -416,9 +416,9 @@ dependencies = [
416416

417417
[[package]]
418418
name = "html-escape"
419-
version = "0.2.6"
419+
version = "0.2.9"
420420
source = "registry+https://github.com/rust-lang/crates.io-index"
421-
checksum = "d348900ce941b7474395ba922ed3735a517df4546a2939ddb416ce85eeaa988e"
421+
checksum = "816ea801a95538fc5f53c836697b3f8b64a9d664c4f0b91efe1fe7c92e4dbcb7"
422422
dependencies = [
423423
"utf8-width",
424424
]
@@ -639,6 +639,7 @@ version = "0.1.0"
639639
dependencies = [
640640
"bytes",
641641
"futures",
642+
"html-escape",
642643
"http",
643644
"http-body",
644645
"hyper",
@@ -689,6 +690,7 @@ dependencies = [
689690
"pin-project",
690691
"prost-types",
691692
"regex",
693+
"serde_json",
692694
"thiserror",
693695
"tokio",
694696
"tokio-stream",
@@ -1422,12 +1424,7 @@ dependencies = [
14221424
name = "linkerd-tracing"
14231425
version = "0.1.0"
14241426
dependencies = [
1425-
"bytes",
1426-
"html-escape",
1427-
"http",
1428-
"hyper",
14291427
"linkerd-error",
1430-
"serde_json",
14311428
"tokio",
14321429
"tokio-trace",
14331430
"tracing",
@@ -2487,9 +2484,9 @@ dependencies = [
24872484

24882485
[[package]]
24892486
name = "utf8-width"
2490-
version = "0.1.4"
2487+
version = "0.1.5"
24912488
source = "registry+https://github.com/rust-lang/crates.io-index"
2492-
checksum = "9071ac216321a4470a69fb2b28cfc68dcd1a39acd877c8be8e014df6772d8efa"
2489+
checksum = "7cf7d77f457ef8dfa11e4cd5933c5ddb5dc52a94664071951219a97710f0a32b"
24932490

24942491
[[package]]
24952492
name = "want"

linkerd/addr/fuzz/Cargo.lock

Lines changed: 0 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -168,15 +168,6 @@ dependencies = [
168168
"libc",
169169
]
170170

171-
[[package]]
172-
name = "html-escape"
173-
version = "0.2.9"
174-
source = "registry+https://github.com/rust-lang/crates.io-index"
175-
checksum = "816ea801a95538fc5f53c836697b3f8b64a9d664c4f0b91efe1fe7c92e4dbcb7"
176-
dependencies = [
177-
"utf8-width",
178-
]
179-
180171
[[package]]
181172
name = "http"
182173
version = "0.2.4"
@@ -188,51 +179,6 @@ dependencies = [
188179
"itoa",
189180
]
190181

191-
[[package]]
192-
name = "http-body"
193-
version = "0.4.2"
194-
source = "registry+https://github.com/rust-lang/crates.io-index"
195-
checksum = "60daa14be0e0786db0f03a9e57cb404c9d756eed2b6c62b9ea98ec5743ec75a9"
196-
dependencies = [
197-
"bytes",
198-
"http",
199-
"pin-project-lite",
200-
]
201-
202-
[[package]]
203-
name = "httparse"
204-
version = "1.4.1"
205-
source = "registry+https://github.com/rust-lang/crates.io-index"
206-
checksum = "f3a87b616e37e93c22fb19bcd386f02f3af5ea98a25670ad0fce773de23c5e68"
207-
208-
[[package]]
209-
name = "httpdate"
210-
version = "1.0.0"
211-
source = "registry+https://github.com/rust-lang/crates.io-index"
212-
checksum = "05842d0d43232b23ccb7060ecb0f0626922c21f30012e97b767b30afd4a5d4b9"
213-
214-
[[package]]
215-
name = "hyper"
216-
version = "0.14.7"
217-
source = "registry+https://github.com/rust-lang/crates.io-index"
218-
checksum = "1e5f105c494081baa3bf9e200b279e27ec1623895cd504c7dbef8d0b080fcf54"
219-
dependencies = [
220-
"bytes",
221-
"futures-channel",
222-
"futures-core",
223-
"futures-util",
224-
"http",
225-
"http-body",
226-
"httparse",
227-
"httpdate",
228-
"itoa",
229-
"pin-project",
230-
"tokio",
231-
"tower-service",
232-
"tracing",
233-
"want",
234-
]
235-
236182
[[package]]
237183
name = "instant"
238184
version = "0.1.9"
@@ -318,12 +264,7 @@ dependencies = [
318264
name = "linkerd-tracing"
319265
version = "0.1.0"
320266
dependencies = [
321-
"bytes",
322-
"html-escape",
323-
"http",
324-
"hyper",
325267
"linkerd-error",
326-
"serde_json",
327268
"tokio",
328269
"tokio-trace",
329270
"tracing",
@@ -405,26 +346,6 @@ dependencies = [
405346
"winapi",
406347
]
407348

408-
[[package]]
409-
name = "pin-project"
410-
version = "1.0.7"
411-
source = "registry+https://github.com/rust-lang/crates.io-index"
412-
checksum = "c7509cc106041c40a4518d2af7a61530e1eed0e6285296a3d8c5472806ccc4a4"
413-
dependencies = [
414-
"pin-project-internal",
415-
]
416-
417-
[[package]]
418-
name = "pin-project-internal"
419-
version = "1.0.7"
420-
source = "registry+https://github.com/rust-lang/crates.io-index"
421-
checksum = "48c950132583b500556b1efd71d45b319029f2b71518d979fcc208e16b42426f"
422-
dependencies = [
423-
"proc-macro2",
424-
"quote",
425-
"syn",
426-
]
427-
428349
[[package]]
429350
name = "pin-project-lite"
430351
version = "0.2.6"
@@ -635,12 +556,6 @@ dependencies = [
635556
"tracing-subscriber",
636557
]
637558

638-
[[package]]
639-
name = "tower-service"
640-
version = "0.3.1"
641-
source = "registry+https://github.com/rust-lang/crates.io-index"
642-
checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
643-
644559
[[package]]
645560
name = "tracing"
646561
version = "0.1.25"
@@ -716,12 +631,6 @@ dependencies = [
716631
"tracing-serde",
717632
]
718633

719-
[[package]]
720-
name = "try-lock"
721-
version = "0.2.3"
722-
source = "registry+https://github.com/rust-lang/crates.io-index"
723-
checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
724-
725634
[[package]]
726635
name = "unicode-xid"
727636
version = "0.2.1"
@@ -734,22 +643,6 @@ version = "0.7.1"
734643
source = "registry+https://github.com/rust-lang/crates.io-index"
735644
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
736645

737-
[[package]]
738-
name = "utf8-width"
739-
version = "0.1.5"
740-
source = "registry+https://github.com/rust-lang/crates.io-index"
741-
checksum = "7cf7d77f457ef8dfa11e4cd5933c5ddb5dc52a94664071951219a97710f0a32b"
742-
743-
[[package]]
744-
name = "want"
745-
version = "0.3.0"
746-
source = "registry+https://github.com/rust-lang/crates.io-index"
747-
checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
748-
dependencies = [
749-
"log",
750-
"try-lock",
751-
]
752-
753646
[[package]]
754647
name = "wasm-bindgen"
755648
version = "0.2.73"

linkerd/app/core/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ independently of the inbound and outbound proxy logic.
1515
[dependencies]
1616
bytes = "1"
1717
http = "0.2"
18+
html-escape = "0.2"
1819
http-body = "0.4"
1920
hyper = { version = "0.14.2", features = ["http1", "http2"] }
2021
futures = "0.3.15"
@@ -35,7 +36,6 @@ linkerd-error-respond = { path = "../../error-respond" }
3536
linkerd-exp-backoff = { path = "../../exp-backoff" }
3637
linkerd-http-classify = { path = "../../http-classify" }
3738
linkerd-http-metrics = { path = "../../http-metrics" }
38-
3939
linkerd-http-retry = { path = "../../http-retry" }
4040
linkerd-identity = { path = "../../identity" }
4141
linkerd-io = { path = "../../io" }
@@ -63,6 +63,7 @@ linkerd-stack-tracing = { path = "../../stack/tracing" }
6363
linkerd-tls = { path = "../../tls" }
6464
linkerd-trace-context = { path = "../../trace-context" }
6565
regex = "1.0.0"
66+
serde_json = "1"
6667
thiserror = "1.0"
6768
tokio = { version = "1", features = ["macros", "sync", "parking_lot"]}
6869
tokio-stream = { version = "0.1.5", features = ["time"] }

linkerd/app/core/src/admin/level.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
use hyper::{
2+
body::{Buf, HttpBody},
3+
Body,
4+
};
5+
use linkerd_error::Error;
6+
use linkerd_tracing::level::Handle;
7+
use std::io;
8+
9+
pub(super) async fn serve<B>(
10+
level: &Handle,
11+
req: http::Request<B>,
12+
) -> Result<http::Response<Body>, Error>
13+
where
14+
B: HttpBody,
15+
B::Error: Into<Error>,
16+
{
17+
let mk_rsp = |status: http::StatusCode, body: Body| -> http::Response<Body> {
18+
http::Response::builder()
19+
.status(status)
20+
.body(body)
21+
.expect("builder with known status code must not fail")
22+
};
23+
24+
let rsp = match *req.method() {
25+
http::Method::GET => {
26+
let level = level.current()?;
27+
mk_rsp(http::StatusCode::OK, level.into())
28+
}
29+
30+
http::Method::PUT => {
31+
let body = hyper::body::aggregate(req.into_body())
32+
.await
33+
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
34+
match level.set_from(body.chunk()) {
35+
Ok(()) => mk_rsp(http::StatusCode::NO_CONTENT, Body::empty()),
36+
Err(error) => {
37+
tracing::warn!(%error, "Setting log level failed");
38+
mk_rsp(http::StatusCode::BAD_REQUEST, error.into())
39+
}
40+
}
41+
}
42+
43+
_ => http::Response::builder()
44+
.status(http::StatusCode::METHOD_NOT_ALLOWED)
45+
.header("allow", "GET")
46+
.header("allow", "PUT")
47+
.body(Body::empty())
48+
.expect("builder with known status code must not fail"),
49+
};
50+
51+
Ok(rsp)
52+
}

linkerd/app/core/src/admin/mod.rs

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ use std::{
2727
};
2828
use tokio::sync::mpsc;
2929

30+
mod level;
3031
mod readiness;
32+
mod tasks;
3133

3234
pub use self::readiness::{Latch, Readiness};
3335

@@ -174,19 +176,25 @@ where
174176
"/ready" => Box::pin(future::ok(self.ready_rsp())),
175177
"/metrics" => {
176178
let rsp = self.metrics.serve(req).unwrap_or_else(|error| {
177-
tracing::error!(%error, "Failed to format metrics");
179+
::tracing::error!(%error, "Failed to format metrics");
178180
Self::internal_error_rsp(error)
179181
});
180182
Box::pin(future::ok(rsp))
181183
}
182184
"/proxy-log-level" => {
183185
if Self::client_is_localhost(&req) {
184-
let handle = self.tracing.clone();
186+
let level = self.tracing.level().cloned();
185187
Box::pin(async move {
186-
handle.serve_level(req).await.or_else(|error| {
187-
tracing::error!(%error, "Failed to get/set tracing level");
188-
Ok(Self::internal_error_rsp(error))
189-
})
188+
let rsp = match level {
189+
Some(level) => {
190+
level::serve(&level, req).await.unwrap_or_else(|error| {
191+
tracing::error!(%error, "Failed to get/set tracing level");
192+
Self::internal_error_rsp(error)
193+
})
194+
}
195+
None => Self::not_found(),
196+
};
197+
Ok(rsp)
190198
})
191199
} else {
192200
Box::pin(future::ok(Self::forbidden_not_localhost()))
@@ -205,13 +213,14 @@ where
205213
}
206214
path if path.starts_with("/tasks") => {
207215
if Self::client_is_localhost(&req) {
208-
let handle = self.tracing.clone();
209-
Box::pin(async move {
210-
handle.serve_tasks(req).await.or_else(|error| {
216+
let rsp = match self.tracing.tasks() {
217+
Some(tasks) => tasks::serve(tasks, req).unwrap_or_else(|error| {
211218
tracing::error!(%error, "Failed to fetch tasks");
212-
Ok(Self::internal_error_rsp(error))
213-
})
214-
})
219+
Self::internal_error_rsp(error)
220+
}),
221+
None => Self::not_found(),
222+
};
223+
Box::pin(future::ok(rsp))
215224
} else {
216225
Box::pin(future::ok(Self::forbidden_not_localhost()))
217226
}

0 commit comments

Comments
 (0)