Skip to content
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(console): add support for Unix domain sockets #388

Merged
merged 4 commits into from
Mar 28, 2023
Merged

Conversation

benesch
Copy link
Contributor

@benesch benesch commented Dec 4, 2022

Add support for console connections that use Unix domain sockets rather than TCP.

Fix #296.

@benesch benesch requested a review from a team as a code owner December 4, 2022 13:15
)
.next()
.expect("tokio console could not resolve TOKIO_CONSOLE_BIND"),
);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hawkw do you think this should support UDS addresses too? E.g., by detecting the presence of a leading /, or the absence of a :port?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, my preference is to have this env var only configure a TCP socket, because it seems unfortunate to have a potential typo in the environment variable silently switch from TCP to UDS when that might not actually be desired.

Instead, I think we might want to consider adding a separate environment variable to configure serving over Unix sockets. It would be fine to add that env var in this branch, or in a follow-up PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead, I think we might want to consider adding a separate environment variable to configure serving over Unix sockets. It would be fine to add that env var in this branch, or in a follow-up PR.

I'll leave that to a different PR, then!

console-subscriber/src/builder.rs Show resolved Hide resolved
Copy link
Member

@hawkw hawkw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this! This branch looks like a great start!

I had a few suggestions, most of which I also elaborated on in inline comments:

  1. Unix-only APIs need #[cfg(unix)] attributes so that the console still compiles on Windows.
  2. We should determine whether we want to allow serving the API on both a Unix domain socket and a TCP socket simultaneously, which might be desirable in some cases.
  3. We probably want a separate env-var-based configuration for serving on UDS, if we even want to allow configuring that with the environment variable API.
  4. Let's update this comment (which generates the CLI help text for tokio-console):
    /// The address of a console-enabled process to connect to.
    ///
    /// This may be an IP address and port, or a DNS name.
    ///
    /// [default: http://127.0.0.1:6669]
    so that it also states that the URL can be a Unix Domain Socket if it starts with file://, on unix platforms.

console-subscriber/src/builder.rs Show resolved Hide resolved
)
.next()
.expect("tokio console could not resolve TOKIO_CONSOLE_BIND"),
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, my preference is to have this env var only configure a TCP socket, because it seems unfortunate to have a potential typo in the environment variable silently switch from TCP to UDS when that might not actually be desired.

Instead, I think we might want to consider adding a separate environment variable to configure serving over Unix sockets. It would be fine to add that env var in this branch, or in a follow-up PR.

console-subscriber/src/builder.rs Show resolved Hide resolved
Comment on lines 16 to 20
use tokio::{
net::UnixListener,
sync::{mpsc, oneshot},
};
use tokio_stream::wrappers::UnixListenerStream;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i believe the UnixListener imports won't compile on operating systems other than Unix (e.g., on Windows). we probably need to add a cfg attribute so that this code builds on Windows.

Suggested change
use tokio::{
net::UnixListener,
sync::{mpsc, oneshot},
};
use tokio_stream::wrappers::UnixListenerStream;
use tokio::sync::{mpsc, oneshot};
#[cfg(unix)]
use tokio::net::UnixListener;
#[cfg(unix)]
use tokio_stream::wrappers::UnixListenerStream;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines 469 to 506
/// A Unix socket address.
Unix(PathBuf),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably have #[cfg(unix)] so that the API is only available when building for Unix.

Suggested change
/// A Unix socket address.
Unix(PathBuf),
/// A Unix socket address.
#[cfg(unix)]
Unix(PathBuf),

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines 500 to 548
impl From<PathBuf> for ServerAddr {
fn from(path: PathBuf) -> ServerAddr {
ServerAddr::Unix(path)
}
}

