1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/system/diagnostics/routine_log.h"
#include <sstream>
#include <string>
#include "base/i18n/time_formatting.h"
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/sequenced_task_runner.h"
#include "base/time/time.h"
namespace ash {
namespace diagnostics {
namespace {
const char kCancelledDescription[] = "Inflight Routine Cancelled";
const char kNewline[] = "\n";
const char kSeparator[] = " - ";
const char kStartedDescription[] = "Started";
std::string GetCurrentDateTimeAsString() {
return base::UTF16ToUTF8(base::TimeFormatShortDateAndTime(base::Time::Now()));
}
std::string GetRoutineLogCategoryString(RoutineLog::RoutineCategory category) {
switch (category) {
case RoutineLog::RoutineCategory::kNetwork:
return "network";
case RoutineLog::RoutineCategory::kSystem:
return "system";
}
}
std::string getRoutineResultString(mojom::StandardRoutineResult result) {
switch (result) {
case mojom::StandardRoutineResult::kTestPassed:
return "Passed";
case mojom::StandardRoutineResult::kTestFailed:
return "Failed";
case mojom::StandardRoutineResult::kExecutionError:
return "Execution error";
case mojom::StandardRoutineResult::kUnableToRun:
return "Unable to run";
}
}
std::string getRoutineTypeString(mojom::RoutineType type) {
std::stringstream s;
s << type;
const std::string routineName = s.str();
// Remove leading "k" ex: "kCpuStress" -> "CpuStress".
DCHECK_GE(routineName.size(), 1U);
DCHECK_EQ(routineName[0], 'k');
return routineName.substr(1, routineName.size() - 1);
}
// Get the category for the routine `type`.
RoutineLog::RoutineCategory GetRoutineCategory(mojom::RoutineType type) {
switch (type) {
case mojom::RoutineType::kBatteryCharge:
case mojom::RoutineType::kBatteryDischarge:
case mojom::RoutineType::kCpuCache:
case mojom::RoutineType::kCpuStress:
case mojom::RoutineType::kCpuFloatingPoint:
case mojom::RoutineType::kCpuPrime:
case mojom::RoutineType::kMemory:
return RoutineLog::RoutineCategory::kSystem;
case mojom::RoutineType::kLanConnectivity:
case mojom::RoutineType::kSignalStrength:
case mojom::RoutineType::kGatewayCanBePinged:
case mojom::RoutineType::kHasSecureWiFiConnection:
case mojom::RoutineType::kDnsResolverPresent:
case mojom::RoutineType::kDnsLatency:
case mojom::RoutineType::kDnsResolution:
case mojom::RoutineType::kCaptivePortal:
case mojom::RoutineType::kHttpFirewall:
case mojom::RoutineType::kHttpsFirewall:
case mojom::RoutineType::kHttpsLatency:
case mojom::RoutineType::kArcHttp:
case mojom::RoutineType::kArcPing:
case mojom::RoutineType::kArcDnsResolution:
return RoutineLog::RoutineCategory::kNetwork;
};
}
} // namespace
RoutineLog::RoutineLog(const base::FilePath& log_base_path)
: log_base_path_(log_base_path) {}
RoutineLog::~RoutineLog() = default;
void RoutineLog::LogRoutineStarted(mojom::RoutineType type) {
std::stringstream log_line;
log_line << GetCurrentDateTimeAsString() << kSeparator
<< getRoutineTypeString(type) << kSeparator << kStartedDescription
<< kNewline;
Append(type, log_line.str());
}
void RoutineLog::LogRoutineCompleted(mojom::RoutineType type,
mojom::StandardRoutineResult result) {
std::stringstream log_line;
log_line << GetCurrentDateTimeAsString() << kSeparator
<< getRoutineTypeString(type) << kSeparator
<< getRoutineResultString(result) << kNewline;
Append(type, log_line.str());
}
void RoutineLog::LogRoutineCancelled(mojom::RoutineType type) {
std::stringstream log_line;
log_line << GetCurrentDateTimeAsString() << kSeparator
<< kCancelledDescription << kNewline;
Append(type, log_line.str());
}
std::string RoutineLog::GetContentsForCategory(
const RoutineCategory category) const {
const auto iter = logs_.find(category);
if (iter == logs_.end()) {
return "";
}
return iter->second->GetContents();
}
void RoutineLog::Append(mojom::RoutineType type, const std::string& text) {
RoutineCategory category = GetRoutineCategory(type);
// Insert a new log if it doesn't exist then append to it.
base::FilePath log_path = GetCategoryLogFilePath(category);
auto iter = logs_.find(category);
if (iter == logs_.end()) {
iter = logs_.emplace(category, std::make_unique<AsyncLog>(log_path)).first;
}
iter->second->Append(text);
}
base::FilePath RoutineLog::GetCategoryLogFilePath(
const RoutineCategory category) {
std::string name =
"diagnostics_routines_" + GetRoutineLogCategoryString(category) + ".log";
return log_base_path_.Append(name);
}
} // namespace diagnostics
} // namespace ash
|