mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Bug 1233881 - Support dynamically setting log levels at runtime via prefs. r=froydnj
Adds support for changing log levels at runtime via 'logging.*' preferences.
This commit is contained in:
parent
5068114946
commit
9664d9a74d
90
xpcom/base/LogModulePrefWatcher.cpp
Normal file
90
xpcom/base/LogModulePrefWatcher.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "LogModulePrefWatcher.h"
|
||||
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsString.h"
|
||||
|
||||
static const char kLoggingPrefPrefix[] = "logging.";
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
NS_IMPL_ISUPPORTS(LogModulePrefWatcher, nsIObserver)
|
||||
|
||||
/**
|
||||
* Loads the log level from the given pref and updates the corresponding
|
||||
* LogModule.
|
||||
*/
|
||||
void
|
||||
LoadPrefValue(const char* aName)
|
||||
{
|
||||
LogLevel logLevel = LogLevel::Disabled;
|
||||
|
||||
int32_t prefLevel = 0;
|
||||
nsAutoCString prefStr;
|
||||
|
||||
if (Preferences::GetInt(aName, &prefLevel) == NS_OK) {
|
||||
logLevel = ToLogLevel(prefLevel);
|
||||
} else if (Preferences::GetCString(aName, &prefStr) == NS_OK) {
|
||||
if (prefStr.LowerCaseEqualsLiteral("error")) {
|
||||
logLevel = LogLevel::Error;
|
||||
} else if (prefStr.LowerCaseEqualsLiteral("warning")) {
|
||||
logLevel = LogLevel::Warning;
|
||||
} else if (prefStr.LowerCaseEqualsLiteral("info")) {
|
||||
logLevel = LogLevel::Info;
|
||||
} else if (prefStr.LowerCaseEqualsLiteral("debug")) {
|
||||
logLevel = LogLevel::Debug;
|
||||
} else if (prefStr.LowerCaseEqualsLiteral("verbose")) {
|
||||
logLevel = LogLevel::Verbose;
|
||||
}
|
||||
}
|
||||
|
||||
const char* moduleName = aName + strlen(kLoggingPrefPrefix);
|
||||
LogModule::Get(moduleName)->SetLevel(logLevel);
|
||||
}
|
||||
|
||||
void
|
||||
LoadExistingPrefs()
|
||||
{
|
||||
uint32_t count;
|
||||
char** names;
|
||||
nsresult rv = Preferences::GetRootBranch()->
|
||||
GetChildList(kLoggingPrefPrefix, &count, &names);
|
||||
if (NS_SUCCEEDED(rv) && count) {
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
LoadPrefValue(names[i]);
|
||||
}
|
||||
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, names);
|
||||
}
|
||||
}
|
||||
|
||||
LogModulePrefWatcher::LogModulePrefWatcher()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
LogModulePrefWatcher::RegisterPrefWatcher()
|
||||
{
|
||||
RefPtr<LogModulePrefWatcher> prefWatcher = new LogModulePrefWatcher();
|
||||
Preferences::AddStrongObserver(prefWatcher, kLoggingPrefPrefix);
|
||||
LoadExistingPrefs();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
LogModulePrefWatcher::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
const char16_t* aData)
|
||||
{
|
||||
if (strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic) == 0) {
|
||||
NS_LossyConvertUTF16toASCII prefName(aData);
|
||||
LoadPrefValue(prefName.get());
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
42
xpcom/base/LogModulePrefWatcher.h
Normal file
42
xpcom/base/LogModulePrefWatcher.h
Normal file
@ -0,0 +1,42 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef LogModulePrefWatcher_h
|
||||
#define LogModulePrefWatcher_h
|
||||
|
||||
#include "nsIObserver.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
/**
|
||||
* Watches for changes to "logging.*" prefs and then updates the appropriate
|
||||
* LogModule's log level. Both the integer and string versions of the LogLevel
|
||||
* enum are supported.
|
||||
*
|
||||
* For example setting the pref "logging.Foo" to "Verbose" will set the
|
||||
* LogModule for "Foo" to the LogLevel::Verbose level. Setting "logging.Bar" to
|
||||
* 4 would set the LogModule for "Bar" to the LogLevel::Debug level.
|
||||
*/
|
||||
class LogModulePrefWatcher : public nsIObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
/**
|
||||
* Starts observing logging pref changes.
|
||||
*/
|
||||
static void RegisterPrefWatcher();
|
||||
|
||||
private:
|
||||
LogModulePrefWatcher();
|
||||
virtual ~LogModulePrefWatcher()
|
||||
{
|
||||
}
|
||||
};
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // LogModulePrefWatcher_h
|
@ -18,11 +18,9 @@
|
||||
const uint32_t kInitialModuleCount = 256;
|
||||
|
||||
namespace mozilla {
|
||||
/**
|
||||
* Safely converts an integer into a valid LogLevel.
|
||||
*/
|
||||
|
||||
LogLevel
|
||||
Clamp(int32_t aLevel)
|
||||
ToLogLevel(int32_t aLevel)
|
||||
{
|
||||
aLevel = std::min(aLevel, static_cast<int32_t>(LogLevel::Verbose));
|
||||
aLevel = std::max(aLevel, static_cast<int32_t>(LogLevel::Disabled));
|
||||
@ -57,7 +55,7 @@ public:
|
||||
// NSPR does not impose a restriction on the values that log levels can
|
||||
// be. LogModule uses the LogLevel enum class so we must clamp the value
|
||||
// to a max of Verbose.
|
||||
LogLevel logLevel = Clamp(prModule->level);
|
||||
LogLevel logLevel = ToLogLevel(prModule->level);
|
||||
module = new LogModule(logLevel);
|
||||
mModules.Put(aName, module);
|
||||
}
|
||||
|
@ -45,6 +45,11 @@ enum class LogLevel {
|
||||
Verbose,
|
||||
};
|
||||
|
||||
/**
|
||||
* Safely converts an integer into a valid LogLevel.
|
||||
*/
|
||||
LogLevel ToLogLevel(int32_t aLevel);
|
||||
|
||||
class LogModule
|
||||
{
|
||||
public:
|
||||
@ -74,6 +79,11 @@ public:
|
||||
*/
|
||||
LogLevel Level() const { return mLevel; }
|
||||
|
||||
/**
|
||||
* Sets the log module's level.
|
||||
*/
|
||||
void SetLevel(LogLevel level) { mLevel = level; }
|
||||
|
||||
private:
|
||||
friend class LogModuleManager;
|
||||
|
||||
|
@ -109,6 +109,7 @@ UNIFIED_SOURCES += [
|
||||
'HoldDropJSObjects.cpp',
|
||||
'JSObjectHolder.cpp',
|
||||
'Logging.cpp',
|
||||
'LogModulePrefWatcher.cpp',
|
||||
'nsConsoleMessage.cpp',
|
||||
'nsConsoleService.cpp',
|
||||
'nsCycleCollector.cpp',
|
||||
|
@ -79,6 +79,7 @@
|
||||
#include "mozilla/Omnijar.h"
|
||||
|
||||
#include "mozilla/Logging.h"
|
||||
#include "LogModulePrefWatcher.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
@ -448,6 +449,20 @@ nsComponentManagerImpl::Init()
|
||||
nsCategoryManager::GetSingleton()->SuppressNotifications(false);
|
||||
|
||||
RegisterWeakMemoryReporter(this);
|
||||
|
||||
// NB: The logging preference watcher needs to be registered late enough in
|
||||
// startup that it's okay to use the preference system, but also as soon as
|
||||
// possible so that log modules enabled via preferences are turned on as
|
||||
// early as possible.
|
||||
//
|
||||
// We can't initialize the preference watcher when the log module manager is
|
||||
// initialized, as a number of things attempt to start logging before the
|
||||
// preference system is initialized.
|
||||
//
|
||||
// The preference system is registered as a component so at this point during
|
||||
// component manager initialization we know it is setup and we can register
|
||||
// for notifications.
|
||||
LogModulePrefWatcher::RegisterPrefWatcher();
|
||||
#endif
|
||||
|
||||
// Unfortunately, we can't register the nsCategoryManager memory reporter
|
||||
|
Loading…
Reference in New Issue
Block a user