diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-07-22 01:09:56 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-07-22 01:09:56 +0000 |
commit | 48a4bf32e2dc4c74a29bbf6056b4add9abc376f3 (patch) | |
tree | 48e3ac8426b6c49538d02ca246e1ba7cf33d934a | |
parent | 73438ee54930f03bdde8112d3c7dcb2664beb21a (diff) | |
parent | c9377edc82325556833e7619612fa5dccc91e623 (diff) | |
download | extras-48a4bf32e2dc4c74a29bbf6056b4add9abc376f3.tar.gz |
Snap for 7571196 from c9377edc82325556833e7619612fa5dccc91e623 to sc-d2-release
Change-Id: I94e518d3287162e8934006dbd6841a996f38e120
-rw-r--r-- | profcollectd/libprofcollectd/Android.bp | 3 | ||||
-rw-r--r-- | profcollectd/libprofcollectd/config.rs | 2 | ||||
-rw-r--r-- | profcollectd/libprofcollectd/lib.rs | 8 | ||||
-rw-r--r-- | profcollectd/libprofcollectd/logging_trace_provider.rs | 56 | ||||
-rw-r--r-- | profcollectd/libprofcollectd/report.rs | 11 | ||||
-rw-r--r-- | profcollectd/libprofcollectd/service.rs | 31 | ||||
-rw-r--r-- | profcollectd/libprofcollectd/simpleperf_etm_trace_provider.rs | 6 | ||||
-rw-r--r-- | profcollectd/libprofcollectd/trace_provider.rs | 19 |
8 files changed, 122 insertions, 14 deletions
diff --git a/profcollectd/libprofcollectd/Android.bp b/profcollectd/libprofcollectd/Android.bp index 2e37af9e..7fb1b567 100644 --- a/profcollectd/libprofcollectd/Android.bp +++ b/profcollectd/libprofcollectd/Android.bp @@ -60,4 +60,7 @@ rust_library { "libsimpleperf_profcollect_rust", ], shared_libs: ["libsimpleperf_profcollect"], + + // Enable 'test' feature for more verbose logging and the logging trace provider. + // features: ["test"], } diff --git a/profcollectd/libprofcollectd/config.rs b/profcollectd/libprofcollectd/config.rs index c3ab45cf..11098fe1 100644 --- a/profcollectd/libprofcollectd/config.rs +++ b/profcollectd/libprofcollectd/config.rs @@ -29,6 +29,8 @@ use std::time::Duration; const PROFCOLLECT_CONFIG_NAMESPACE: &str = "profcollect_native_boot"; const PROFCOLLECT_NODE_ID_PROPERTY: &str = "persist.profcollectd.node_id"; +pub const REPORT_RETENTION_SECS: u64 = 14 * 24 * 60 * 60; // 14 days. + lazy_static! { pub static ref TRACE_OUTPUT_DIR: &'static Path = Path::new("/data/misc/profcollectd/trace/"); pub static ref PROFILE_OUTPUT_DIR: &'static Path = Path::new("/data/misc/profcollectd/output/"); diff --git a/profcollectd/libprofcollectd/lib.rs b/profcollectd/libprofcollectd/lib.rs index aacbf8e3..f417bd8c 100644 --- a/profcollectd/libprofcollectd/lib.rs +++ b/profcollectd/libprofcollectd/lib.rs @@ -23,6 +23,9 @@ mod service; mod simpleperf_etm_trace_provider; mod trace_provider; +#[cfg(feature = "test")] +mod logging_trace_provider; + use anyhow::{Context, Result}; use profcollectd_aidl_interface::aidl::com::android::server::profcollect::IProfCollectd::{ self, BnProfCollectd, @@ -90,9 +93,8 @@ pub fn report() -> Result<String> { /// Inits logging for Android pub fn init_logging() { + let min_log_level = if cfg!(feature = "test") { log::Level::Info } else { log::Level::Error }; android_logger::init_once( - android_logger::Config::default() - .with_tag("profcollectd") - .with_min_level(log::Level::Error), + android_logger::Config::default().with_tag("profcollectd").with_min_level(min_log_level), ); } diff --git a/profcollectd/libprofcollectd/logging_trace_provider.rs b/profcollectd/libprofcollectd/logging_trace_provider.rs new file mode 100644 index 00000000..1325855d --- /dev/null +++ b/profcollectd/libprofcollectd/logging_trace_provider.rs @@ -0,0 +1,56 @@ +// +// Copyright (C) 2021 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +//! Logging trace provider for development and testing purposes. + +use anyhow::Result; +use std::path::Path; +use std::time::Duration; +use trace_provider::TraceProvider; + +use crate::trace_provider; + +static LOGGING_TRACEFILE_EXTENSION: &str = "loggingtrace"; + +pub struct LoggingTraceProvider {} + +impl TraceProvider for LoggingTraceProvider { + fn get_name(&self) -> &'static str { + "logging" + } + + fn trace(&self, trace_dir: &Path, tag: &str, sampling_period: &Duration) { + let trace_file = trace_provider::get_path(trace_dir, tag, LOGGING_TRACEFILE_EXTENSION); + + log::info!( + "Trace event triggered, tag {}, sampling for {}ms, saving to {}", + tag, + sampling_period.as_millis(), + trace_file.display() + ); + } + + fn process(&self, _trace_dir: &Path, _profile_dir: &Path) -> Result<()> { + log::info!("Process event triggered"); + Ok(()) + } +} + +impl LoggingTraceProvider { + pub fn supported() -> bool { + true + } +} diff --git a/profcollectd/libprofcollectd/report.rs b/profcollectd/libprofcollectd/report.rs index c37993b7..a67d500b 100644 --- a/profcollectd/libprofcollectd/report.rs +++ b/profcollectd/libprofcollectd/report.rs @@ -23,7 +23,7 @@ use std::fs::{self, File, Permissions}; use std::io::{Read, Write}; use std::os::unix::fs::PermissionsExt; use std::path::{Path, PathBuf}; -use std::time::SystemTime; +use std::time::{Duration, SystemTime}; use uuid::v1::{Context, Timestamp}; use uuid::Uuid; use zip::write::FileOptions; @@ -82,3 +82,12 @@ fn get_report_filename(node_id: &MacAddr6) -> Result<String> { let uuid = Uuid::new_v1(ts, &node_id.as_bytes())?; Ok(uuid.to_string()) } + +/// Get report creation timestamp through its filename (version 1 UUID). +pub fn get_report_ts(filename: &str) -> Result<SystemTime> { + let uuid_ts = Uuid::parse_str(filename)? + .to_timestamp() + .ok_or_else(|| anyhow!("filename is not a valid V1 UUID."))? + .to_unix(); + Ok(SystemTime::UNIX_EPOCH + Duration::new(uuid_ts.0, uuid_ts.1)) +} diff --git a/profcollectd/libprofcollectd/service.rs b/profcollectd/libprofcollectd/service.rs index 0b9cca1e..04f30f89 100644 --- a/profcollectd/libprofcollectd/service.rs +++ b/profcollectd/libprofcollectd/service.rs @@ -21,16 +21,17 @@ use binder::public_api::Result as BinderResult; use binder::Status; use profcollectd_aidl_interface::aidl::com::android::server::profcollect::IProfCollectd::IProfCollectd; use std::ffi::CString; -use std::fs::{copy, create_dir, read_to_string, remove_dir_all, remove_file, write}; +use std::fs::{copy, create_dir, read_dir, read_to_string, remove_dir_all, remove_file, write}; use std::path::PathBuf; use std::str::FromStr; use std::sync::{Mutex, MutexGuard}; +use std::time::Duration; use crate::config::{ Config, BETTERBUG_CACHE_DIR_PREFIX, BETTERBUG_CACHE_DIR_SUFFIX, CONFIG_FILE, - PROFILE_OUTPUT_DIR, REPORT_OUTPUT_DIR, TRACE_OUTPUT_DIR, + PROFILE_OUTPUT_DIR, REPORT_OUTPUT_DIR, REPORT_RETENTION_SECS, TRACE_OUTPUT_DIR, }; -use crate::report::pack_report; +use crate::report::{get_report_ts, pack_report}; use crate::scheduler::Scheduler; fn err_to_binder_status(msg: Error) -> Status { @@ -155,6 +156,30 @@ impl ProfcollectdBinderService { write(*CONFIG_FILE, &new_config.to_string())?; } + // Clear profile reports out of rentention period. + for report in read_dir(*REPORT_OUTPUT_DIR)? { + let report = report?.path(); + let report_name = report + .file_stem() + .and_then(|f| f.to_str()) + .ok_or_else(|| anyhow!("Malformed path {}", report.display()))?; + let report_ts = get_report_ts(report_name); + if let Err(e) = report_ts { + log::error!( + "Cannot decode creation timestamp for report {}, caused by {}, deleting", + report_name, + e + ); + remove_file(report)?; + continue; + } + let report_age = report_ts.unwrap().elapsed()?; + if report_age > Duration::from_secs(REPORT_RETENTION_SECS) { + log::info!("Report {} past rentention period, deleting", report_name); + remove_file(report)?; + } + } + Ok(ProfcollectdBinderService { lock: Mutex::new(Lock { scheduler: new_scheduler, config: new_config }), }) diff --git a/profcollectd/libprofcollectd/simpleperf_etm_trace_provider.rs b/profcollectd/libprofcollectd/simpleperf_etm_trace_provider.rs index 2038a5be..d3baaa36 100644 --- a/profcollectd/libprofcollectd/simpleperf_etm_trace_provider.rs +++ b/profcollectd/libprofcollectd/simpleperf_etm_trace_provider.rs @@ -35,12 +35,10 @@ impl TraceProvider for SimpleperfEtmTraceProvider { } fn trace(&self, trace_dir: &Path, tag: &str, sampling_period: &Duration) { - let mut trace_file = PathBuf::from(trace_dir); - trace_file.push(trace_provider::construct_file_name(tag)); - trace_file.set_extension(ETM_TRACEFILE_EXTENSION); + let trace_file = trace_provider::get_path(trace_dir, tag, ETM_TRACEFILE_EXTENSION); simpleperf_profcollect::record( - &trace_file, + &*trace_file, sampling_period, simpleperf_profcollect::RecordScope::BOTH, ); diff --git a/profcollectd/libprofcollectd/trace_provider.rs b/profcollectd/libprofcollectd/trace_provider.rs index ed0d56f5..44d4cee9 100644 --- a/profcollectd/libprofcollectd/trace_provider.rs +++ b/profcollectd/libprofcollectd/trace_provider.rs @@ -18,12 +18,15 @@ use anyhow::{anyhow, Result}; use chrono::Utc; -use std::path::Path; +use std::path::{Path, PathBuf}; use std::sync::{Arc, Mutex}; use std::time::Duration; use crate::simpleperf_etm_trace_provider::SimpleperfEtmTraceProvider; +#[cfg(feature = "test")] +use crate::logging_trace_provider::LoggingTraceProvider; + pub trait TraceProvider { fn get_name(&self) -> &'static str; fn trace(&self, trace_dir: &Path, tag: &str, sampling_period: &Duration); @@ -36,9 +39,19 @@ pub fn get_trace_provider() -> Result<Arc<Mutex<dyn TraceProvider + Send>>> { return Ok(Arc::new(Mutex::new(SimpleperfEtmTraceProvider {}))); } + #[cfg(feature = "test")] + if LoggingTraceProvider::supported() { + log::info!("logging trace provider registered."); + return Ok(Arc::new(Mutex::new(LoggingTraceProvider {}))); + } + Err(anyhow!("No trace provider found for this device.")) } -pub fn construct_file_name(tag: &str) -> String { - format!("{}_{}", Utc::now().format("%Y%m%d-%H%M%S"), tag) +pub fn get_path(dir: &Path, tag: &str, ext: &str) -> Box<Path> { + let filename = format!("{}_{}", Utc::now().format("%Y%m%d-%H%M%S"), tag); + let mut trace_file = PathBuf::from(dir); + trace_file.push(filename); + trace_file.set_extension(ext); + trace_file.into_boxed_path() } |