Create Android trace events (if available) from tracing spans
This commit is contained in:
parent
4c2bf6da69
commit
f4755cfbd7
|
@ -520,6 +520,29 @@ version = "1.0.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
|
||||
|
||||
[[package]]
|
||||
name = "dlopen2"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b121caccfc363e4d9a4589528f3bef7c71b83c6ed01c8dc68cbeeb7fd29ec698"
|
||||
dependencies = [
|
||||
"dlopen2_derive",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dlopen2_derive"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a09ac8bb8c16a282264c379dffba707b9c998afc7506009137f3c6136888078"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.8.0"
|
||||
|
@ -2167,11 +2190,13 @@ dependencies = [
|
|||
name = "zcash-android-wallet-sdk"
|
||||
version = "0.0.4"
|
||||
dependencies = [
|
||||
"dlopen2",
|
||||
"failure",
|
||||
"hdwallet",
|
||||
"hdwallet-bitcoin",
|
||||
"hex",
|
||||
"jni",
|
||||
"libc",
|
||||
"log-panics",
|
||||
"paranoid-android",
|
||||
"schemer",
|
||||
|
|
|
@ -31,6 +31,10 @@ paranoid-android = "0.2"
|
|||
tracing = "0.1"
|
||||
tracing-subscriber = "0.3"
|
||||
|
||||
# Conditional access to newer NDK features
|
||||
dlopen2 = "0.4"
|
||||
libc = "0.2"
|
||||
|
||||
## Uncomment this to test librustzcash changes locally
|
||||
#[patch.crates-io]
|
||||
#zcash_address = { path = '../../clones/librustzcash/components/zcash_address' }
|
||||
|
|
|
@ -15,6 +15,7 @@ use schemer::MigratorError;
|
|||
use secrecy::{ExposeSecret, SecretVec};
|
||||
use tracing::{debug, error};
|
||||
use tracing_subscriber::prelude::*;
|
||||
use tracing_subscriber::reload;
|
||||
use zcash_address::{ToAddress, ZcashAddress};
|
||||
use zcash_client_backend::keys::{DecodingError, UnifiedSpendingKey};
|
||||
use zcash_client_backend::{
|
||||
|
@ -104,15 +105,27 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_initLogs(
|
|||
.with_ansi(false)
|
||||
.with_filter(tracing_subscriber::filter::LevelFilter::DEBUG);
|
||||
|
||||
// Generate Android trace events from `tracing` spans.
|
||||
let (trace_event_layer, reload_handle) = reload::Layer::new(utils::trace::Layer::new(None));
|
||||
|
||||
// Install the `tracing` subscriber.
|
||||
let registry = tracing_subscriber::registry();
|
||||
#[cfg(target_os = "android")]
|
||||
let registry = registry.with(android_layer);
|
||||
registry.init();
|
||||
registry.with(trace_event_layer).init();
|
||||
|
||||
// Log panics instead of writing them to stderr.
|
||||
log_panics::init();
|
||||
|
||||
// Load optional NDK APIs. We do this via a reload so that we can capture any errors
|
||||
// that occur while trying to dynamically load the NDK.
|
||||
if let Err(e) = reload_handle.modify(|layer| match utils::target_ndk::load() {
|
||||
Ok(api) => *layer = utils::trace::Layer::new(Some(api)),
|
||||
Err(e) => error!("Could not open NDK library or load symbols: {}", e),
|
||||
}) {
|
||||
error!("Failed to reload tracing subscriber with NDK APIs: {}", e);
|
||||
}
|
||||
|
||||
debug!("logs have been initialized successfully");
|
||||
print_debug_state();
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@ use jni::{
|
|||
use std::ops::Deref;
|
||||
|
||||
pub(crate) mod exception;
|
||||
pub(crate) mod target_ndk;
|
||||
pub(crate) mod trace;
|
||||
|
||||
pub(crate) fn java_string_to_rust(env: &JNIEnv<'_>, jstring: JString<'_>) -> String {
|
||||
env.get_string(jstring)
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
//! Utilities for accessing target NDK APIs.
|
||||
|
||||
use dlopen2::{
|
||||
wrapper::{Container, WrapperApi, WrapperMultiApi},
|
||||
Error,
|
||||
};
|
||||
use libc::c_char;
|
||||
|
||||
/// NDK APIs introduced in API level 23.
|
||||
#[derive(WrapperApi)]
|
||||
#[allow(non_snake_case)]
|
||||
pub struct Api23 {
|
||||
#[allow(non_snake_case)]
|
||||
ATrace_beginSection: unsafe extern "C" fn(sectionName: *const c_char),
|
||||
#[allow(non_snake_case)]
|
||||
ATrace_endSection: unsafe extern "C" fn(),
|
||||
}
|
||||
|
||||
#[derive(WrapperMultiApi)]
|
||||
pub struct Api {
|
||||
pub v23: Option<Api23>,
|
||||
}
|
||||
|
||||
pub type NdkApi = Container<Api>;
|
||||
|
||||
pub fn load() -> Result<NdkApi, Error> {
|
||||
unsafe { Container::load("libandroid.so") }
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
use std::ffi::CString;
|
||||
|
||||
use tracing::{error, span, Subscriber};
|
||||
use tracing_subscriber::{layer::Context, registry::LookupSpan};
|
||||
|
||||
use super::target_ndk::{Api23, NdkApi};
|
||||
|
||||
pub struct Layer {
|
||||
ndk_api: Option<NdkApi>,
|
||||
}
|
||||
|
||||
impl Layer {
|
||||
pub fn new(ndk_api: Option<NdkApi>) -> Self {
|
||||
Layer { ndk_api }
|
||||
}
|
||||
|
||||
fn with_api(&self, f: impl FnOnce(&Api23)) {
|
||||
if let Some(v23) = self.ndk_api.as_ref().and_then(|api| api.v23.as_ref()) {
|
||||
f(v23)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Subscriber> tracing_subscriber::Layer<S> for Layer
|
||||
where
|
||||
for<'lookup> S: LookupSpan<'lookup>,
|
||||
{
|
||||
fn on_enter(&self, id: &span::Id, ctx: Context<'_, S>) {
|
||||
self.with_api(|api| match ctx.metadata(id) {
|
||||
Some(metadata) => match CString::new(metadata.name()) {
|
||||
Ok(section_name) => unsafe { api.ATrace_beginSection(section_name.as_ptr()) },
|
||||
Err(_) => error!(
|
||||
"Span name contains internal NUL byte: '{}'",
|
||||
metadata.name()
|
||||
),
|
||||
},
|
||||
None => error!("Span {:?} has no metadata", id),
|
||||
});
|
||||
}
|
||||
|
||||
fn on_exit(&self, _id: &span::Id, _ctx: Context<'_, S>) {
|
||||
self.with_api(|api| {
|
||||
unsafe { api.ATrace_endSection() };
|
||||
});
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue