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 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
|
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_POLICY_CORE_COMMON_POLICY_LOGGER_H_
#define COMPONENTS_POLICY_CORE_COMMON_POLICY_LOGGER_H_
#include <deque>
#include <sstream>
#include <string>
#include <string_view>
#include "base/logging.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "base/values.h"
#include "components/policy/policy_export.h"
// Note: the DLOG_POLICY macro has no "#if DCHECK_IS_ON()" check because some
// messages logged with DLOG are still important to be seen on the
// chrome://policy/logs page in release mode. The DLOG call in StreamLog() will
// do the check as usual for command line logging.
#define LOG_POLICY(log_severity, log_source) \
LOG_POLICY_##log_severity(::policy::PolicyLogger::LogHelper::LogType::kLog, \
log_source)
#define DLOG_POLICY(log_severity, log_source) \
LOG_POLICY_##log_severity(::policy::PolicyLogger::LogHelper::LogType::kDLog, \
log_source)
#define VLOG_POLICY(log_verbosity, log_source) \
::policy::PolicyLogger::LogHelper( \
::policy::PolicyLogger::LogHelper::LogType::kVLog, \
::policy::PolicyLogger::Log::Severity::kVerbose, log_verbosity, \
log_source, std::string_view(__FILE__, std::size(__FILE__)), __LINE__)
#define DVLOG_POLICY(log_verbosity, log_source) \
::policy::PolicyLogger::LogHelper( \
::policy::PolicyLogger::LogHelper::LogType::kDLog, \
::policy::PolicyLogger::Log::Severity::kVerbose, log_verbosity, \
log_source, std::string_view(__FILE__, std::size(__FILE__)), __LINE__)
#define LOG_POLICY_INFO(log_type, log_source) \
::policy::PolicyLogger::LogHelper( \
log_type, ::policy::PolicyLogger::Log::Severity::kInfo, \
::policy::PolicyLogger::LogHelper::kNoVerboseLog, log_source, \
std::string_view(__FILE__, std::size(__FILE__)), __LINE__)
#define LOG_POLICY_WARNING(log_type, log_source) \
::policy::PolicyLogger::LogHelper( \
log_type, ::policy::PolicyLogger::Log::Severity::kWarning, \
::policy::PolicyLogger::LogHelper::kNoVerboseLog, log_source, \
std::string_view(__FILE__, std::size(__FILE__)), __LINE__)
#define LOG_POLICY_ERROR(log_type, log_source) \
::policy::PolicyLogger::LogHelper( \
log_type, ::policy::PolicyLogger::Log::Severity::kError, \
::policy::PolicyLogger::LogHelper::kNoVerboseLog, log_source, \
std::string_view(__FILE__, std::size(__FILE__)), __LINE__)
#define POLICY_AUTH ::policy::PolicyLogger::Log::Source::kAuthentication
#define POLICY_PROCESSING ::policy::PolicyLogger::Log::Source::kPolicyProcessing
#define CBCM_ENROLLMENT ::policy::PolicyLogger::Log::Source::kCBCMEnrollment
#define POLICY_FETCHING ::policy::PolicyLogger::Log::Source::kPolicyFetching
#define PLATFORM_POLICY ::policy::PolicyLogger::Log::Source::kPlatformPolicy
#define REMOTE_COMMANDS ::policy::PolicyLogger::Log::Source::kRemoteCommands
#define DEVICE_TRUST ::policy::PolicyLogger::Log::Source::kDeviceTrust
#define OIDC_ENROLLMENT ::policy::PolicyLogger::Log::Source::kOidcEnrollment
#define EXTENSIBLE_SSO ::policy::PolicyLogger::Log::Source::kExtensibleSSO
#define REPORTING ::policy::PolicyLogger::Log::Source::kReporting
namespace policy {
// Collects logs to be displayed in chrome://policy-logs.
class POLICY_EXPORT PolicyLogger {
public:
class POLICY_EXPORT Log {
public:
// The categories for policy log events.
enum class Source {
kPolicyProcessing,
kCBCMEnrollment,
kPolicyFetching,
kPlatformPolicy,
kAuthentication,
kRemoteCommands,
kDeviceTrust,
kOidcEnrollment,
kExtensibleSSO,
kReporting,
};
enum class Severity { kInfo, kWarning, kError, kVerbose };
Log(const Severity log_severity,
const Source log_source,
const std::string& message,
std::string_view file,
const int line);
Log(const Log&) = delete;
Log& operator=(const Log&) = delete;
Log(Log&&) = default;
Log& operator=(Log&&) = default;
~Log() = default;
Severity log_severity() const { return log_severity_; }
Source log_source() const { return log_source_; }
const std::string& message() const { return message_; }
const std::string_view& file() const { return file_; }
int line() const { return line_; }
base::Time timestamp() const { return timestamp_; }
base::Value::Dict GetAsDict() const;
private:
Severity log_severity_;
Source log_source_;
std::string message_;
std::string_view file_;
int line_;
base::Time timestamp_;
};
// Helper class to temporarily hold log information before adding it as a Log
// object to the logs list when it is destroyed.
class POLICY_EXPORT LogHelper {
public:
// Value indicating that the log is not from VLOG, DVLOG, and other verbose
// log macros.
const static int kNoVerboseLog = -1;
enum class LogType { kLog, kDLog, kVLog };
LogHelper(const LogType log_type,
const PolicyLogger::Log::Severity log_severity,
const int log_verbosity,
const PolicyLogger::Log::Source log_source,
std::string_view file,
const int line);
LogHelper(const LogHelper&) = delete;
LogHelper& operator=(const LogHelper&) = delete;
LogHelper(LogHelper&&) = delete;
LogHelper& operator=(LogHelper&&) = delete;
// Moves the log to the list.
~LogHelper();
template <typename T>
LogHelper& operator<<(const T& message) {
message_buffer_ << message;
return *this;
}
// Calls the appropriate base/logging macro.
void StreamLog() const;
private:
LogType log_type_;
PolicyLogger::Log::Severity log_severity_;
int log_verbosity_;
PolicyLogger::Log::Source log_source_;
std::ostringstream message_buffer_;
std::string_view file_;
int line_;
};
static constexpr base::TimeDelta kTimeToLive = base::Minutes(30);
static constexpr size_t kMaxLogsSize = 200;
static PolicyLogger* GetInstance();
PolicyLogger();
PolicyLogger(const PolicyLogger&) = delete;
PolicyLogger& operator=(const PolicyLogger&) = delete;
~PolicyLogger();
// Returns the logs list as base::Value::List to send to UI.
base::Value::List GetAsList();
// Checks if browser is running on Android.
bool IsPolicyLoggingEnabled() const;
// Sets `is_log_deletion_enabled_` to allow scheduling old log deletion.
void EnableLogDeletion();
// Returns the logs size for testing purposes.
size_t GetPolicyLogsSizeForTesting();
// Clears `logs_` and sets `is_log_deletion_scheduled_` as cleanup after every
// test.
void ResetLoggerForTesting();
private:
// Adds a new log to the logs_ list and calls `ScheduleOldLogsDeletion` if
// there is no deletion task scheduled.
void AddLog(Log&& new_log);
// Deletes logs in the list that have been in the list for `kTimeToLive`
// minutes to an hour.
void DeleteOldLogs();
// Posts a new log deletion task and sets the `is_log_deletion_scheduled_`
// flag.
void ScheduleOldLogsDeletion();
// Log deletion scheduling fails in unit tests when there is no task
// environment (See crbug.com/1434241). To avoid having a task environment in
// every existing and new unit test that calls a function with logs, this flag
// is disabled in unit tests, and enabled everywhere else early in the policy
// stack initialization from `BrowserPolicyConnector::Init`.
bool is_log_deletion_enabled_{false};
bool is_log_deletion_scheduled_{false};
base::Lock lock_;
std::deque<Log> logs_ GUARDED_BY(lock_);
base::WeakPtrFactory<PolicyLogger> weak_factory_{this};
};
} // namespace policy
#endif // COMPONENTS_POLICY_CORE_COMMON_POLICY_LOGGER_H_
|