forked from mirrors/jj
perf: add chrome tracing layer
This generates profiles in the Google Chrome JSON tracing format. They can be opened in Chrome's `chrome://tracing` page or in tools like https://ui.perfetto.dev. Enable by running e.g. `JJ_TRACE=1 cargo run -- status`.
This commit is contained in:
parent
e618b2c14f
commit
6f15a27079
4 changed files with 88 additions and 3 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -8,3 +8,6 @@ result
|
|||
|
||||
# Editor specific ignores
|
||||
.idea
|
||||
|
||||
# Generated by setting `JJ_TRACE` environment variable.
|
||||
jj-trace-*.json
|
||||
|
|
32
Cargo.lock
generated
32
Cargo.lock
generated
|
@ -1035,6 +1035,7 @@ dependencies = [
|
|||
"timeago",
|
||||
"toml_edit",
|
||||
"tracing",
|
||||
"tracing-chrome",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
|
@ -2261,6 +2262,17 @@ dependencies = [
|
|||
"syn 2.0.23",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-chrome"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "496b3cd5447f7ff527bbbf19b071ad542a000adf297d4127078b4dfdb931f41a"
|
||||
dependencies = [
|
||||
"serde_json",
|
||||
"tracing-core",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.30"
|
||||
|
@ -2268,6 +2280,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"valuable",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-log"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"log",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2281,9 +2305,11 @@ dependencies = [
|
|||
"once_cell",
|
||||
"regex",
|
||||
"sharded-slab",
|
||||
"smallvec",
|
||||
"thread_local",
|
||||
"tracing",
|
||||
"tracing-core",
|
||||
"tracing-log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2353,6 +2379,12 @@ version = "0.2.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
|
|
|
@ -62,6 +62,7 @@ thiserror = "1.0.43"
|
|||
timeago = { version = "0.4.1", default-features = false }
|
||||
toml_edit = { version = "0.19.12", features = ["serde"] }
|
||||
tracing = "0.1.37"
|
||||
tracing-chrome = "0.7.1"
|
||||
tracing-subscriber = { version = "0.3.17", default-features = false, features = ["std", "ansi", "env-filter", "fmt"] }
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
|
|
|
@ -23,6 +23,7 @@ use std::process::ExitCode;
|
|||
use std::rc::Rc;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
use std::time::SystemTime;
|
||||
|
||||
use clap::builder::{NonEmptyStringValueParser, TypedValueParser, ValueParserFactory};
|
||||
use clap::{Arg, ArgAction, ArgMatches, Command, FromArgMatches};
|
||||
|
@ -62,6 +63,7 @@ use jj_lib::{dag_walk, file_util, git, revset};
|
|||
use once_cell::unsync::OnceCell;
|
||||
use thiserror::Error;
|
||||
use toml_edit;
|
||||
use tracing_chrome::ChromeLayerBuilder;
|
||||
use tracing_subscriber::prelude::*;
|
||||
|
||||
use crate::config::{
|
||||
|
@ -332,6 +334,20 @@ impl From<GitConfigParseError> for CommandError {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct ChromeTracingFlushGuard {
|
||||
_inner: Option<Rc<tracing_chrome::FlushGuard>>,
|
||||
}
|
||||
|
||||
impl Debug for ChromeTracingFlushGuard {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let Self { _inner } = self;
|
||||
f.debug_struct("ChromeTracingFlushGuard")
|
||||
.field("inner", &"not shown")
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle to initialize or change tracing subscription.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct TracingSubscription {
|
||||
|
@ -339,6 +355,7 @@ pub struct TracingSubscription {
|
|||
tracing_subscriber::EnvFilter,
|
||||
tracing_subscriber::Registry,
|
||||
>,
|
||||
_chrome_tracing_flush_guard: ChromeTracingFlushGuard,
|
||||
}
|
||||
|
||||
impl TracingSubscription {
|
||||
|
@ -349,11 +366,43 @@ impl TracingSubscription {
|
|||
.with_default_directive(tracing::metadata::LevelFilter::ERROR.into())
|
||||
.from_env_lossy();
|
||||
let (filter, reload_log_filter) = tracing_subscriber::reload::Layer::new(filter);
|
||||
|
||||
let (chrome_tracing_layer, chrome_tracing_flush_guard) = match std::env::var("JJ_TRACE") {
|
||||
Ok(_) => {
|
||||
let filename = format!(
|
||||
"jj-trace-{}.json",
|
||||
SystemTime::now()
|
||||
.duration_since(SystemTime::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs(),
|
||||
);
|
||||
let include_args = std::env::var("JJ_TRACE_INCLUDE_ARGS").is_ok();
|
||||
let (layer, guard) = ChromeLayerBuilder::new()
|
||||
.file(filename)
|
||||
.include_args(include_args)
|
||||
.build();
|
||||
(
|
||||
Some(layer),
|
||||
ChromeTracingFlushGuard {
|
||||
_inner: Some(Rc::new(guard)),
|
||||
},
|
||||
)
|
||||
}
|
||||
Err(_) => (None, ChromeTracingFlushGuard { _inner: None }),
|
||||
};
|
||||
|
||||
tracing_subscriber::registry()
|
||||
.with(filter)
|
||||
.with(tracing_subscriber::fmt::Layer::default().with_writer(std::io::stderr))
|
||||
.with(
|
||||
tracing_subscriber::fmt::Layer::default()
|
||||
.with_writer(std::io::stderr)
|
||||
.with_filter(filter),
|
||||
)
|
||||
.with(chrome_tracing_layer)
|
||||
.init();
|
||||
TracingSubscription { reload_log_filter }
|
||||
TracingSubscription {
|
||||
reload_log_filter,
|
||||
_chrome_tracing_flush_guard: chrome_tracing_flush_guard,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn enable_verbose_logging(&self) -> Result<(), CommandError> {
|
||||
|
|
Loading…
Reference in a new issue