OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/chromeos/system/syslogs_provider.h" | 5 #include "chrome/browser/chromeos/system/syslogs_provider.h" |
6 | 6 |
7 #include <functional> | |
8 #include <set> | |
9 | |
7 #include "base/command_line.h" | 10 #include "base/command_line.h" |
8 #include "base/file_path.h" | 11 #include "base/file_path.h" |
9 #include "base/file_util.h" | 12 #include "base/file_util.h" |
10 #include "base/logging.h" | 13 #include "base/logging.h" |
11 #include "base/memory/scoped_ptr.h" | 14 #include "base/memory/scoped_ptr.h" |
12 #include "base/memory/singleton.h" | 15 #include "base/memory/singleton.h" |
13 #include "base/string_util.h" | 16 #include "base/string_util.h" |
17 #include "base/utf_string_conversions.h" | |
18 #include "chrome/browser/memory_details.h" | |
14 #include "chrome/common/chrome_switches.h" | 19 #include "chrome/common/chrome_switches.h" |
15 #include "content/browser/browser_thread.h" | 20 #include "content/browser/browser_thread.h" |
16 | 21 |
17 namespace chromeos { | 22 namespace chromeos { |
18 namespace system { | 23 namespace system { |
19 namespace { | 24 namespace { |
20 | 25 |
21 const char kSysLogsScript[] = | 26 const char kSysLogsScript[] = |
22 "/usr/share/userfeedback/scripts/sysinfo_script_runner"; | 27 "/usr/share/userfeedback/scripts/sysinfo_script_runner"; |
23 const char kBzip2Command[] = | 28 const char kBzip2Command[] = |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
211 // Schedule a task on the FILE thread which will then trigger a request | 216 // Schedule a task on the FILE thread which will then trigger a request |
212 // callback on the calling thread (e.g. UI) when complete. | 217 // callback on the calling thread (e.g. UI) when complete. |
213 BrowserThread::PostTask( | 218 BrowserThread::PostTask( |
214 BrowserThread::FILE, FROM_HERE, | 219 BrowserThread::FILE, FROM_HERE, |
215 NewRunnableMethod( | 220 NewRunnableMethod( |
216 this, &SyslogsProviderImpl::ReadSyslogs, request, | 221 this, &SyslogsProviderImpl::ReadSyslogs, request, |
217 compress_logs, context)); | 222 compress_logs, context)); |
218 | 223 |
219 return request->handle(); | 224 return request->handle(); |
220 } | 225 } |
221 | 226 |
stevenjb
2011/08/03 01:55:20
Actual new code.
| |
227 // Derived class from memoryDetails converts the results into a single string | |
228 // and adds a "mem_usage" entry to the logs, then forwards the result. | |
229 // Format of entry is (one process per line, reverse-sorted by size): | |
230 // Tab [Title1|Title2]: 50 MB | |
231 // Browser: 30 MB | |
232 // Tab [Title]: 20 MB | |
233 // Extension [Title]: 10 MB | |
234 // ... | |
235 class SyslogsMemoryHandler : public MemoryDetails { | |
236 public: | |
237 typedef SyslogsProvider::ReadCompleteCallback ReadCompleteCallback; | |
238 | |
239 // |logs| is modified (see comment above) and passed to |request|. | |
240 // |zip_content| is passed to |request|. | |
241 SyslogsMemoryHandler( | |
242 scoped_refptr<CancelableRequest<ReadCompleteCallback> > request, | |
243 LogDictionaryType* logs, | |
244 std::string* zip_content) | |
245 : request_(request), | |
246 logs_(logs), | |
247 zip_content_(zip_content) { | |
248 } | |
249 | |
250 virtual void OnDetailsAvailable() OVERRIDE { | |
251 const ProcessData& chrome = processes()[0]; // Chrome is the first entry. | |
252 // Process info, sorted by memory used (highest to lowest). | |
253 typedef std::pair<size_t, std::string> ProcInfo; | |
254 typedef std::set<ProcInfo, std::greater<ProcInfo> > ProcInfoSet; | |
255 ProcInfoSet process_info; | |
256 for (ProcessMemoryInformationList::const_iterator iter1 = | |
257 chrome.processes.begin(); | |
258 iter1 != chrome.processes.end(); ++iter1) { | |
259 std::string process_string( | |
260 ChildProcessInfo::GetFullTypeNameInEnglish( | |
261 iter1->type, iter1->renderer_type)); | |
262 if (!iter1->titles.empty()) { | |
263 std::string titles(" ["); | |
264 for (std::vector<string16>::const_iterator iter2 = | |
265 iter1->titles.begin(); | |
266 iter2 != iter1->titles.end(); ++iter2) { | |
267 if (iter2 != iter1->titles.begin()) | |
268 titles += "|"; | |
269 titles += UTF16ToUTF8(*iter2); | |
270 } | |
271 titles += "]"; | |
272 process_string += titles; | |
273 } | |
274 // Use private working set for memory used calculation. | |
275 size_t ws_bytes = iter1->working_set.priv / 1024; | |
James Cook
2011/08/03 17:06:49
If you're dividing by 1024, this isn't bytes. ws_
stevenjb
2011/08/03 19:11:39
Done.
| |
276 process_info.insert(std::make_pair(ws_bytes, process_string)); | |
277 } | |
278 // Add one line for each reverse-sorted entry. | |
279 std::string mem_string; | |
280 for (ProcInfoSet::iterator iter = process_info.begin(); | |
281 iter != process_info.end(); ++iter) { | |
282 mem_string += iter->second + StringPrintf(": %u MB", iter->first) + "\n"; | |
283 } | |
284 (*logs_)["mem_usage"] = mem_string; | |
285 // This will call the callback on the calling thread. | |
286 request_->ForwardResult( | |
287 Tuple2<LogDictionaryType*, std::string*>(logs_, zip_content_)); | |
288 } | |
289 | |
290 private: | |
291 virtual ~SyslogsMemoryHandler() {} | |
292 | |
293 scoped_refptr<CancelableRequest<ReadCompleteCallback> > request_; | |
294 LogDictionaryType* logs_; | |
295 std::string* zip_content_; | |
296 DISALLOW_COPY_AND_ASSIGN(SyslogsMemoryHandler); | |
297 }; | |
298 | |
222 // Called from FILE thread. | 299 // Called from FILE thread. |
223 void SyslogsProviderImpl::ReadSyslogs( | 300 void SyslogsProviderImpl::ReadSyslogs( |
224 scoped_refptr<CancelableRequest<ReadCompleteCallback> > request, | 301 scoped_refptr<CancelableRequest<ReadCompleteCallback> > request, |
225 bool compress_logs, | 302 bool compress_logs, |
226 SyslogsContext context) { | 303 SyslogsContext context) { |
227 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 304 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
228 | 305 |
229 if (request->canceled()) | 306 if (request->canceled()) |
230 return; | 307 return; |
231 | 308 |
(...skipping 14 matching lines...) Expand all Loading... | |
246 GetSyslogsContextString(context)); | 323 GetSyslogsContextString(context)); |
247 | 324 |
248 std::string* zip_content = NULL; | 325 std::string* zip_content = NULL; |
249 if (compress_logs) { | 326 if (compress_logs) { |
250 // Load compressed logs. | 327 // Load compressed logs. |
251 zip_content = new std::string(); | 328 zip_content = new std::string(); |
252 LoadCompressedLogs(zip_file, zip_content); | 329 LoadCompressedLogs(zip_file, zip_content); |
253 file_util::Delete(zip_file, false); | 330 file_util::Delete(zip_file, false); |
254 } | 331 } |
255 | 332 |
256 // Will call the callback on the calling thread. | 333 // SyslogsMemoryHandler will clean itself up. |
257 request->ForwardResult(Tuple2<LogDictionaryType*, | 334 // SyslogsMemoryHandler::OnDetailsAvailable() will modify |logs| and call |
258 std::string*>(logs, zip_content)); | 335 // request->ForwardResult(logs, zip_content). |
336 scoped_refptr<SyslogsMemoryHandler> | |
337 handler(new SyslogsMemoryHandler(request, logs, zip_content)); | |
338 handler->StartFetch(); | |
259 } | 339 } |
260 | 340 |
261 | |
262 void SyslogsProviderImpl::LoadCompressedLogs(const FilePath& zip_file, | 341 void SyslogsProviderImpl::LoadCompressedLogs(const FilePath& zip_file, |
263 std::string* zip_content) { | 342 std::string* zip_content) { |
264 DCHECK(zip_content); | 343 DCHECK(zip_content); |
265 if (!file_util::ReadFileToString(zip_file, zip_content)) { | 344 if (!file_util::ReadFileToString(zip_file, zip_content)) { |
266 LOG(ERROR) << "Cannot read compressed logs file from " << | 345 LOG(ERROR) << "Cannot read compressed logs file from " << |
267 zip_file.value().c_str(); | 346 zip_file.value().c_str(); |
268 } | 347 } |
269 } | 348 } |
270 | 349 |
271 const char* SyslogsProviderImpl::GetSyslogsContextString( | 350 const char* SyslogsProviderImpl::GetSyslogsContextString( |
(...skipping 21 matching lines...) Expand all Loading... | |
293 SyslogsProvider* SyslogsProvider::GetInstance() { | 372 SyslogsProvider* SyslogsProvider::GetInstance() { |
294 return SyslogsProviderImpl::GetInstance(); | 373 return SyslogsProviderImpl::GetInstance(); |
295 } | 374 } |
296 | 375 |
297 } // namespace system | 376 } // namespace system |
298 } // namespace chromeos | 377 } // namespace chromeos |
299 | 378 |
300 // Allows InvokeLater without adding refcounting. SyslogsProviderImpl is a | 379 // Allows InvokeLater without adding refcounting. SyslogsProviderImpl is a |
301 // Singleton and won't be deleted until it's last InvokeLater is run. | 380 // Singleton and won't be deleted until it's last InvokeLater is run. |
302 DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::system::SyslogsProviderImpl); | 381 DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::system::SyslogsProviderImpl); |
OLD | NEW |