blob: 69fd6057c97c8b7b8ec8d400592c3f655d6b6720 [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
5#include "log_tool.h"
6
Ben Chanf6cd93a2012-10-14 19:37:00 -07007#include <glib.h>
8
9#include <base/base64.h>
Elly Jones03cd6d72012-06-11 13:04:28 -040010#include <base/file_util.h>
11#include <base/logging.h>
12#include <base/string_split.h>
Ben Chanf6cd93a2012-10-14 19:37:00 -070013#include <base/string_util.h>
Elly Jones03cd6d72012-06-11 13:04:28 -040014
15#include "process_with_output.h"
16
17namespace debugd {
18
19const char *kShell = "/bin/sh";
20
21using std::string;
22using std::vector;
23
24typedef vector<string> Strings;
25
Ben Chanf6cd93a2012-10-14 19:37:00 -070026// Returns |value| if |value| is a valid UTF-8 string or a base64-encoded
27// string of |value| otherwise.
28string EnsureUTF8String(const string& value) {
29 if (IsStringUTF8(value))
30 return value;
31
32 gchar* base64_value = g_base64_encode(
33 reinterpret_cast<const guchar*>(value.c_str()), value.length());
34 if (base64_value) {
35 string encoded_value = "<base64>: ";
36 encoded_value += base64_value;
37 g_free(base64_value);
38 return encoded_value;
39 }
40 return "<invalid>";
41}
42
Elly Fong-Jones57f018c2012-10-08 14:22:01 -040043// TODO(ellyjones): sandbox. crosbug.com/35122
Elly Jones03cd6d72012-06-11 13:04:28 -040044string Run(const string& cmdline) {
45 string output;
46 ProcessWithOutput p;
Elly Jonese0518ff2012-08-13 13:22:46 -040047 string tailed_cmdline = cmdline + " | tail -c 256K";
Elly Jones03cd6d72012-06-11 13:04:28 -040048 if (!p.Init())
49 return "<not available>";
50 p.AddArg(kShell);
51 p.AddStringOption("-c", tailed_cmdline);
52 if (p.Run())
53 return "<not available>";
54 p.GetOutput(&output);
55 if (!output.size())
56 return "<empty>";
Ben Chanf6cd93a2012-10-14 19:37:00 -070057 return EnsureUTF8String(output);
Elly Jones03cd6d72012-06-11 13:04:28 -040058}
59
60struct Log {
61 const char *name;
62 const char *command;
63};
64
Elly Jones533c7c42012-08-10 15:07:05 -040065static const Log common_logs[] = {
Elly Jones03cd6d72012-06-11 13:04:28 -040066 { "CLIENT_ID", "/bin/cat '/home/chronos/Consent To Send Stats'" },
67 { "LOGDATE", "/bin/date" },
68 { "Xorg.0.log", "/bin/cat /var/log/Xorg.0.log" },
Elly Jones03cd6d72012-06-11 13:04:28 -040069 { "bios_info", "/bin/cat /var/log/bios_info.txt" },
Stefan Reinauer4393fa72012-10-18 11:08:09 -070070 { "bios_log", "/bin/cat /sys/firmware/log" },
71 { "bios_times", "/bin/cat /var/log/bios_times.txt" },
Elly Jones03cd6d72012-06-11 13:04:28 -040072 { "board-specific",
73 "/usr/share/userfeedback/scripts/get_board_specific_info" },
74 { "boot_times", "/bin/cat /tmp/boot-times-sent" },
Elly Jones03cd6d72012-06-11 13:04:28 -040075 { "chrome_system_log", "/bin/cat /var/log/chrome/chrome" },
Elly Fong-Jones57f018c2012-10-08 14:22:01 -040076 { "console-ramoops", "/bin/cat /dev/pstore/console-ramoops" },
Elly Jones03cd6d72012-06-11 13:04:28 -040077 { "cpu", "/usr/bin/uname -p" },
78 { "cpuinfo", "/bin/cat /proc/cpuinfo" },
Elly Jones03cd6d72012-06-11 13:04:28 -040079 { "dmesg", "/bin/dmesg" },
80 { "ec_info", "/bin/cat /var/log/ec_info.txt" },
Stefan Reinauer4393fa72012-10-18 11:08:09 -070081 { "eventlog", "/bin/cat /var/log/eventlog.txt" },
Sonny Raodb876812012-11-16 16:16:41 -080082 { "exynos_gem_objects",
83 "/bin/cat /sys/kernel/debug/dri/0/exynos_gem_objects" },
Elly Jones03cd6d72012-06-11 13:04:28 -040084 { "font_info", "/usr/share/userfeedback/scripts/font_info" },
85 { "hardware_class", "/usr/bin/crossystem hwid" },
86 { "hostname", "/bin/hostname" },
87 { "hw_platform", "/usr/bin/uname -i" },
Sonny Raofc348f62012-10-24 18:11:04 -070088 { "i915_gem_gtt", "/bin/cat /sys/kernel/debug/dri/0/i915_gem_gtt" },
89 { "i915_gem_objects", "/bin/cat /sys/kernel/debug/dri/0/i915_gem_objects" },
Elly Jones03cd6d72012-06-11 13:04:28 -040090 { "ifconfig", "/sbin/ifconfig -a" },
Elly Jones2bde94d2012-07-31 18:07:46 -040091 { "kernel-crashes", "/bin/cat /var/spool/crash/kernel.*.kcrash" },
Elly Jones03cd6d72012-06-11 13:04:28 -040092 { "lsmod", "lsmod" },
93 { "lspci", "/usr/sbin/lspci" },
94 { "lsusb", "lsusb" },
Sonny Raodb876812012-11-16 16:16:41 -080095 { "mali_memory", "/bin/cat /sys/devices/platform/mali.0/memory" },
Elly Jones03cd6d72012-06-11 13:04:28 -040096 { "meminfo", "cat /proc/meminfo" },
97 { "memory_spd_info", "/bin/cat /var/log/memory_spd_info.txt" },
Kees Cooka8f3e7e2012-11-19 14:16:01 -080098 { "mount-encrypted", "/bin/cat /var/log/mount-encrypted.log" },
Wade Guthrie67b672e2012-11-14 13:14:31 -080099 { "netlog", "/usr/share/userfeedback/scripts/getmsgs --last '2 hours'"
100 " /var/log/net.log" },
Elly Jones03cd6d72012-06-11 13:04:28 -0400101 { "power-supply-info", "/usr/bin/power-supply-info" },
102 { "powerd.LATEST", "/bin/cat /var/log/power_manager/powerd.LATEST" },
103 { "powerd.out", "/bin/cat /var/log/power_manager/powerd.out" },
104 { "powerm.LATEST", "/bin/cat /var/log/power_manager/powerm.LATEST" },
105 { "powerm.out", "/bin/cat /var/log/power_manager/powerm.out" },
106 // Changed from 'ps ux' to 'ps aux' since we're running as debugd, not chronos
107 { "ps", "/bin/ps aux" },
108 { "syslog", "/usr/share/userfeedback/scripts/getmsgs --last '2 hours'"
Elly Jonesf8a67ee2012-06-19 13:48:38 -0400109 " /var/log/messages" },
Elly Jones03cd6d72012-06-11 13:04:28 -0400110 { "touchpad", "/opt/google/touchpad/tpcontrol status" },
Elly Jonesd31aee22012-07-02 11:09:10 -0400111 { "touchpad_activity", "/opt/google/touchpad/generate_userfeedback alt" },
Elly Jones03cd6d72012-06-11 13:04:28 -0400112 { "ui_log", "/usr/share/userfeedback/scripts/get_log /var/log/ui/ui.LATEST" },
113 { "uname", "/bin/uname -a" },
114 { "update_engine.log", "cat $(ls -1tr /var/log/update_engine | tail -5 | sed"
Elly Jonesd31aee22012-07-02 11:09:10 -0400115 " s.^./var/log/update_engine/.)" },
Elly Jones03cd6d72012-06-11 13:04:28 -0400116 { "verified boot", "/bin/cat /var/log/debug_vboot_noisy.log" },
117 { "vpd_2.0", "/bin/cat /var/log/vpd_2.0.txt" },
118 { "wifi_status", "/usr/bin/network_diagnostics --wifi --no-log" },
119
Gaurav Shah6e8fd892012-10-01 11:51:08 -0700120
Elly Jones03cd6d72012-06-11 13:04:28 -0400121 // Stuff pulled out of the original list. These need access to the running X
122 // session, which we'd rather not give to debugd, or return info specific to
123 // the current session (in the setsid(2) sense), which is not useful for
124 // debugd
125 // { "env", "set" },
126 // { "setxkbmap", "/usr/bin/setxkbmap -print -query" },
127 // { "xrandr", "/usr/bin/xrandr --verbose" }
Elly Jones533c7c42012-08-10 15:07:05 -0400128 { NULL, NULL }
129};
130
131static const Log extra_logs[] = {
132 { "mm-status", "/usr/bin/modem status" },
133 { "network-devices", "/usr/bin/connectivity show devices" },
134 { "network-services", "/usr/bin/connectivity show services" },
135 { NULL, NULL }
136};
137
Gaurav Shahf6c8f2a2012-10-11 17:22:43 -0700138static const Log feedback_logs[] = {
Elly Jones533c7c42012-08-10 15:07:05 -0400139 { "mm-status", "/usr/bin/modem status-feedback" },
140 { "network-devices", "/usr/bin/connectivity show-feedback devices" },
141 { "network-services", "/usr/bin/connectivity show-feedback services" },
142 { NULL, NULL }
Elly Jones03cd6d72012-06-11 13:04:28 -0400143};
144
Gaurav Shahf6c8f2a2012-10-11 17:22:43 -0700145// List of log files that must directly be collected by Chrome. This is because
146// debugd is running under a VFS namespace and does not have access to later
147// cryptohome mounts.
148static const Log user_logs[] = {
149 {"chrome_user_log", "/home/chronos/user/log/chrome"},
150 {"login-times", "/home/chronos/user/login-times"},
151 {"logout-times", "/home/chronos/user/logout-times"},
152 { NULL, NULL}
153};
154
Elly Jones03cd6d72012-06-11 13:04:28 -0400155LogTool::LogTool() { }
156LogTool::~LogTool() { }
157
Elly Jones533c7c42012-08-10 15:07:05 -0400158bool GetNamedLogFrom(const string& name, const struct Log* logs,
159 string* result) {
160 for (size_t i = 0; logs[i].name; i++) {
161 if (name == logs[i].name) {
162 *result = Run(logs[i].command);
163 return true;
164 }
165 }
166 *result = "<invalid log name>";
167 return false;
Elly Jones03cd6d72012-06-11 13:04:28 -0400168}
169
Elly Jones533c7c42012-08-10 15:07:05 -0400170string LogTool::GetLog(const string& name, DBus::Error& error) { // NOLINT
171 string result;
172 GetNamedLogFrom(name, common_logs, &result)
173 || GetNamedLogFrom(name, extra_logs, &result)
174 || GetNamedLogFrom(name, feedback_logs, &result);
175 return result;
176}
177
178void GetLogsFrom(const struct Log* logs, LogTool::LogMap* map) {
179 for (size_t i = 0; logs[i].name; i++)
180 (*map)[logs[i].name] = Run(logs[i].command);
181}
182
183LogTool::LogMap LogTool::GetAllLogs(DBus::Error& error) { // NOLINT
184 LogMap result;
185 GetLogsFrom(common_logs, &result);
186 GetLogsFrom(extra_logs, &result);
187 return result;
188}
189
190LogTool::LogMap LogTool::GetFeedbackLogs(DBus::Error& error) { // NOLINT
191 LogMap result;
192 GetLogsFrom(common_logs, &result);
193 GetLogsFrom(feedback_logs, &result);
Elly Jones03cd6d72012-06-11 13:04:28 -0400194 return result;
195}
196
Gaurav Shahf6c8f2a2012-10-11 17:22:43 -0700197LogTool::LogMap LogTool::GetUserLogFiles(DBus::Error& error) { // NOLINT
198 LogMap result;
199 for (size_t i = 0; user_logs[i].name; ++i)
200 result[user_logs[i].name] = user_logs[i].command;
201 return result;
202}
203
Elly Jones03cd6d72012-06-11 13:04:28 -0400204}; // namespace debugd