summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorLinus Färnstrand <linus@mullvad.net>2019-06-10 11:15:16 +0200
committerLinus Färnstrand <linus@mullvad.net>2019-06-10 11:15:16 +0200
commit7aee7111bd914eb64bb7cff86758dcf7b41dc08f (patch)
treef774aa261927373d5b351d93d10d691de7a54091
parentd20fed36f95e2d535b2272777a78dc84ed9e1e6b (diff)
parent09a1093b1ca7f4d10aa8ffd77ddfe0b1ca2b065c (diff)
downloadmullvadvpn-7aee7111bd914eb64bb7cff86758dcf7b41dc08f.tar.xz
mullvadvpn-7aee7111bd914eb64bb7cff86758dcf7b41dc08f.zip
Merge branch 'problem-report-automatically-include-frontend-logs'
-rw-r--r--CHANGELOG.md1
-rw-r--r--gui/src/main/index.ts17
-rw-r--r--mullvad-problem-report/src/main.rs95
3 files changed, 89 insertions, 24 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b5c2b0abdf..b8666cbe48 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -34,6 +34,7 @@ Line wrap the file at 100 chars. Th
- Add translations for the current location displayed on the main screen in the GUI.
- Allow a subset of NDP (Router solicitation, router advertisement and redirects) in the firewall.
- Allow setting proxy mode from UI.
+- Automatically include frontend logs in problem report when ran from CLI.
#### Linux
- Add standard window decorations to the application window.
diff --git a/gui/src/main/index.ts b/gui/src/main/index.ts
index b4c97cbb2c..15a137dd10 100644
--- a/gui/src/main/index.ts
+++ b/gui/src/main/index.ts
@@ -70,9 +70,6 @@ class ApplicationMain {
private daemonRpc = new DaemonRpc();
private reconnectBackoff = new ReconnectionBackoff();
private connectedToDaemon = false;
-
- private logFilePaths: string[] = [];
- private oldLogFilePaths: string[] = [];
private quitStage = AppQuitStage.unready;
private accountHistory: AccountToken[] = [];
@@ -188,17 +185,15 @@ class ApplicationMain {
private initLogging() {
const logDirectory = getLogsDirectory();
const mainLogFile = getMainLogFile();
- const rendererLogFile = getRendererLogFile();
- const logFiles = [mainLogFile, rendererLogFile];
+ const logFiles = [mainLogFile, getRendererLogFile()];
if (process.env.NODE_ENV !== 'development') {
// Ensure log directory exists
mkdirp.sync(logDirectory);
- this.logFilePaths = logFiles;
- this.oldLogFilePaths = logFiles
- .map((logFile) => backupLogFile(logFile))
- .filter((oldLogFile): oldLogFile is string => typeof oldLogFile === 'string');
+ for (const logFile of logFiles) {
+ backupLogFile(logFile);
+ }
}
setupLogging(mainLogFile);
@@ -886,10 +881,8 @@ class ApplicationMain {
const executable = resolveBin('problem-report');
const args = ['collect', '--output', reportPath];
if (toRedact.length > 0) {
- args.push('--redact', ...toRedact, '--');
+ args.push('--redact', ...toRedact);
}
- args.push(...this.logFilePaths);
- args.push(...this.oldLogFilePaths);
execFile(executable, args, { windowsHide: true }, (error, stdout, stderr) => {
if (error) {
diff --git a/mullvad-problem-report/src/main.rs b/mullvad-problem-report/src/main.rs
index 8d47ebbb98..868aadd2ef 100644
--- a/mullvad-problem-report/src/main.rs
+++ b/mullvad-problem-report/src/main.rs
@@ -15,6 +15,7 @@ use std::{
borrow::Cow,
cmp::min,
collections::{HashMap, HashSet},
+ env,
ffi::OsStr,
fs::{self, File},
io::{self, BufWriter, Read, Seek, SeekFrom, Write},
@@ -87,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)]
@@ -99,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() {
@@ -191,7 +197,19 @@ fn run() -> Result<(), Error> {
.map(|os_values| os_values.map(Path::new).collect())
.unwrap_or_else(Vec::new);
let output_path = Path::new(collect_matches.value_of_os("output").unwrap());
- collect_report(&extra_logs, output_path, redact_custom_strings)
+ collect_report(&extra_logs, output_path, redact_custom_strings)?;
+
+ let expanded_output_path = output_path
+ .canonicalize()
+ .unwrap_or_else(|_| output_path.to_owned());
+ println!(
+ "Problem report written to {}",
+ expanded_output_path.display()
+ );
+ println!("");
+ println!("Send the problem report to support via the send subcommand. See:");
+ println!(" $ {} send --help", env::args().next().unwrap());
+ Ok(())
} else if let Some(send_matches) = matches.subcommand_matches("send") {
let report_path = Path::new(send_matches.value_of_os("report").unwrap());
let user_email = send_matches.value_of("email").unwrap_or("");
@@ -209,10 +227,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) {
@@ -228,8 +249,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);
@@ -239,9 +276,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(),
@@ -268,6 +306,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"),
@@ -362,6 +432,7 @@ impl ProblemReport {
},
));
self.logs.push((redacted_path, content));
+ println!("Adding {}", expanded_path.display());
}
}