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

telemetry: introduce orb-telemetry crate and use it in orb-ui #258

Merged
merged 1 commit into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 7 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,19 @@ members = [
"hil",
"mcu-interface",
"mcu-util",
"ui",
"ui/cone",
"ui/pid",
"ui/sound",
"ui/uart",
"qr-link",
"security-utils",
"seek-camera/sys",
"seek-camera/wrapper",
"slot-ctrl",
"supervisor",
"telemetry",
"thermal-cam-ctrl",
"ui",
"ui/cone",
"ui/pid",
"ui/sound",
"ui/uart",
"update-agent",
"update-agent/core",
"update-verifier",
Expand Down Expand Up @@ -81,6 +82,7 @@ orb-build-info.path = "build-info"
orb-const-concat.path = "const-concat"
orb-security-utils.path = "security-utils"
orb-slot-ctrl.path = "slot-ctrl"
orb-telemetry.path = "telemetry"
orb-update-agent-core.path = "update-agent/core"
orb-zbus-proxies.path = "zbus-proxies"

Expand Down
23 changes: 23 additions & 0 deletions telemetry/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[package]
name = "orb-telemetry"
version = "0.0.0"
description = "Standardized telemetry setup for the orb"
authors = ["Ryan Butler <[email protected]>"]
publish = false

edition.workspace = true
license.workspace = true
repository.workspace = true
rust-version.workspace = true

[dependencies]
tracing-journald.workspace = true
tracing-subscriber.workspace = true
tracing.workspace = true

[target.'cfg(tokio_unstable)'.dependencies]
console-subscriber.workspace = true

[lints.rust.unexpected_cfgs]
level = "warn"
check-cfg = ['cfg(tokio_unstable)']
84 changes: 84 additions & 0 deletions telemetry/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
use std::io::IsTerminal as _;

use tracing::level_filters::LevelFilter;
use tracing_subscriber::{
layer::SubscriberExt as _, util::SubscriberInitExt as _, EnvFilter,
};

#[derive(Debug)]
pub struct TelemetryConfig {
syslog_identifier: Option<String>,
global_filter: EnvFilter,
}

impl TelemetryConfig {
/// Provides all required arguments for telemetry configuration.
/// - `log_identifier` will be used for journald, if appropriate.
#[expect(clippy::new_without_default, reason = "may add required args later")]
pub fn new() -> Self {
Self {
syslog_identifier: None,
global_filter: EnvFilter::builder()
.with_default_directive(LevelFilter::INFO.into())
.from_env_lossy(),
}
}

/// Enables journald, and uses the provided syslog identifier.
///
/// If you run the application in a tty, stderr will be used instead.
pub fn with_journald(self, syslog_identifier: &str) -> Self {
Self {
syslog_identifier: Some(syslog_identifier.to_owned()),
..self
}
}

/// Override the global filter to a custom filter.
/// Only do this if actually necessary to deviate from the orb's defaults.
pub fn with_global_filter(self, filter: EnvFilter) -> Self {
Self {
global_filter: filter,
..self
}
}

/// Initializes the telemetry config. Call this only once, at the beginning of the
/// program.
///
/// Calling this more than once or when another tracing subscriber is registered
/// will cause a panic.
Comment on lines +49 to +50
Copy link
Collaborator

Choose a reason for hiding this comment

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

should we prevent the panic? return an error instead?

Copy link
Collaborator Author

@TheButlah TheButlah Oct 23, 2024

Choose a reason for hiding this comment

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

I think the panic is preferred. This type of code is once-only initialization code. If we called it more than once we should abort.

Generally errors are more for things that actually are expected to happen and need to be robustly handled. But someone calling this twice is better immediately slapped on the wrist and told to change their code.

pub fn init(self) {
let registry = tracing_subscriber::registry();
// The type is only there to get it to compile.
let tokio_console_layer: Option<tracing_subscriber::layer::Identity> = None;
#[cfg(tokio_unstable)]
let tokio_console_layer = console_subscriber::spawn();
// Checking for a terminal helps detect if we are running under systemd.
let journald_layer = if !std::io::stderr().is_terminal() {
self.syslog_identifier.and_then(|syslog_identifier| {
tracing_journald::layer()
.inspect_err(|err| {
eprintln!(
"failed connecting to journald socket. \
will write to stderr: {err}"
);
})
.map(|layer| layer.with_syslog_identifier(syslog_identifier))
.ok()
})
} else {
None
};
let stderr_layer = journald_layer
.is_none()
.then(|| tracing_subscriber::fmt::layer().with_writer(std::io::stderr));
assert!(stderr_layer.is_some() || journald_layer.is_some());
registry
.with(tokio_console_layer)
.with(stderr_layer)
.with(journald_layer)
.with(self.global_filter)
.init();
}
}
6 changes: 2 additions & 4 deletions ui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ rust-version.workspace = true
[dependencies]
async-trait = "0.1.74"
clap.workspace = true
color-eyre.workspace = true
dashmap = "5.5.3"
derive_more.workspace = true
eyre.workspace = true
Expand All @@ -21,6 +22,7 @@ orb-build-info.path = "../build-info"
orb-messages.workspace = true
orb-rgb.path = "rgb"
orb-sound.path = "sound"
orb-telemetry.workspace = true
orb-uart.path = "uart"
pid.path = "pid"
prost = "0.12.3"
Expand All @@ -29,13 +31,9 @@ serde.workspace = true
serde_json = "1.0.108"
tokio-stream = "0.1.14"
tokio.workspace = true
tracing-subscriber.workspace = true
tracing.workspace = true
zbus.workspace = true

[target.'cfg(tokio_unstable)'.dependencies]
console-subscriber.workspace = true

[build-dependencies]
orb-build-info = { path = "../build-info", features = ["build-script"] }

Expand Down
19 changes: 5 additions & 14 deletions ui/examples/ui-replay.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
use chrono::{DateTime, Utc};
use clap::Parser;
use eyre::{Context, ContextCompat, Result};
use color_eyre::{eyre::WrapErr, Result};
use eyre::OptionExt;
use std::fs::File;
use std::io;
use std::io::BufRead;
use std::str::FromStr;
use tokio::time::sleep;
use tracing::level_filters::LevelFilter;
use tracing::{debug, info, warn};
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::util::SubscriberInitExt;
use tracing_subscriber::{fmt, EnvFilter};
use zbus::Connection;

const RECORDS_FILE: &str = "worldcoin-ui-logs.txt";
Expand Down Expand Up @@ -56,7 +53,7 @@ impl FromStr for EventRecord {
// split line to take everything after "UI event:"
let (_, event) = line
.split_once("UI event: ")
.wrap_err(format!("Unable to split line: {}", line))?;
.ok_or_eyre(format!("Unable to split line: {}", line))?;
let event = event.to_string();
match timestamp_str.parse::<DateTime<Utc>>() {
Ok(timestamp) => {
Expand All @@ -70,14 +67,8 @@ impl FromStr for EventRecord {

#[tokio::main]
async fn main() -> Result<()> {
tracing_subscriber::registry()
.with(fmt::layer())
.with(
EnvFilter::builder()
.with_default_directive(LevelFilter::INFO.into())
.from_env_lossy(),
)
.init();
color_eyre::install()?;
orb_telemetry::TelemetryConfig::new().init();

let args = Args::parse();
let connection = Connection::session().await?;
Expand Down
17 changes: 4 additions & 13 deletions ui/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ use futures::channel::mpsc;
use orb_build_info::{make_build_info, BuildInfo};
use tokio::time;
use tracing::debug;
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::util::SubscriberInitExt;
use tracing_subscriber::{filter::LevelFilter, fmt, EnvFilter};

use crate::engine::{Engine, Event, EventChannel, OperatingMode};
use crate::observer::listen;
Expand All @@ -29,6 +26,7 @@ pub mod sound;

const INPUT_CAPACITY: usize = 100;
const BUILD_INFO: BuildInfo = make_build_info!();
const SYSLOG_IDENTIFIER: &str = "worldcoin-ui";

/// Utility args
#[derive(Parser, Debug)]
Expand Down Expand Up @@ -112,16 +110,9 @@ async fn get_hw_version() -> Result<Hardware> {

#[tokio::main]
async fn main() -> Result<()> {
let registry = tracing_subscriber::registry();
#[cfg(tokio_unstable)]
let registry = registry.with(console_subscriber::spawn());
registry
.with(fmt::layer())
.with(
EnvFilter::builder()
.with_default_directive(LevelFilter::INFO.into())
.from_env_lossy(),
)
color_eyre::install()?;
orb_telemetry::TelemetryConfig::new()
.with_journald(SYSLOG_IDENTIFIER)
.init();

let args = Args::parse();
Expand Down
Loading