diff options
| author | Linus Färnstrand <linus@mullvad.net> | 2019-06-04 16:01:45 +0200 |
|---|---|---|
| committer | Linus Färnstrand <linus@mullvad.net> | 2019-06-10 10:39:18 +0200 |
| commit | a53f2bba58613da29023503eb70aabd824e8326a (patch) | |
| tree | 4d66374cb86153f36bfddcbd4313b09d2967c304 | |
| parent | 7a11893ae5560e87b5fd4a1cdc5f29193fddf787 (diff) | |
| download | mullvadvpn-a53f2bba58613da29023503eb70aabd824e8326a.tar.xz mullvadvpn-a53f2bba58613da29023503eb70aabd824e8326a.zip | |
Automatically pick up frontend logs in problem-report
| -rw-r--r-- | mullvad-problem-report/src/main.rs | 79 |
1 files changed, 68 insertions, 11 deletions
diff --git a/mullvad-problem-report/src/main.rs b/mullvad-problem-report/src/main.rs index ae8762c102..363fd0c9bc 100644 --- a/mullvad-problem-report/src/main.rs +++ b/mullvad-problem-report/src/main.rs @@ -88,10 +88,7 @@ pub enum LogError { #[error(display = "Unable to get log directory")] GetLogDir(#[error(source)] mullvad_paths::Error), - #[error( - display = "Failed to list the files in the mullvad-daemon log directory: {}", - path - )] + #[error(display = "Failed to list the files in the log directory: {}", path)] ListLogDir { path: String, #[error(cause)] @@ -100,6 +97,14 @@ pub enum LogError { #[error(display = "Error reading the contents of log file: {}", path)] ReadLogError { path: String }, + + #[cfg(any(target_os = "linux", target_os = "macos"))] + #[error(display = "No home directory for current user")] + NoHomeDir, + + #[cfg(target_os = "windows")] + #[error(display = "Missing %LOCALAPPDATA% environment variable")] + NoLocalAppDataDir, } fn main() { @@ -216,10 +221,13 @@ fn collect_report( ) -> Result<(), Error> { let mut problem_report = ProblemReport::new(redact_custom_strings); - match logs_from_log_directory() { - Ok(logs) => { + let daemon_logs = mullvad_paths::get_log_dir() + .map_err(LogError::GetLogDir) + .and_then(list_logs); + match daemon_logs { + Ok(daemon_logs) => { let mut other_logs = Vec::new(); - for log in logs { + for log in daemon_logs { match log { Ok(path) => { if is_tunnel_log(&path) { @@ -235,8 +243,24 @@ fn collect_report( problem_report.add_log(&other_log); } } - Err(error) => problem_report.add_error("Failed to list logs in log directory", &error), + Err(error) => { + problem_report.add_error("Failed to list logs in daemon log directory", &error) + } }; + match frontend_log_dir().map(|dir| dir.and_then(list_logs)) { + Some(Ok(frontend_logs)) => { + for log in frontend_logs { + match log { + Ok(path) => problem_report.add_log(&path), + Err(error) => problem_report.add_error("Unable to get log path", &error), + } + } + } + Some(Err(error)) => { + problem_report.add_error("Failed to list logs in frontend log directory", &error) + } + None => {} + } problem_report.add_logs(extra_logs); @@ -246,9 +270,10 @@ fn collect_report( }) } -fn logs_from_log_directory() -> Result<impl Iterator<Item = Result<PathBuf, LogError>>, LogError> { - let log_dir = mullvad_paths::get_log_dir().map_err(LogError::GetLogDir)?; - +/// Returns an iterator over all files in the given directory that has the `.log` extension. +fn list_logs( + log_dir: PathBuf, +) -> Result<impl Iterator<Item = Result<PathBuf, LogError>>, LogError> { fs::read_dir(&log_dir) .map_err(|source| LogError::ListLogDir { path: log_dir.display().to_string(), @@ -275,6 +300,38 @@ fn logs_from_log_directory() -> Result<impl Iterator<Item = Result<PathBuf, LogE }) } +/// Returns the directory where the Mullvad GUI frontend stores its logs. +/// If the current platform has a separate directory for frontend logs. +fn frontend_log_dir() -> Option<Result<PathBuf, LogError>> { + #[cfg(target_os = "linux")] + { + Some( + dirs::home_dir() + .ok_or(LogError::NoHomeDir) + .map(|home_dir| home_dir.join(".config/Mullvad VPN/logs")), + ) + } + #[cfg(target_os = "macos")] + { + Some( + dirs::home_dir() + .ok_or(LogError::NoHomeDir) + .map(|home_dir| home_dir.join("Library/Logs/Mullvad VPN")), + ) + } + #[cfg(target_os = "windows")] + { + Some(match std::env::var_os("LOCALAPPDATA") { + Some(dir) => Ok(Path::new(&dir).join("Mullvad VPN/logs")), + None => Err(LogError::NoLocalAppDataDir), + }) + } + #[cfg(target_os = "android")] + { + None + } +} + fn is_tunnel_log(path: &Path) -> bool { match path.file_name() { Some(file_name) => file_name.to_string_lossy().contains("openvpn"), |
