summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-07-22 01:09:56 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-07-22 01:09:56 +0000
commit48a4bf32e2dc4c74a29bbf6056b4add9abc376f3 (patch)
tree48e3ac8426b6c49538d02ca246e1ba7cf33d934a
parent73438ee54930f03bdde8112d3c7dcb2664beb21a (diff)
parentc9377edc82325556833e7619612fa5dccc91e623 (diff)
downloadextras-48a4bf32e2dc4c74a29bbf6056b4add9abc376f3.tar.gz
Snap for 7571196 from c9377edc82325556833e7619612fa5dccc91e623 to sc-d2-release
Change-Id: I94e518d3287162e8934006dbd6841a996f38e120
-rw-r--r--profcollectd/libprofcollectd/Android.bp3
-rw-r--r--profcollectd/libprofcollectd/config.rs2
-rw-r--r--profcollectd/libprofcollectd/lib.rs8
-rw-r--r--profcollectd/libprofcollectd/logging_trace_provider.rs56
-rw-r--r--profcollectd/libprofcollectd/report.rs11
-rw-r--r--profcollectd/libprofcollectd/service.rs31
-rw-r--r--profcollectd/libprofcollectd/simpleperf_etm_trace_provider.rs6
-rw-r--r--profcollectd/libprofcollectd/trace_provider.rs19
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()
}