Chromium Code Reviews| 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 |