blob: 74c262deb5e33ae4be419180cdcd4b56054f0849 [file] [log] [blame]
Elly Jones03cd6d72012-06-11 13:04:28 -04001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Alex Vakulenko262be3f2014-07-30 15:25:50 -07005#include "debugd/src/log_tool.h"
Elly Jones03cd6d72012-06-11 13:04:28 -04006
Ben Chana0011d82014-05-13 00:19:29 -07007#include <vector>
8
Ben Chanab93abf2017-01-24 13:32:51 -08009#include <base/base64.h>
Ben Chancd8fda42014-09-05 08:21:06 -070010#include <base/files/file_util.h>
Ahmed Fakhry21140cf2016-03-04 17:15:19 -080011#include <base/json/json_writer.h>
Elly Jones03cd6d72012-06-11 13:04:28 -040012#include <base/logging.h>
Eric Carusocc7106c2017-04-27 14:22:42 -070013#include <base/memory/ptr_util.h>
Ben Chan9953a592014-02-05 23:32:00 -080014#include <base/strings/string_split.h>
15#include <base/strings/string_util.h>
Ahmed Fakhry21140cf2016-03-04 17:15:19 -080016#include <base/values.h>
Elly Jones03cd6d72012-06-11 13:04:28 -040017
Rebecca Silbersteine78af402014-10-02 10:55:04 -070018#include <chromeos/dbus/service_constants.h>
Eric Carusocc7106c2017-04-27 14:22:42 -070019#include <shill/dbus-proxies.h>
Rebecca Silbersteine78af402014-10-02 10:55:04 -070020
Ben Chanaf125862017-02-08 23:11:18 -080021#include "debugd/src/constants.h"
Alex Vakulenko262be3f2014-07-30 15:25:50 -070022#include "debugd/src/process_with_output.h"
Elly Jones03cd6d72012-06-11 13:04:28 -040023
24namespace debugd {
25
Elly Jones03cd6d72012-06-11 13:04:28 -040026using std::string;
Elly Jones03cd6d72012-06-11 13:04:28 -040027
Eric Caruso96d03d32017-04-25 18:01:17 -070028using Strings = std::vector<string>;
Elly Jones03cd6d72012-06-11 13:04:28 -040029
Ahmed Fakhry21140cf2016-03-04 17:15:19 -080030namespace {
31
Ben Chanaf125862017-02-08 23:11:18 -080032const char kRoot[] = "root";
33const char kShell[] = "/bin/sh";
Ahmed Fakhry21140cf2016-03-04 17:15:19 -080034
35// Minimum time in seconds needed to allow shill to test active connections.
36const int kConnectionTesterTimeoutSeconds = 5;
Ben Chanf6cd93a2012-10-14 19:37:00 -070037
Elly Fong-Jonesd9a16cd2012-11-12 16:09:49 -050038struct Log {
39 const char *name;
40 const char *command;
41 const char *user;
42 const char *group;
Ricky Zhou4c473ca2016-06-21 17:46:58 -070043 const char *size_cap; // passed as arg to 'tail'
Elly Fong-Jonesd9a16cd2012-11-12 16:09:49 -050044};
45
Ahmed Fakhry21140cf2016-03-04 17:15:19 -080046const Log common_logs[] = {
Mike Frysingerc3e835a2017-01-06 04:09:34 -050047 { "CLIENT_ID", "/usr/bin/metrics_client -i"},
Elly Jones03cd6d72012-06-11 13:04:28 -040048 { "LOGDATE", "/bin/date" },
Ahmed Fakhryb7d12cd2017-05-03 11:05:13 -070049 { "atrus_logs", "/bin/cat /var/log/atrus.log 2> /dev/null" },
Lutz Justenc2265662017-06-27 10:13:23 +020050 { "authpolicy", "/bin/cat /var/log/authpolicy.log" },
Elly Jones03cd6d72012-06-11 13:04:28 -040051 { "bios_info", "/bin/cat /var/log/bios_info.txt" },
Vadim Bendebury64aeeed2013-09-16 13:16:49 -070052 { "bios_log",
53 "/bin/cat /sys/firmware/log "
54 "/proc/device-tree/chosen/ap-console-buffer 2> /dev/null" },
Stefan Reinauer4393fa72012-10-18 11:08:09 -070055 { "bios_times", "/bin/cat /var/log/bios_times.txt" },
Elly Jones03cd6d72012-06-11 13:04:28 -040056 { "board-specific",
Thiemo Nagela269ad22014-11-27 17:13:01 +010057 "/usr/share/userfeedback/scripts/get_board_specific_info" },
Olof Johanssone5d0fd32016-01-29 14:40:34 -080058 { "cheets_log", "/usr/bin/collect-cheets-logs 2>&1" },
Thiemo Nagela269ad22014-11-27 17:13:01 +010059 { "clobber.log", "/bin/cat /var/log/clobber.log 2> /dev/null" },
60 { "clobber-state.log", "/bin/cat /var/log/clobber-state.log 2> /dev/null" },
Elly Jones03cd6d72012-06-11 13:04:28 -040061 { "chrome_system_log", "/bin/cat /var/log/chrome/chrome" },
Stefan Reinauer48f883d2014-08-22 14:31:58 -070062 { "console-ramoops", "/bin/cat /dev/pstore/console-ramoops 2> /dev/null" },
Elly Jones03cd6d72012-06-11 13:04:28 -040063 { "cpu", "/usr/bin/uname -p" },
64 { "cpuinfo", "/bin/cat /proc/cpuinfo" },
Benson Leung1526c8f2017-01-22 20:38:04 -080065 { "cr50_version", "/bin/cat /var/cache/cr50-version" },
Eric Caruso57333f12015-09-08 12:50:32 -070066 { "cros_ec",
67 "/bin/cat /var/log/cros_ec.previous /var/log/cros_ec.log 2> /dev/null" },
Nicolas Boichat083795f2016-08-16 11:16:49 +020068 { "cros_ec_panicinfo",
Nicolas Boichatd51092b2016-09-01 10:36:46 +080069 "/bin/cat /sys/kernel/debug/cros_ec/panicinfo 2> /dev/null",
70 SandboxedProcess::kDefaultUser,
71 kDebugfsGroup
72 },
Shawn Nematbakhsh60813732017-07-13 10:46:23 -070073 { "cros_ec_pdinfo",
74 "/bin/cat /sys/kernel/debug/cros_ec/pdinfo 2> /dev/null",
75 SandboxedProcess::kDefaultUser,
76 kDebugfsGroup
77 },
Elly Jones03cd6d72012-06-11 13:04:28 -040078 { "dmesg", "/bin/dmesg" },
79 { "ec_info", "/bin/cat /var/log/ec_info.txt" },
Stefan Reinauer4393fa72012-10-18 11:08:09 -070080 { "eventlog", "/bin/cat /var/log/eventlog.txt" },
Elly Fong-Jones215b5622013-03-20 14:32:18 -040081 {
82 "exynos_gem_objects",
Yuly Novikov13ece852013-07-11 17:19:10 -040083 "/bin/cat /sys/kernel/debug/dri/0/exynos_gem_objects 2> /dev/null",
Elly Fong-Jones215b5622013-03-20 14:32:18 -040084 SandboxedProcess::kDefaultUser,
85 kDebugfsGroup
86 },
Elly Jones03cd6d72012-06-11 13:04:28 -040087 { "font_info", "/usr/share/userfeedback/scripts/font_info" },
Daisuke Nojiridebede0e2017-02-17 14:21:28 -080088 { "sensor_info", "/usr/share/userfeedback/scripts/sensor_info" },
Elly Jones03cd6d72012-06-11 13:04:28 -040089 { "hardware_class", "/usr/bin/crossystem hwid" },
90 { "hostname", "/bin/hostname" },
91 { "hw_platform", "/usr/bin/uname -i" },
Elly Fong-Jones215b5622013-03-20 14:32:18 -040092 {
93 "i915_gem_gtt",
Yuly Novikov13ece852013-07-11 17:19:10 -040094 "/bin/cat /sys/kernel/debug/dri/0/i915_gem_gtt 2> /dev/null",
Elly Fong-Jones215b5622013-03-20 14:32:18 -040095 SandboxedProcess::kDefaultUser,
96 kDebugfsGroup
97 },
98 {
99 "i915_gem_objects",
Yuly Novikov13ece852013-07-11 17:19:10 -0400100 "/bin/cat /sys/kernel/debug/dri/0/i915_gem_objects 2> /dev/null",
Elly Fong-Jones215b5622013-03-20 14:32:18 -0400101 SandboxedProcess::kDefaultUser,
102 kDebugfsGroup
103 },
104 {
105 "i915_error_state",
Yuly Novikov4ac12fb2013-07-18 20:08:44 -0400106 "/usr/bin/xz -c /sys/kernel/debug/dri/0/i915_error_state 2> /dev/null",
Elly Fong-Jones215b5622013-03-20 14:32:18 -0400107 SandboxedProcess::kDefaultUser,
108 kDebugfsGroup,
109 },
Daniel Erat982ab4b2014-04-09 07:32:38 -0700110 { "ifconfig", "/bin/ifconfig -a" },
Lutz Justenc2265662017-06-27 10:13:23 +0200111 { "input_devices", "/bin/cat /proc/bus/input/devices" },
Stefan Reinauer48f883d2014-08-22 14:31:58 -0700112 { "kernel-crashes",
113 "/bin/cat /var/spool/crash/kernel.*.kcrash 2> /dev/null" },
Elly Jones03cd6d72012-06-11 13:04:28 -0400114 { "lsmod", "lsmod" },
115 { "lspci", "/usr/sbin/lspci" },
Simon Que41c88b52017-06-19 14:05:07 -0400116 { "lsusb", "lsusb && lsusb -t" },
Yuly Novikov13ece852013-07-11 17:19:10 -0400117 {
Thiemo Nagela269ad22014-11-27 17:13:01 +0100118 "mali_memory",
119 "/bin/cat /sys/class/misc/mali0/device/memory 2> /dev/null"
Yuly Novikov13ece852013-07-11 17:19:10 -0400120 },
Elly Jones03cd6d72012-06-11 13:04:28 -0400121 { "meminfo", "cat /proc/meminfo" },
122 { "memory_spd_info", "/bin/cat /var/log/memory_spd_info.txt" },
Simon Quecb63b9c2017-06-19 14:53:31 -0400123 // The sed command finds the EDID blob (starting the line after "value:") and
124 // replaces the serial number with all zeroes.
125 //
126 // The EDID is printed as a hex dump over several lines, each line containing
127 // the contents of 16 bytes. The first 16 bytes are broken down as follows:
128 // uint64_t fixed_pattern; // Always 00 FF FF FF FF FF FF 00.
129 // uint16_t manufacturer_id; // Manufacturer ID, encoded as PNP IDs.
130 // uint16_t product_code; // Manufacturer product code, little-endian.
131 // uint32_t serial_number; // Serial number, little-endian.
132 // Source: https://en.wikipedia.org/wiki/EDID#EDID_1.3_data_format
133 //
134 // The subsequent substitution command looks for the fixed pattern followed by
135 // two 32-bit fields (manufacturer + product, serial number). It replaces the
136 // latter field with 8 bytes of zeroes.
137 //
138 // TODO(crbug.com/731133): Remove the sed command once modetest itself can
139 // remove serial numbers.
140 {
141 "modetest",
142 "(modetest; modetest -M evdi; modetest -M udl) | "
143 "sed -E '/EDID/ {:a;n;/value:/!ba;n;"
144 "s/(00f{12}00)([0-9a-f]{8})([0-9a-f]{8})/\\1\\200000000/}'",
145 kRoot,
146 kRoot,
147 },
Kees Cooka8f3e7e2012-11-19 14:16:01 -0800148 { "mount-encrypted", "/bin/cat /var/log/mount-encrypted.log" },
Junichi Uekawa710cb4b2017-04-10 16:05:27 +0900149 { "mountinfo", "/bin/cat /proc/1/mountinfo" },
Darin Petkov54743582012-12-10 14:18:32 +0100150 { "net-diags.net.log", "/bin/cat /var/log/net-diags.net.log" },
Wade Guthrie67b672e2012-11-14 13:14:31 -0800151 { "netlog", "/usr/share/userfeedback/scripts/getmsgs --last '2 hours'"
152 " /var/log/net.log" },
henryhsufa6daa12014-09-24 13:26:30 +0800153 {
154 "nvmap_iovmm",
155 "/bin/cat /sys/kernel/debug/nvmap/iovmm/allocations 2> /dev/null",
156 SandboxedProcess::kDefaultUser,
157 kDebugfsGroup,
158 },
Vincent Palatinc64af9d2013-08-05 16:34:10 -0700159 { "platform_info", "/bin/cat /var/log/platform_info.txt" },
Daniel Erat9b58b6d2013-04-30 14:58:56 -0700160 { "power_supply_info", "/usr/bin/power_supply_info" },
Daniel Eratd8b84992017-03-13 17:30:00 -0600161 { "power_supply_sysfs", "/usr/bin/print_sysfs_power_supply_data" },
Elly Jones03cd6d72012-06-11 13:04:28 -0400162 { "powerd.LATEST", "/bin/cat /var/log/power_manager/powerd.LATEST" },
Daniel Erat546c3882013-11-22 12:46:01 -0800163 { "powerd.PREVIOUS", "/bin/cat /var/log/power_manager/powerd.PREVIOUS" },
Daniel Erat93da9a12012-12-06 14:14:17 -0800164 { "powerd.out", "/bin/cat /var/log/powerd.out" },
Thiemo Nagela269ad22014-11-27 17:13:01 +0100165 { "powerwash_count", "/bin/cat /var/log/powerwash_count 2> /dev/null" },
Mattias Nissler887dce22017-07-03 14:44:35 +0200166 // Changed from 'ps ux' to 'ps aux' since we're running as debugd,
167 // not chronos.
Elly Jones03cd6d72012-06-11 13:04:28 -0400168 { "ps", "/bin/ps aux" },
yusukes34171ba2017-04-27 15:46:01 -0700169 // /proc/slabinfo is owned by root and has 0400 permission.
170 { "slabinfo", "/bin/cat /proc/slabinfo", kRoot, kRoot, },
Puthikorn Voravootivat6de5e122013-12-06 11:43:13 -0800171 { "storage_info", "/bin/cat /var/log/storage_info.txt" },
Elly Jones03cd6d72012-06-11 13:04:28 -0400172 { "syslog", "/usr/share/userfeedback/scripts/getmsgs --last '2 hours'"
Elly Jonesf8a67ee2012-06-19 13:48:38 -0400173 " /var/log/messages" },
Brandon Mayere24c7a22017-08-04 13:58:48 -0400174 { "system_log_stats", "echo 'BLOCK_SIZE=1024'; "
175 "find /var/log/ -type f -exec du --block-size=1024 {} + | sort -n -r",
176 kRoot, kRoot},
Elly Fong-Jonesb4f49c42013-02-28 13:45:26 -0500177 { "tlsdate", "/bin/cat /var/log/tlsdate.log" },
Hsu-Cheng Tsaie8c31d52017-03-31 12:34:55 +0800178 { "top thread", "/usr/bin/top -Hb -n 1 | head -n 40"},
179 { "top memory", "/usr/bin/top -o \"+%MEM\" -bn 1 | head -n 57"},
Elly Jones03cd6d72012-06-11 13:04:28 -0400180 { "touchpad", "/opt/google/touchpad/tpcontrol status" },
Chung-yih Wang4b876142014-04-30 17:01:49 +0800181 { "touchpad_activity", "/opt/google/input/cmt_feedback alt" },
Andrew de los Reyesc060c342013-04-10 13:46:30 -0700182 { "touch_fw_version", "grep -E"
Charlie Mooneybb08f982016-02-04 15:35:56 -0800183 " -e 'synaptics: Touchpad model'"
184 " -e 'chromeos-[a-z]*-touch-[a-z]*-update'"
Andrew de los Reyesc060c342013-04-10 13:46:30 -0700185 " /var/log/messages | tail -n 20" },
Mattias Nissler887dce22017-07-03 14:44:35 +0200186 // TODO(jorgelo,mnissler): Don't run this as root.
187 // On TPM 1.2 devices this will likely require adding a new user to the 'tss'
188 // group.
189 // On TPM 2.0 devices 'get_version_info' uses D-Bus and therefore can run as
190 // any user.
191 { "tpm_version", "/usr/sbin/tpm-manager get_version_info", kRoot, kRoot },
Charlie Mooney69f56702017-05-02 14:55:41 -0700192 { "atmel_ts_refs", "/opt/google/touch/scripts/atmel_tools.sh ts r",
193 kRoot, kRoot},
194 { "atmel_tp_refs", "/opt/google/touch/scripts/atmel_tools.sh tp r",
195 kRoot, kRoot},
196 { "atmel_ts_deltas", "/opt/google/touch/scripts/atmel_tools.sh ts d",
197 kRoot, kRoot},
198 { "atmel_tp_deltas", "/opt/google/touch/scripts/atmel_tools.sh tp d",
199 kRoot, kRoot},
Gwendal Grignou427d94e2016-10-25 11:34:51 -0700200 {
201 "trim",
202 "cat /var/lib/trim/stateful_trim_state /var/lib/trim/stateful_trim_data"
203 },
Elly Jones03cd6d72012-06-11 13:04:28 -0400204 { "ui_log", "/usr/share/userfeedback/scripts/get_log /var/log/ui/ui.LATEST" },
205 { "uname", "/bin/uname -a" },
206 { "update_engine.log", "cat $(ls -1tr /var/log/update_engine | tail -5 | sed"
Thiemo Nagela269ad22014-11-27 17:13:01 +0100207 " s.^./var/log/update_engine/.)" },
Elly Jones03cd6d72012-06-11 13:04:28 -0400208 { "verified boot", "/bin/cat /var/log/debug_vboot_noisy.log" },
Justin TerAvestbf921a32017-05-11 14:31:44 -0600209 { "vmlog.1.LATEST", "/bin/cat /var/log/vmlog/vmlog.1.LATEST" },
210 { "vmlog.1.PREVIOUS", "/bin/cat /var/log/vmlog/vmlog.1.PREVIOUS" },
211 { "vmlog.LATEST", "/bin/cat /var/log/vmlog/vmlog.LATEST" },
212 { "vmlog.PREVIOUS", "/bin/cat /var/log/vmlog/vmlog.PREVIOUS" },
Elly Jones03cd6d72012-06-11 13:04:28 -0400213 { "vpd_2.0", "/bin/cat /var/log/vpd_2.0.txt" },
Samuel Tan107b6c82014-07-10 15:33:44 -0700214 { "wifi_status", "/usr/bin/network_diag --wifi-internal --no-log" },
Sonny Raoab5f9952013-07-17 14:13:53 -0700215 { "zram compressed data size",
216 "/bin/cat /sys/block/zram0/compr_data_size 2> /dev/null" },
217 { "zram original data size",
218 "/bin/cat /sys/block/zram0/orig_data_size 2> /dev/null" },
219 { "zram total memory used",
220 "/bin/cat /sys/block/zram0/mem_used_total 2> /dev/null" },
221 { "zram total reads",
222 "/bin/cat /sys/block/zram0/num_reads 2> /dev/null" },
223 { "zram total writes",
224 "/bin/cat /sys/block/zram0/num_writes 2> /dev/null" },
Luigi Semenzato0253b142017-07-07 15:59:48 -0700225 { "zram new stats names", "/bin/echo orig_size compr_size used_total limit "
Luigi Semenzato4164de42017-07-06 10:42:54 -0700226 "used_max zero_pages migrated" },
Luigi Semenzato0253b142017-07-07 15:59:48 -0700227 { "zram new stats values", "/bin/cat /sys/block/zram0/mm_stat 2> /dev/null" },
Wei-Ning Huang230b7d82017-07-14 16:19:13 +0800228 { "cros_tp version", "/bin/cat /sys/class/chromeos/cros_tp/version" },
229 { "cros_tp console", "/usr/sbin/ectool --name=cros_tp console",
230 kRoot, kRoot },
Wei-Ning Huang23ffdcf2017-08-04 11:30:39 +0800231 { "cros_tp frame", "/usr/sbin/ectool --name=cros_tp tpframeget",
232 kRoot, kRoot },
Gaurav Shah6e8fd892012-10-01 11:51:08 -0700233
Elly Jones03cd6d72012-06-11 13:04:28 -0400234 // Stuff pulled out of the original list. These need access to the running X
235 // session, which we'd rather not give to debugd, or return info specific to
236 // the current session (in the setsid(2) sense), which is not useful for
237 // debugd
238 // { "env", "set" },
239 // { "setxkbmap", "/usr/bin/setxkbmap -print -query" },
240 // { "xrandr", "/usr/bin/xrandr --verbose" }
Ben Chan64d19b22017-02-06 14:03:47 -0800241 { nullptr, nullptr }
Elly Jones533c7c42012-08-10 15:07:05 -0400242};
243
Ahmed Fakhry21140cf2016-03-04 17:15:19 -0800244const Log extra_logs[] = {
Ben Chan36e42282014-02-12 22:32:34 -0800245#if USE_CELLULAR
Elly Jones533c7c42012-08-10 15:07:05 -0400246 { "mm-status", "/usr/bin/modem status" },
Ben Chan36e42282014-02-12 22:32:34 -0800247#endif // USE_CELLULAR
Elly Jones533c7c42012-08-10 15:07:05 -0400248 { "network-devices", "/usr/bin/connectivity show devices" },
249 { "network-services", "/usr/bin/connectivity show services" },
Ben Chan64d19b22017-02-06 14:03:47 -0800250 { nullptr, nullptr }
Elly Jones533c7c42012-08-10 15:07:05 -0400251};
252
Ahmed Fakhry21140cf2016-03-04 17:15:19 -0800253const Log feedback_logs[] = {
Ben Chan36e42282014-02-12 22:32:34 -0800254#if USE_CELLULAR
Elly Jones533c7c42012-08-10 15:07:05 -0400255 { "mm-status", "/usr/bin/modem status-feedback" },
Ben Chan36e42282014-02-12 22:32:34 -0800256#endif // USE_CELLULAR
Elly Jones533c7c42012-08-10 15:07:05 -0400257 { "network-devices", "/usr/bin/connectivity show-feedback devices" },
258 { "network-services", "/usr/bin/connectivity show-feedback services" },
Ben Chan64d19b22017-02-06 14:03:47 -0800259 { nullptr, nullptr }
Elly Jones03cd6d72012-06-11 13:04:28 -0400260};
261
Ahmed Fakhry1498b4e2016-03-30 12:42:20 -0700262// List of log files needed to be part of the feedback report that are huge and
263// must be sent back to the client via the file descriptor using
264// LogTool::GetBigFeedbackLogs().
265const Log big_feedback_logs[] = {
Eric Carusoe3166f22016-06-10 15:36:02 -0700266 { "arc-bugreport",
Yusuke Sato874c0a82016-10-13 15:41:37 -0700267 "/bin/cat /run/arc/bugreport/pipe 2> /dev/null",
Eric Carusoe3166f22016-06-10 15:36:02 -0700268 // ARC bugreport permissions are weird. Since we're just running cat, this
269 // shouldn't cause any issues.
270 kRoot,
Ricky Zhou4c473ca2016-06-21 17:46:58 -0700271 kRoot,
272 "10M",
Eric Carusoe3166f22016-06-10 15:36:02 -0700273 },
Ben Chan64d19b22017-02-06 14:03:47 -0800274 { nullptr, nullptr }
Ahmed Fakhry1498b4e2016-03-30 12:42:20 -0700275};
276
Gaurav Shahf6c8f2a2012-10-11 17:22:43 -0700277// List of log files that must directly be collected by Chrome. This is because
278// debugd is running under a VFS namespace and does not have access to later
279// cryptohome mounts.
Ahmed Fakhry21140cf2016-03-04 17:15:19 -0800280const Log user_logs[] = {
Elly Fong-Jones6456ce52013-04-17 13:31:13 -0400281 {"chrome_user_log", "log/chrome"},
282 {"login-times", "login-times"},
283 {"logout-times", "logout-times"},
Ben Chan64d19b22017-02-06 14:03:47 -0800284 { nullptr, nullptr}
Gaurav Shahf6c8f2a2012-10-11 17:22:43 -0700285};
286
Ahmed Fakhry21140cf2016-03-04 17:15:19 -0800287// Returns |value| if |value| is a valid UTF-8 string or a base64-encoded
288// string of |value| otherwise.
289string EnsureUTF8String(const string& value) {
290 if (base::IsStringUTF8(value))
291 return value;
292
Eric Caruso96d03d32017-04-25 18:01:17 -0700293 string encoded_value;
Ben Chanab93abf2017-01-24 13:32:51 -0800294 base::Base64Encode(value, &encoded_value);
295 return "<base64>: " + encoded_value;
Ahmed Fakhry21140cf2016-03-04 17:15:19 -0800296}
297
298// TODO(ellyjones): sandbox. crosbug.com/35122
299string Run(const Log& log) {
300 string output;
301 ProcessWithOutput p;
Eric Caruso96d03d32017-04-25 18:01:17 -0700302 string tailed_cmdline = string(log.command) + " | tail -c " +
Ahmed Fakhrye4a0b502016-09-19 18:18:49 -0700303 (log.size_cap ? log.size_cap : "512K");
Ahmed Fakhry21140cf2016-03-04 17:15:19 -0800304 if (log.user && log.group)
305 p.SandboxAs(log.user, log.group);
306 if (!p.Init())
307 return "<not available>";
308 p.AddArg(kShell);
309 p.AddStringOption("-c", tailed_cmdline);
310 if (p.Run())
311 return "<not available>";
312 p.GetOutput(&output);
313 if (!output.size())
314 return "<empty>";
315 return EnsureUTF8String(output);
316}
317
318// Fills |dictionary| with the anonymized contents of the logs in |logs|.
319void GetLogsInDictionary(const struct Log* logs,
320 AnonymizerTool* anonymizer,
321 base::DictionaryValue* dictionary) {
322 for (size_t i = 0; logs[i].name; ++i) {
323 dictionary->SetStringWithoutPathExpansion(
324 logs[i].name, anonymizer->Anonymize(Run(logs[i])));
325 }
326}
327
328// Serializes the |dictionary| into the file with the given |fd| in a JSON
329// format.
330void SerializeLogsAsJSON(const base::DictionaryValue& dictionary,
Eric Carusocc7106c2017-04-27 14:22:42 -0700331 const dbus::FileDescriptor& fd) {
Eric Caruso96d03d32017-04-25 18:01:17 -0700332 string logs_json;
Ahmed Fakhry21140cf2016-03-04 17:15:19 -0800333 base::JSONWriter::WriteWithOptions(dictionary,
334 base::JSONWriter::OPTIONS_PRETTY_PRINT,
335 &logs_json);
Eric Carusocc7106c2017-04-27 14:22:42 -0700336 base::WriteFileDescriptor(fd.value(), logs_json.c_str(), logs_json.size());
Ahmed Fakhry21140cf2016-03-04 17:15:19 -0800337}
338
Elly Jones533c7c42012-08-10 15:07:05 -0400339bool GetNamedLogFrom(const string& name, const struct Log* logs,
340 string* result) {
341 for (size_t i = 0; logs[i].name; i++) {
342 if (name == logs[i].name) {
Elly Fong-Jonesd9a16cd2012-11-12 16:09:49 -0500343 *result = Run(logs[i]);
Elly Jones533c7c42012-08-10 15:07:05 -0400344 return true;
345 }
346 }
347 *result = "<invalid log name>";
348 return false;
Elly Jones03cd6d72012-06-11 13:04:28 -0400349}
350
Ahmed Fakhry21140cf2016-03-04 17:15:19 -0800351void GetLogsFrom(const struct Log* logs, LogTool::LogMap* map) {
352 for (size_t i = 0; logs[i].name; i++)
353 (*map)[logs[i].name] = Run(logs[i]);
354}
355
356} // namespace
357
Eric Carusof9091f82017-04-28 14:18:59 -0700358void LogTool::CreateConnectivityReport() {
Rebecca Silbersteine78af402014-10-02 10:55:04 -0700359 // Perform ConnectivityTrial to report connection state in feedback log.
Eric Carusof9091f82017-04-28 14:18:59 -0700360 auto shill = base::MakeUnique<org::chromium::flimflam::ManagerProxy>(bus_);
Rebecca Silbersteine78af402014-10-02 10:55:04 -0700361 // Give the connection trial time to test the connection and log the results
362 // before collecting the logs for feedback.
363 // TODO(silberst): Replace the simple approach of a single timeout with a more
364 // coordinated effort.
Eric Carusocc7106c2017-04-27 14:22:42 -0700365 if (shill && shill->CreateConnectivityReport(nullptr))
366 sleep(kConnectionTesterTimeoutSeconds);
Rebecca Silbersteine78af402014-10-02 10:55:04 -0700367}
368
Eric Carusoc93a15c2017-04-24 16:15:12 -0700369string LogTool::GetLog(const string& name) {
Elly Jones533c7c42012-08-10 15:07:05 -0400370 string result;
371 GetNamedLogFrom(name, common_logs, &result)
372 || GetNamedLogFrom(name, extra_logs, &result)
373 || GetNamedLogFrom(name, feedback_logs, &result);
374 return result;
375}
376
Eric Carusof9091f82017-04-28 14:18:59 -0700377LogTool::LogMap LogTool::GetAllLogs() {
378 CreateConnectivityReport();
Elly Jones533c7c42012-08-10 15:07:05 -0400379 LogMap result;
380 GetLogsFrom(common_logs, &result);
381 GetLogsFrom(extra_logs, &result);
382 return result;
383}
384
Eric Carusof9091f82017-04-28 14:18:59 -0700385LogTool::LogMap LogTool::GetFeedbackLogs() {
386 CreateConnectivityReport();
Elly Jones533c7c42012-08-10 15:07:05 -0400387 LogMap result;
388 GetLogsFrom(common_logs, &result);
389 GetLogsFrom(feedback_logs, &result);
Darin Petkovce9b3a12013-01-10 16:38:54 +0100390 AnonymizeLogMap(&result);
Elly Jones03cd6d72012-06-11 13:04:28 -0400391 return result;
392}
393
Eric Carusof9091f82017-04-28 14:18:59 -0700394void LogTool::GetBigFeedbackLogs(const dbus::FileDescriptor& fd) {
395 CreateConnectivityReport();
Ahmed Fakhry21140cf2016-03-04 17:15:19 -0800396 base::DictionaryValue dictionary;
397 GetLogsInDictionary(common_logs, &anonymizer_, &dictionary);
398 GetLogsInDictionary(feedback_logs, &anonymizer_, &dictionary);
Ahmed Fakhry1498b4e2016-03-30 12:42:20 -0700399 GetLogsInDictionary(big_feedback_logs, &anonymizer_, &dictionary);
Ahmed Fakhry21140cf2016-03-04 17:15:19 -0800400 SerializeLogsAsJSON(dictionary, fd);
401}
402
Eric Carusoc93a15c2017-04-24 16:15:12 -0700403LogTool::LogMap LogTool::GetUserLogFiles() {
Gaurav Shahf6c8f2a2012-10-11 17:22:43 -0700404 LogMap result;
405 for (size_t i = 0; user_logs[i].name; ++i)
406 result[user_logs[i].name] = user_logs[i].command;
407 return result;
408}
409
Darin Petkovce9b3a12013-01-10 16:38:54 +0100410void LogTool::AnonymizeLogMap(LogMap* log_map) {
Ben Chane2fa3572017-02-08 22:46:18 -0800411 for (auto& entry : *log_map)
412 entry.second = anonymizer_.Anonymize(entry.second);
Darin Petkovce9b3a12013-01-10 16:38:54 +0100413}
414
Ben Chana0011d82014-05-13 00:19:29 -0700415} // namespace debugd