Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(31)

Side by Side Diff: chrome/browser/extensions/api/log_private/log_private_api_chromeos.cc

Issue 329853010: Additional methods for chrome.logPrivate API (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: all works Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/api/log_private/log_private_api.h" 5 #include "chrome/browser/extensions/api/log_private/log_private_api.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/command_line.h"
10 #include "base/json/json_writer.h" 11 #include "base/json/json_writer.h"
11 #include "base/lazy_instance.h" 12 #include "base/lazy_instance.h"
12 #include "base/logging.h" 13 #include "base/logging.h"
13 #include "base/memory/linked_ptr.h" 14 #include "base/memory/linked_ptr.h"
14 #include "base/memory/scoped_ptr.h" 15 #include "base/memory/scoped_ptr.h"
15 #include "chrome/browser/browser_process.h" 16 #include "chrome/browser/browser_process.h"
17 #include "chrome/browser/download/download_prefs.h"
18 #include "chrome/browser/extensions/api/file_handlers/app_file_handler_util.h"
16 #include "chrome/browser/extensions/api/log_private/filter_handler.h" 19 #include "chrome/browser/extensions/api/log_private/filter_handler.h"
17 #include "chrome/browser/extensions/api/log_private/log_parser.h" 20 #include "chrome/browser/extensions/api/log_private/log_parser.h"
18 #include "chrome/browser/extensions/api/log_private/syslog_parser.h" 21 #include "chrome/browser/extensions/api/log_private/syslog_parser.h"
19 #include "chrome/browser/feedback/system_logs/scrubbed_system_logs_fetcher.h" 22 #include "chrome/browser/feedback/system_logs/scrubbed_system_logs_fetcher.h"
20 #include "chrome/browser/io_thread.h" 23 #include "chrome/browser/io_thread.h"
21 #include "chrome/browser/net/chrome_net_log.h" 24 #include "chrome/browser/net/chrome_net_log.h"
22 #include "chrome/browser/profiles/profile.h" 25 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/common/extensions/api/log_private.h" 26 #include "chrome/common/extensions/api/log_private.h"
27 #include "chrome/common/logging_chrome.h"
28 #include "content/public/browser/render_process_host.h"
24 #include "extensions/browser/event_router.h" 29 #include "extensions/browser/event_router.h"
25 #include "extensions/browser/extension_function.h" 30 #include "extensions/browser/extension_function.h"
26 #include "extensions/browser/extension_registry.h" 31 #include "extensions/browser/extension_registry.h"
32 #include "extensions/browser/granted_file_entry.h"
33
34 #if defined(OS_CHROMEOS)
35 #include "chrome/browser/chromeos/system_logs/debug_log_writer.h"
36 #endif
27 37
28 using content::BrowserThread; 38 using content::BrowserThread;
29 39
30 namespace events { 40 namespace events {
31 const char kOnAddNetInternalsEntries[] = "logPrivate.onAddNetInternalsEntries"; 41 const char kOnAddNetInternalsEntries[] = "logPrivate.onAddNetInternalsEntries";
32 } // namespace events 42 } // namespace events
33 43
34 namespace extensions { 44 namespace extensions {
35 namespace { 45 namespace {
36 46
47 const char kLogFileNameBase[] = "net-internals";
37 const int kNetLogEventDelayMilliseconds = 100; 48 const int kNetLogEventDelayMilliseconds = 100;
38 49
39 scoped_ptr<LogParser> CreateLogParser(const std::string& log_type) { 50 scoped_ptr<LogParser> CreateLogParser(const std::string& log_type) {
40 if (log_type == "syslog") 51 if (log_type == "syslog")
41 return scoped_ptr<LogParser>(new SyslogParser()); 52 return scoped_ptr<LogParser>(new SyslogParser());
42 // TODO(shinfan): Add more parser here 53 // TODO(shinfan): Add more parser here
43 54
44 NOTREACHED() << "Invalid log type: " << log_type; 55 NOTREACHED() << "Invalid log type: " << log_type;
45 return scoped_ptr<LogParser>(); 56 return scoped_ptr<LogParser>();
46 } 57 }
(...skipping 17 matching lines...) Expand all
64 } // namespace 75 } // namespace
65 76
66 // static 77 // static
67 LogPrivateAPI* LogPrivateAPI::Get(content::BrowserContext* context) { 78 LogPrivateAPI* LogPrivateAPI::Get(content::BrowserContext* context) {
68 return GetFactoryInstance()->Get(context); 79 return GetFactoryInstance()->Get(context);
69 } 80 }
70 81
71 LogPrivateAPI::LogPrivateAPI(content::BrowserContext* context) 82 LogPrivateAPI::LogPrivateAPI(content::BrowserContext* context)
72 : browser_context_(context), 83 : browser_context_(context),
73 logging_net_internals_(false), 84 logging_net_internals_(false),
85 event_sink_(LogPrivateAPI::REPORT_EVENTS_TO_EXTENSION),
74 extension_registry_observer_(this) { 86 extension_registry_observer_(this) {
75 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); 87 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_));
76 } 88 }
77 89
78 LogPrivateAPI::~LogPrivateAPI() { 90 LogPrivateAPI::~LogPrivateAPI() {
79 } 91 }
80 92
81 void LogPrivateAPI::StartNetInternalsWatch(const std::string& extension_id) { 93 void LogPrivateAPI::StartNetInternalsWatch(
94 const std::string& extension_id,
95 LogPrivateAPI::CapturedEventsSink event_sink) {
82 net_internal_watches_.insert(extension_id); 96 net_internal_watches_.insert(extension_id);
83 BrowserThread::PostTask( 97 BrowserThread::PostTask(
84 BrowserThread::IO, FROM_HERE, 98 BrowserThread::IO, FROM_HERE,
85 base::Bind(&LogPrivateAPI::MaybeStartNetInternalLogging, 99 base::Bind(&LogPrivateAPI::MaybeStartNetInternalLogging,
86 base::Unretained(this))); 100 base::Unretained(this),
101 event_sink));
87 } 102 }
88 103
89 void LogPrivateAPI::StopNetInternalsWatch(const std::string& extension_id) { 104 void LogPrivateAPI::StopNetInternalsWatch(const std::string& extension_id,
105 const base::Closure& closure) {
90 net_internal_watches_.erase(extension_id); 106 net_internal_watches_.erase(extension_id);
91 MaybeStopNetInternalLogging(); 107 MaybeStopNetInternalLogging(closure);
108 }
109
110 void LogPrivateAPI::StopAllWatches(const std::string& extension_id,
111 const base::Closure& closure) {
112 StopNetInternalsWatch(extension_id, closure);
92 } 113 }
93 114
94 static base::LazyInstance<BrowserContextKeyedAPIFactory<LogPrivateAPI> > 115 static base::LazyInstance<BrowserContextKeyedAPIFactory<LogPrivateAPI> >
95 g_factory = LAZY_INSTANCE_INITIALIZER; 116 g_factory = LAZY_INSTANCE_INITIALIZER;
96 117
97 // static 118 // static
98 BrowserContextKeyedAPIFactory<LogPrivateAPI>* 119 BrowserContextKeyedAPIFactory<LogPrivateAPI>*
99 LogPrivateAPI::GetFactoryInstance() { 120 LogPrivateAPI::GetFactoryInstance() {
100 return g_factory.Pointer(); 121 return g_factory.Pointer();
101 } 122 }
(...skipping 26 matching lines...) Expand all
128 // Create the event's arguments value. 149 // Create the event's arguments value.
129 scoped_ptr<base::ListValue> event_args(new base::ListValue()); 150 scoped_ptr<base::ListValue> event_args(new base::ListValue());
130 event_args->Append(value->DeepCopy()); 151 event_args->Append(value->DeepCopy());
131 scoped_ptr<Event> event(new Event(events::kOnAddNetInternalsEntries, 152 scoped_ptr<Event> event(new Event(events::kOnAddNetInternalsEntries,
132 event_args.Pass())); 153 event_args.Pass()));
133 EventRouter::Get(browser_context_) 154 EventRouter::Get(browser_context_)
134 ->DispatchEventToExtension(*ix, event.Pass()); 155 ->DispatchEventToExtension(*ix, event.Pass());
135 } 156 }
136 } 157 }
137 158
138 void LogPrivateAPI::MaybeStartNetInternalLogging() { 159 void LogPrivateAPI::MaybeStartNetInternalLogging(
160 LogPrivateAPI::CapturedEventsSink event_sink) {
139 DCHECK_CURRENTLY_ON(BrowserThread::IO); 161 DCHECK_CURRENTLY_ON(BrowserThread::IO);
140 if (!logging_net_internals_) { 162 if (!logging_net_internals_) {
141 g_browser_process->io_thread()->net_log()->AddThreadSafeObserver(
142 this, net::NetLog::LOG_ALL_BUT_BYTES);
143 logging_net_internals_ = true; 163 logging_net_internals_ = true;
164 event_sink_ = event_sink;
165 switch (event_sink_) {
166 case REPORT_EVENTS_TO_EXTENSION: {
167 g_browser_process->io_thread()->net_log()->AddThreadSafeObserver(
168 this, net::NetLog::LOG_ALL_BUT_BYTES);
169 break;
170 }
171 case RECORD_EVENTS_TO_FILE: {
172 base::FilePath file_path =
173 logging::GetSessionLogDir(
174 *CommandLine::ForCurrentProcess()).Append(kLogFileNameBase);
175 file_path = logging::GenerateTimestampedName(file_path,
176 base::Time::Now());
177 FILE* file = NULL;
178 file = fopen(file_path.value().c_str(), "w");
179 if (file == NULL) {
180 LOG(ERROR) << "Could not open file " << file_path.value()
xiaowenx 2014/06/25 05:30:44 Does zork's comment earlier about VLOG(1) also app
zel 2014/06/27 19:31:01 same answer
181 << " for net logging";
182 } else {
183 scoped_ptr<base::Value> constants(net::NetLogLogger::GetConstants());
184 net_log_logger_.reset(new net::NetLogLogger(file, *constants));
185 net_log_logger_->set_log_level(net::NetLog::LOG_ALL_BUT_BYTES);
186 net_log_logger_->StartObserving(
187 g_browser_process->io_thread()->net_log());
188 }
189 break;
190 }
xiaowenx 2014/06/25 05:30:44 Do you want to add in: "default: NOTREACHED()" to
Zachary Kuznia 2014/06/25 18:39:03 Switches with enums generate a compile error if ca
zel 2014/06/27 19:31:01 Yep. We prefer failing in compile time vs. runtime
191 }
144 } 192 }
145 } 193 }
146 194
147 void LogPrivateAPI::MaybeStopNetInternalLogging() { 195 void LogPrivateAPI::MaybeStopNetInternalLogging(const base::Closure& closure) {
148 if (net_internal_watches_.empty()) { 196 if (net_internal_watches_.empty()) {
149 BrowserThread::PostTask( 197 BrowserThread::PostTaskAndReply(
150 BrowserThread::IO, FROM_HERE, 198 BrowserThread::IO, FROM_HERE,
151 base::Bind(&LogPrivateAPI:: StopNetInternalLogging, 199 base::Bind(&LogPrivateAPI:: StopNetInternalLogging,
152 base::Unretained(this))); 200 base::Unretained(this)),
201 closure);
153 } 202 }
154 } 203 }
155 204
156 void LogPrivateAPI::StopNetInternalLogging() { 205 void LogPrivateAPI::StopNetInternalLogging() {
157 DCHECK_CURRENTLY_ON(BrowserThread::IO); 206 DCHECK_CURRENTLY_ON(BrowserThread::IO);
158 if (net_log() && logging_net_internals_) { 207 if (net_log() && logging_net_internals_) {
159 net_log()->RemoveThreadSafeObserver(this);
160 logging_net_internals_ = false; 208 logging_net_internals_ = false;
209 switch (event_sink_) {
210 case REPORT_EVENTS_TO_EXTENSION:
211 net_log()->RemoveThreadSafeObserver(this);
212 break;
213 case RECORD_EVENTS_TO_FILE:
214 net_log_logger_->StopObserving();
215 net_log_logger_.reset();
216 break;
xiaowenx 2014/06/25 05:30:44 Same as above, do you want to add a default case?
zel 2014/06/27 19:31:01 same as above
217 }
161 } 218 }
162 } 219 }
163 220
164 void LogPrivateAPI::OnExtensionUnloaded( 221 void LogPrivateAPI::OnExtensionUnloaded(
165 content::BrowserContext* browser_context, 222 content::BrowserContext* browser_context,
166 const Extension* extension, 223 const Extension* extension,
167 UnloadedExtensionInfo::Reason reason) { 224 UnloadedExtensionInfo::Reason reason) {
168 StopNetInternalsWatch(extension->id()); 225 StopNetInternalsWatch(extension->id(), base::Closure());
169 } 226 }
170 227
171 LogPrivateGetHistoricalFunction::LogPrivateGetHistoricalFunction() { 228 LogPrivateGetHistoricalFunction::LogPrivateGetHistoricalFunction() {
172 } 229 }
173 230
174 LogPrivateGetHistoricalFunction::~LogPrivateGetHistoricalFunction() { 231 LogPrivateGetHistoricalFunction::~LogPrivateGetHistoricalFunction() {
175 } 232 }
176 233
177 bool LogPrivateGetHistoricalFunction::RunAsync() { 234 bool LogPrivateGetHistoricalFunction::RunAsync() {
178 // Get parameters 235 // Get parameters
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 267
211 LogPrivateStartNetInternalsWatchFunction:: 268 LogPrivateStartNetInternalsWatchFunction::
212 LogPrivateStartNetInternalsWatchFunction() { 269 LogPrivateStartNetInternalsWatchFunction() {
213 } 270 }
214 271
215 LogPrivateStartNetInternalsWatchFunction:: 272 LogPrivateStartNetInternalsWatchFunction::
216 ~LogPrivateStartNetInternalsWatchFunction() { 273 ~LogPrivateStartNetInternalsWatchFunction() {
217 } 274 }
218 275
219 bool LogPrivateStartNetInternalsWatchFunction::RunSync() { 276 bool LogPrivateStartNetInternalsWatchFunction::RunSync() {
220 LogPrivateAPI::Get(GetProfile())->StartNetInternalsWatch(extension_id()); 277 LogPrivateAPI::Get(GetProfile())->StartNetInternalsWatch(
278 extension_id(),
279 LogPrivateAPI::REPORT_EVENTS_TO_EXTENSION);
221 return true; 280 return true;
222 } 281 }
223 282
224 LogPrivateStopNetInternalsWatchFunction:: 283 LogPrivateStopNetInternalsWatchFunction::
225 LogPrivateStopNetInternalsWatchFunction() { 284 LogPrivateStopNetInternalsWatchFunction() {
226 } 285 }
227 286
228 LogPrivateStopNetInternalsWatchFunction:: 287 LogPrivateStopNetInternalsWatchFunction::
229 ~LogPrivateStopNetInternalsWatchFunction() { 288 ~LogPrivateStopNetInternalsWatchFunction() {
230 } 289 }
231 290
232 bool LogPrivateStopNetInternalsWatchFunction::RunSync() { 291 bool LogPrivateStopNetInternalsWatchFunction::RunSync() {
233 LogPrivateAPI::Get(GetProfile())->StopNetInternalsWatch(extension_id()); 292 LogPrivateAPI::Get(GetProfile())->StopNetInternalsWatch(extension_id(),
293 base::Closure());
234 return true; 294 return true;
235 } 295 }
236 296
297 LogPrivateStartEventRecorderFunction::LogPrivateStartEventRecorderFunction() {
298 }
299
300 LogPrivateStartEventRecorderFunction::~LogPrivateStartEventRecorderFunction() {
301 }
302
303 bool LogPrivateStartEventRecorderFunction::RunSync() {
304 scoped_ptr<api::log_private::StartEventRecorder::Params> params(
305 api::log_private::StartEventRecorder::Params::Create(*args_));
306 EXTENSION_FUNCTION_VALIDATE(params.get());
307 if (params->type == api::log_private::EVENT_TYPE_NETWORK) {
Zachary Kuznia 2014/06/25 00:05:53 params->type should be generated as an enum, so if
308 LogPrivateAPI::Get(GetProfile())->StartNetInternalsWatch(
309 extension_id(),
310 LogPrivateAPI::RECORD_EVENTS_TO_FILE);
xiaowenx 2014/06/25 05:30:44 We always want network events to be saved to a fil
zel 2014/06/27 19:31:01 For this API call - yes. Those files are aggregate
311 } else {
312 NOTREACHED();
313 return false;
314 }
315
316 return true;
317 }
318
319 LogPrivateStopEventRecorderFunction::LogPrivateStopEventRecorderFunction() {
320 }
321
322 LogPrivateStopEventRecorderFunction::~LogPrivateStopEventRecorderFunction() {
323 }
324
325 bool LogPrivateStopEventRecorderFunction::RunSync() {
326 scoped_ptr<api::log_private::StartEventRecorder::Params> params(
xiaowenx 2014/06/25 05:30:44 Should this say "StopEventRecorder::Params" instea
zel 2014/06/27 19:31:01 Good catch. They happen to be the same by accident
327 api::log_private::StartEventRecorder::Params::Create(*args_));
328 EXTENSION_FUNCTION_VALIDATE(params.get());
329 if (params->type == api::log_private::EVENT_TYPE_NETWORK) {
330 LogPrivateAPI::Get(GetProfile())->StopNetInternalsWatch(extension_id(),
331 base::Closure());
332 } else {
333 NOTREACHED();
334 return false;
335 }
336 return true;
337 }
338
339 LogPrivateDumpLogsFunction::LogPrivateDumpLogsFunction() {
340 }
341
342 LogPrivateDumpLogsFunction::~LogPrivateDumpLogsFunction() {
343 }
344
345 bool LogPrivateDumpLogsFunction::RunAsync() {
346 LogPrivateAPI::Get(Profile::FromBrowserContext(browser_context()))->
347 StopAllWatches(
348 extension_id(),
349 base::Bind(&LogPrivateDumpLogsFunction::OnStopAllWatches, this));
350 return true;
351 }
352
353 void LogPrivateDumpLogsFunction::OnStopAllWatches() {
354 const DownloadPrefs* const prefs =
355 DownloadPrefs::FromBrowserContext(browser_context());
356 chromeos::DebugLogWriter::StoreLogs(
357 prefs->DownloadPath(),
358 base::Bind(&LogPrivateDumpLogsFunction::OnStoreLogsCompleted,
359 this));
360 }
361
362 void LogPrivateDumpLogsFunction::OnStoreLogsCompleted(
363 const base::FilePath& log_path, bool succeeded) {
364
365 scoped_ptr<base::DictionaryValue> response(new base::DictionaryValue());
366 extensions::GrantedFileEntry file_entry =
367 extensions::app_file_handler_util::CreateFileEntry(
368 Profile::FromBrowserContext(browser_context()),
369 GetExtension(),
370 render_view_host_->GetProcess()->GetID(),
371 log_path,
372 false);
373
374 base::DictionaryValue* entry = new base::DictionaryValue();
375 entry->SetString("fileSystemId", file_entry.filesystem_id);
376 entry->SetString("baseName", file_entry.registered_name);
377 entry->SetString("id", file_entry.id);
378 entry->SetBoolean("isDirectory", false);
379 response->Set("entry", entry);
380 SetResult(response.release());
381 SendResponse(succeeded);
382 }
383
384
237 } // namespace extensions 385 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698