forked from mirrors/gecko-dev
Bug 1894703 - Set logging modules from a single preference r=padenot
This uses a new preference logging.config.modules. When the user sets a MOZ_LOG string to this preference, it's parsed the same way and the corresponding modules are enabled. Differential Revision: https://phabricator.services.mozilla.com/D209249
This commit is contained in:
parent
4fa8b7bce2
commit
8d1becb7de
5 changed files with 80 additions and 0 deletions
|
|
@ -10,6 +10,7 @@
|
|||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "NSPRLogModulesParser.h"
|
||||
#include "nsString.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "base/process_util.h"
|
||||
|
|
@ -23,6 +24,7 @@ static const char kLoggingPrefLogFile[] = "logging.config.LOG_FILE";
|
|||
static const char kLoggingPrefAddTimestamp[] = "logging.config.add_timestamp";
|
||||
static const char kLoggingPrefSync[] = "logging.config.sync";
|
||||
static const char kLoggingPrefStacks[] = "logging.config.profilerstacks";
|
||||
static const char kLoggingPrefLogModules[] = "logging.config.modules";
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
|
@ -85,6 +87,30 @@ static void LoadPrefValue(const char* aName) {
|
|||
} else if (prefName.EqualsLiteral(kLoggingPrefStacks)) {
|
||||
bool captureStacks = Preferences::GetBool(aName, false);
|
||||
LogModule::SetCaptureStacks(captureStacks);
|
||||
} else if (prefName.EqualsLiteral(kLoggingPrefLogModules)) {
|
||||
// The content of the preference will be parsed as a MOZ_LOG string, then
|
||||
// the corresponding log modules (if any) will be enabled, others will be
|
||||
// disabled.
|
||||
LogModule::DisableModules();
|
||||
|
||||
rv = Preferences::GetCString(aName, prefValue);
|
||||
if (NS_FAILED(rv)) {
|
||||
// If the preference is missing, there's nothing to set.
|
||||
return;
|
||||
}
|
||||
|
||||
NSPRLogModulesParser(
|
||||
prefValue.BeginReading(),
|
||||
[](const char* aName, LogLevel aLevel, int32_t aValue) mutable {
|
||||
// Only the special string "profilerstacks" is taken into account,
|
||||
// because we're especially interested in usage with the Firefox
|
||||
// Profiler.
|
||||
if (strcmp(aName, "profilerstacks") == 0) {
|
||||
LogModule::SetCaptureStacks(true);
|
||||
} else {
|
||||
LogModule::Get(aName)->SetLevel(aLevel);
|
||||
}
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -774,6 +774,13 @@ class LogModuleManager {
|
|||
}
|
||||
}
|
||||
|
||||
void DisableModules() {
|
||||
OffTheBooksMutexAutoLock guard(mModulesLock);
|
||||
for (auto& m : mModules) {
|
||||
(*(m.GetModifiableData()))->SetLevel(LogLevel::Disabled);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
OffTheBooksMutex mModulesLock;
|
||||
nsClassHashtable<nsCharPtrHashKey, LogModule> mModules;
|
||||
|
|
@ -841,6 +848,8 @@ void LogModule::SetCaptureStacks(bool aCaptureStacks) {
|
|||
sLogModuleManager->SetCaptureStacks(aCaptureStacks);
|
||||
}
|
||||
|
||||
void LogModule::DisableModules() { sLogModuleManager->DisableModules(); }
|
||||
|
||||
// This function is defined in gecko_logger/src/lib.rs
|
||||
// We mirror the level in rust code so we don't get forwarded all of the
|
||||
// rust logging and have to create an LogModule for each rust component.
|
||||
|
|
|
|||
|
|
@ -125,6 +125,11 @@ class LogModule {
|
|||
*/
|
||||
static void SetCaptureStacks(bool aCaptureStacks);
|
||||
|
||||
/**
|
||||
* Disable all log modules.
|
||||
*/
|
||||
static void DisableModules();
|
||||
|
||||
/**
|
||||
* Indicates whether or not the given log level is enabled.
|
||||
*/
|
||||
|
|
|
|||
37
xpcom/tests/unit/test_logFromPreference.js
Normal file
37
xpcom/tests/unit/test_logFromPreference.js
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const kModulesPref = "logging.config.modules";
|
||||
add_task(async () => {
|
||||
Services.prefs.setStringPref(kModulesPref, "prof:5");
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref(kModulesPref);
|
||||
});
|
||||
|
||||
const entries = 10000;
|
||||
const interval = 1;
|
||||
const threads = ["GeckoMain"];
|
||||
const features = ["nostacksampling"];
|
||||
await Services.profiler.StartProfiler(entries, interval, features, threads);
|
||||
const profileData = await Services.profiler.getProfileDataAsync();
|
||||
await Services.profiler.StopProfiler();
|
||||
const { markers, stringTable } = profileData.threads[0];
|
||||
const stringIndexForLogMessages = stringTable.indexOf("LogMessages");
|
||||
Assert.greaterOrEqual(
|
||||
stringIndexForLogMessages,
|
||||
0,
|
||||
"A string index for the string LogMessages have been found."
|
||||
);
|
||||
|
||||
// At least one log for the profiler json streaming operation should exist.
|
||||
// See https://searchfox.org/mozilla-central/rev/445a6e86233c733c5557ef44e1d33444adaddefc/mozglue/baseprofiler/core/platform.cpp#2015
|
||||
const logMessageMarkers = markers.data.filter(
|
||||
tuple => tuple[markers.schema.name] === stringIndexForLogMessages
|
||||
);
|
||||
|
||||
Assert.greaterOrEqual(
|
||||
logMessageMarkers.length,
|
||||
0,
|
||||
"At least one log message have been found."
|
||||
);
|
||||
});
|
||||
|
|
@ -58,6 +58,9 @@ fail-if = ["os == 'android'"]
|
|||
|
||||
["test_localfile.js"]
|
||||
|
||||
["test_logFromPreference.js"]
|
||||
skip-if = "(os == 'android' && release_or_beta)" # bug 1841818
|
||||
|
||||
["test_mac_bundle.js"]
|
||||
|
||||
["test_mac_xattrs.js"]
|
||||
|
|
|
|||
Loading…
Reference in a new issue