impl<'a> From<&'a Path> for ServerAddr {
fn from(path: &'a Path) -> ServerAddr {
ServerAddr::Unix(path.to_path_buf())
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

similarly, these probably need to be cfg-flagged:

Suggested change
impl From<PathBuf> for ServerAddr {
fn from(path: PathBuf) -> ServerAddr {
ServerAddr::Unix(path)
}
}
impl<'a> From<&'a Path> for ServerAddr {
fn from(path: &'a Path) -> ServerAddr {
ServerAddr::Unix(path.to_path_buf())
}
}
#[cfg(unix)]
impl From<PathBuf> for ServerAddr {
fn from(path: PathBuf) -> ServerAddr {
ServerAddr::Unix(path)
}
}
#[cfg(unix)]
impl<'a> From<&'a Path> for ServerAddr {
fn from(path: &'a Path) -> ServerAddr {
ServerAddr::Unix(path.to_path_buf())
}
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

console-subscriber/src/lib.rs Show resolved Hide resolved
tokio-console/src/conn.rs Show resolved Hide resolved
Comment on lines 86 to 100
None | Some("file") => {
// Dummy endpoint is ignored by the connector.
let endpoint = Endpoint::from_static("http://localhost");
let path = self.target.path().to_owned();
endpoint
.connect_with_connector(tower::service_fn(move |_| {
UnixStream::connect(path.clone())
}))
.await?
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this match arm will need to be #[cfg(unix)], because it uses the Unix-only UnixStream type:

Suggested change
None | Some("file") => {
// Dummy endpoint is ignored by the connector.
let endpoint = Endpoint::from_static("http://localhost");
let path = self.target.path().to_owned();
endpoint
.connect_with_connector(tower::service_fn(move |_| {
UnixStream::connect(path.clone())
}))
.await?
}
#[cfg(unix)]
None | Some("file") => {
// Dummy endpoint is ignored by the connector.
let endpoint = Endpoint::from_static("http://localhost");
let path = self.target.path().to_owned();
endpoint
.connect_with_connector(tower::service_fn(move |_| {
UnixStream::connect(path.clone())
}))
.await?
}

also, we may want to add a separate #[cfg(not(unix))] match arm that prints an error message when trying to connect to a Unix domain socket on non-unix platforms?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -78,7 +82,23 @@ impl Connection {
tokio::time::sleep(backoff).await;
}
let try_connect = async {
let mut client = InstrumentClient::connect(self.target.clone()).await?;
let channel = match self.target.scheme_str() {
None | Some("file") => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm not sure how i feel about treating URLs without a scheme as UDS...is that the generally accepted convention?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there is a generally accepted convention. Some other software uses unix: as the scheme, as in unix://path/to/socket. For now I just removed the treatment of None as UDS; let me know if you'd prefer some other scheme instead.

Copy link
Contributor Author

@benesch benesch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the comments! I've addressed everything, I think!

console-subscriber/src/builder.rs Show resolved Hide resolved
)
.next()
.expect("tokio console could not resolve TOKIO_CONSOLE_BIND"),
);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead, I think we might want to consider adding a separate environment variable to configure serving over Unix sockets. It would be fine to add that env var in this branch, or in a follow-up PR.

I'll leave that to a different PR, then!

console-subscriber/src/builder.rs Show resolved Hide resolved
Comment on lines 469 to 506
/// A Unix socket address.
Unix(PathBuf),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines 500 to 548
impl From<PathBuf> for ServerAddr {
fn from(path: PathBuf) -> ServerAddr {
ServerAddr::Unix(path)
}
}

impl<'a> From<&'a Path> for ServerAddr {
fn from(path: &'a Path) -> ServerAddr {
ServerAddr::Unix(path.to_path_buf())
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines 16 to 20
use tokio::{
net::UnixListener,
sync::{mpsc, oneshot},
};
use tokio_stream::wrappers::UnixListenerStream;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

console-subscriber/src/lib.rs Show resolved Hide resolved
Comment on lines 86 to 100
None | Some("file") => {
// Dummy endpoint is ignored by the connector.
let endpoint = Endpoint::from_static("http://localhost");
let path = self.target.path().to_owned();
endpoint
.connect_with_connector(tower::service_fn(move |_| {
UnixStream::connect(path.clone())
}))
.await?
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -78,7 +82,23 @@ impl Connection {
tokio::time::sleep(backoff).await;
}
let try_connect = async {
let mut client = InstrumentClient::connect(self.target.clone()).await?;
let channel = match self.target.scheme_str() {
None | Some("file") => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there is a generally accepted convention. Some other software uses unix: as the scheme, as in unix://path/to/socket. For now I just removed the treatment of None as UDS; let me know if you'd prefer some other scheme instead.

@benesch benesch force-pushed the uds branch 2 times, most recently from 560e0c4 to bac69ec Compare December 11, 2022 20:32
@benesch
Copy link
Contributor Author

benesch commented Dec 16, 2022

@hawkw anything you're waiting on me on?

@hawkw
Copy link
Member

hawkw commented Dec 16, 2022

@hawkw anything you're waiting on me on?

Nope, sorry, I just hadn't gotten the chance to give this a review yet. I'll try to do one today!

@benesch
Copy link
Contributor Author

benesch commented Dec 16, 2022

No problem! Just wanted to make sure I hadn't missed something. Feel free to just push directly at the branch (or open a new PR, whatever) if easier.

Copy link
Member

@hawkw hawkw left a 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 some last suggestions for improving the documentation. Once those are addressed, though, I'll be very happy to merge this!

console-subscriber/examples/uds.rs Outdated Show resolved Hide resolved
console-subscriber/src/builder.rs Show resolved Hide resolved
@@ -138,7 +140,7 @@ impl Builder {
/// defaults.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this documentation should be updated to state that the provided address can be a TCP address, or (on Unix systems) a UDS address. It would be nice to show examples of both usages in this method's documentation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

console-subscriber/src/builder.rs Show resolved Hide resolved
@hawkw
Copy link
Member

hawkw commented Dec 16, 2022

It looks like, because additional documentation was added to the CLI help text, the documentation needs to be regenerated (which is why CI is failing): https://github.com/tokio-rs/console/actions/runs/3715257647/jobs/6300201144#step:8:150

Copy link
Contributor Author

@benesch benesch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, thanks for the second pass! Should be ready to go.

@@ -138,7 +140,7 @@ impl Builder {
/// defaults.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

console-subscriber/src/builder.rs Show resolved Hide resolved
console-subscriber/src/builder.rs Show resolved Hide resolved
console-subscriber/examples/uds.rs Outdated Show resolved Hide resolved
@benesch
Copy link
Contributor Author

benesch commented Dec 27, 2022

Sorry to be a bother, @hawkw, but could you trigger a CI run?

@hawkw
Copy link
Member

hawkw commented Dec 27, 2022

Sorry to be a bother, @hawkw, but could you trigger a CI run?

Yup, sorry, I hadn't realized you pushed more commits. Thanks for the reminder!

Copy link
Member

@hawkw hawkw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great! Thanks again for working on it!

I'm going to merge this as soon as CI passes. :)

@hawkw hawkw enabled auto-merge (squash) December 27, 2022 20:26
Add support for console connections that use Unix domain sockets rather
than TCP.

Fix tokio-rs#296.
auto-merge was automatically disabled December 28, 2022 04:43

Head branch was pushed to by a user without write access

@benesch
Copy link
Contributor Author

benesch commented Dec 28, 2022

Thank you! I fixed the UDS example not compiling on Windows with some conditional compilation. Didn't see a better way. There's no equivalent of required-features for an example (e.g., required-platform) in Cargo.toml.

Also looks like there's a clippy failure that's unrelated to this PR. Want me to push up a fix in this PR, or would you rather address separately?

@benesch
Copy link
Contributor Author

benesch commented Jan 7, 2023

Also looks like there's a clippy failure that's unrelated to this PR. Want me to push up a fix in this PR, or would you rather address separately?

Gentle ping on this question, @hawkw!

@hawkw hawkw enabled auto-merge (squash) February 6, 2023 18:46
@hawkw hawkw merged commit bff8b8a into tokio-rs:main Mar 28, 2023
@benesch
Copy link
Contributor Author

benesch commented Mar 29, 2023

Thanks, Eliza! Excited to have this merged.

hawkw added a commit that referenced this pull request Sep 29, 2023
Add support for console connections that use Unix domain sockets rather
than TCP.

Closes #296.

Co-authored-by: Eliza Weisman <eliza@buoyant.io>
hawkw added a commit that referenced this pull request Sep 29, 2023
# Changelog

All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## console-subscriber-v0.2.0 - (2023-09-29)

[0b0c1af](https://github.com/tokio-rs/console/commit/0b0c1aff18c3260d3a45a78f6c0d6f4206af1cbb)...[0b0c1af](https://github.com/tokio-rs/console/commit/0b0c1aff18c3260d3a45a78f6c0d6f4206af1cbb)

### <a id = "console-subscriber-v0.2.0-breaking"></a>Breaking Changes
- **Update Tonic and Prost dependencies ([#364](#364 ([f9b8e03](https://github.com/tokio-rs/console/commit/f9b8e03bd7ee1d0edb441c94a93a350d5b06ed3b))<br />This commit updates the public dependencies `prost` and `tonic` to
semver-incompatible versions (v0.11.0 and v0.8.0, respectively). This is
a breaking change for users who are integrating the `console-api` protos
with their own `tonic` servers or clients.
- **Update `tonic` to v0.10 and increase MSRV to 1.64 ([#464](#464 ([96e62c8](https://github.com/tokio-rs/console/commit/96e62c83ef959569bb062dc8fee98fa2b2461e8d))<br />This is a breaking change for users of `console-api` and
`console-subscriber`, as it changes the public `tonic` dependency to a
semver-incompatible version. This breaks compatibility with `tonic`
0.9.x and `prost` 0.11.x.

### Added

- [**breaking**](#console-subscriber-v0.2.0-breaking) Update Tonic and Prost dependencies ([#364](#364)) ([f9b8e03](f9b8e03))
- Add support for Unix domain sockets ([#388](#388)) ([a944dbc](a944dbc), closes [#296](#296))
- Add scheduled time per task ([#406](#406)) ([f280df9](f280df9))
- Add task scheduled times histogram ([#409](#409)) ([d92a399](d92a399))
- Update `tonic` to 0.9 ([#420](#420)) ([48af1ee](48af1ee))
- Update MSRV to Rust 1.60.0 ([b18ee47](b18ee47))
- Expose server parts ([#451](#451)) ([e51ac5a](e51ac5a))
- Add cfg `console_without_tokio_unstable` ([#446](#446)) ([7ed6673](7ed6673))
- Add warning for tasks that never yield ([#439](#439)) ([d05fa9e](d05fa9e))
- [**breaking**](#console-subscriber-v0.2.0-breaking) Update `tonic` to v0.10 and increase MSRV to 1.64 ([#464](#464)) ([96e62c8](96e62c8))

### Documented

- Fix unclosed code block ([#463](#463)) ([362bdbe](362bdbe))
- Update MSRV version docs to 1.64 ([#467](#467)) ([94a5a51](94a5a51))

### Fixed

- Fix build on tokio 1.21.0 ([#374](#374)) ([c34ac2d](c34ac2d))
- Fix off-by-one indexing for `callsites` ([#391](#391)) ([43891ab](43891ab))
- Bump minimum Tokio version ([#397](#397)) ([bbb8f25](bbb8f25), fixes [#386](#386))
- Fix self wakes count ([#430](#430)) ([d308935](d308935))
- Remove clock skew warning in `start_poll` ([#434](#434)) ([4a88b28](4a88b28))
- Do not report excessive polling ([#378](#378)) ([#440](#440)) ([8b483bf](8b483bf), closes [#378](#378))
- Correct retain logic ([#447](#447)) ([36ffc51](36ffc51))

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
hawkw added a commit that referenced this pull request Sep 29, 2023
# Changelog

All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## tokio-console-v0.1.10 - (2023-09-29)

[7d009f8](https://github.com/tokio-rs/console/commit/7d009f87120ce0c89f5f9c5311f05b6756ca770f)...[7d009f8](https://github.com/tokio-rs/console/commit/7d009f87120ce0c89f5f9c5311f05b6756ca770f)

### <a id = "tokio-console-v0.1.10-breaking"></a>Breaking Changes
- **Update Tonic and Prost dependencies ([#364](#364 ([f9b8e03](https://github.com/tokio-rs/console/commit/f9b8e03bd7ee1d0edb441c94a93a350d5b06ed3b))<br />This commit updates the public dependencies `prost` and `tonic` to
semver-incompatible versions (v0.11.0 and v0.8.0, respectively). This is
a breaking change for users who are integrating the `console-api` protos
with their own `tonic` servers or clients.
- **Update `tonic` to v0.10 and increase MSRV to 1.64 ([#464](#464 ([96e62c8](https://github.com/tokio-rs/console/commit/96e62c83ef959569bb062dc8fee98fa2b2461e8d))<br />This is a breaking change for users of `console-api` and
`console-subscriber`, as it changes the public `tonic` dependency to a
semver-incompatible version. This breaks compatibility with `tonic`
0.9.x and `prost` 0.11.x.

### Added

- [**breaking**](#tokio-console-v0.1.10-breaking) Update Tonic and Prost dependencies ([#364](#364)) ([f9b8e03](f9b8e03))
- Only suggest opening issues for panics ([#365](#365)) ([da2a89c](da2a89c))
- Init error handling before subcmds ([#365](#365)) ([ec66eda](ec66eda))
- Filter out boring frames in backtraces ([#365](#365)) ([95a5e54](95a5e54))
- Include config options in autogenerated issues ([#365](#365)) ([3244a1f](3244a1f))
- Reduce decimal digits in UI ([#402](#402)) ([c13085e](c13085e))
- Use tokio task ids in task views ([#403](#403)) ([f5b06d2](f5b06d2))
- Add support for Unix domain sockets ([#388](#388)) ([a944dbc](a944dbc), closes [#296](#296))
- Add scheduled time per task ([#406](#406)) ([f280df9](f280df9))
- Add task scheduled times histogram ([#409](#409)) ([d92a399](d92a399))
- Update `tonic` to 0.9 ([#420](#420)) ([48af1ee](48af1ee))
- Update MSRV to Rust 1.60.0 ([b18ee47](b18ee47))
- Migrate to `ratatui` and update `crossterm` ([#425](#425)) ([b209dd6](b209dd6))
- Help view modal ([#432](#432)) ([359a4e7](359a4e7))
- Add way to inspect details of task from resource view ([#449](#449)) ([132ed4e](132ed4e), closes [#448](#448))
- Add warning for tasks that never yield ([#439](#439)) ([d05fa9e](d05fa9e))
- [**breaking**](#tokio-console-v0.1.10-breaking) Update `tonic` to v0.10 and increase MSRV to 1.64 ([#464](#464)) ([96e62c8](96e62c8))

### Documented

- Update screenshots in README ([#419](#419)) ([e9bcd67](e9bcd67))
- Revert "update screenshots in README ([#419](#419))" ([993a3d9](993a3d9))
- Update screenshots in README ([#421](#421)) ([8a27f96](8a27f96))
- Add column descriptions for all tables ([#431](#431)) ([e3cf82b](e3cf82b))
- Update MSRV version docs to 1.64 ([#467](#467)) ([94a5a51](94a5a51))

### Fixed

- Fix ascii-only flipped input ([#377](#377)) ([652ac34](652ac34))
- Declare `tokio-console` bin as `default-run` ([#379](#379)) ([9ce60ec](9ce60ec))
- Make `retain_for` default to 6s if not specfied ([#383](#383)) ([0a6012b](0a6012b), fixes [#382](#382))
- Enable view-switching keystrokes on details views ([#387](#387)) ([f417d7a](f417d7a))
- Fix `ViewOptions` default lang' ([#394](#394)) ([a1cf1b8](a1cf1b8), fixes [#393](#393))
- Remove `tracing-subscriber` 0.2 from dependencies ([#404](#404)) ([768534a](768534a))
- Fix calculation of busy time during poll ([#405](#405)) ([e2c536a](e2c536a))
- Remove histogram minimum count ([#424](#424)) ([02cf8a6](02cf8a6))
- Remove trailing space from task/resource location ([#443](#443)) ([90e5918](90e5918))
- Make long locations readable ([#441](#441)) ([9428d7f](9428d7f), closes [#411](#411))
- Fix task detail view Id to display remote tokio::task::Id ([#455](#455)) ([70c3952](70c3952))

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Currently, the console only supports TCP, is there a plan to support Unix Domain Socket?
2 participants