* Deprecate ::setProfileID(). This was added in r17776 to allow callers
(e.g. LocalSettings.php and StartProfiler.php, outside Git) to change
the ID at runtime. Site admins don't seem to do this in practice.
We have since then introduced request IDs, and the ability to
declaratively describe the Profiler singleton via $wgProfiler,
where 'profileID' is already supported nowadays.
The propertly can stil be set for other purposes by sub-classes.
* Remove ::setContext() and ::getContext() which was already hard
deprecated a while ago (1.38).
* Deprecate ::getAllowOutput() which is unused.
* Profiler::$context has been removed too since the methods consuming
this member has been removed.
Change-Id: Id2ff252e506d4445e68e1e944d44f3b4b0bdbdb4
* Illegal string offset and invalid argument supplied to foreach, due to incorrect type information
* Array internal pointer reset is unnecessary
* $hookData unused since MW 1.35 due to incomplete revert
* array_push() with single element
* Unnecessary sprintf()
* for loop can be replaced with str_repeat()
* preg_replace() can be replaced with rtrim()
* array_values() call is redundant
* Unnecessary cast to string
* Unnecessary ternary. Often the result relies on short-circuit evaluation, but I find it more readable nonetheless.
Change-Id: I4c45bdb59b51b243fa96286bec8b58deb097d707
== Status quo
In web requests we have:
* Setup.php: Load LocalSettings.php (CommonSettings.php in prod),
which may assign $wgProfiler, e.g. if X-Wikimedia-Debug is used.
* Setup.php: Pass global to Profiler::init().
No Profiler::instance() singleton calls exist until after this point,
which is good as otherwise it'd initialise the singleton incorrectly.
In maintenance scripts, today we have the following broken sequence:
* doMaintenance: Load MaintenanceRunner.
* MaintenanceRunner: Register the '--profiler' option.
* doMaintenance: Define MW_FINAL_SETUP_CALLBACK.
* doMaintenance: Load Setup.php.
* Setup.php: Load LocalSettings.php
* Setup.php: Call MW_FINAL_SETUP_CALLBACK
** calls MaintenanceRunner::setup
** calls MaintenanceRunner::activateProfiler
** this constructs the Profiler object directly (duplicating Profiler::init)
and saves the singleton via Profiler::replaceStubInstance.
The activateProfiler() method also uses the singleton to enable
outputting of results at shutdown, and set Rdbms warning limits.
* Setup.php: Call $wgSettings->apply().
* Setup.php: Pass global to Profiler::init().
** It wipes the singleton we just made.
** It re-creates it based on $wgProfiler, which MaintenanceRunner
failed to overwrite (it used to, but this was lost when
SettingsBuilder and MaintenanceRunner were introduced).
** It explicitly forces ProfilerStub in CLI mode, thus even if
$wgProfiler was assigned, it would still not work.
== Change
The above made sense prior to the MaintenanceRunner and
SettingsBuilder refactoring when more of Setup.php ran before
Maintenance began doing its thing, and thus it made sense that
Setup's Profiler::init call would force stub for CLI mode, and then
let Maintenance use replaceStubInstance to replace it afterward, but
the order has changed.
I'm using this oppertunity to get rid of the "replace afterwards"
approach and instead use SettingsBuilder to set wgProfiler correctly
in the first place, and further more recognise the concept of
CLI-enablement as an explicit (internal) option to avoid a conflict
between these two requirements.
Note that this isn't the first time it broke. It also broke some time
before 2014 when change I35faedff818af2ad45 restored its behaviour.
== Test plan
* Using MediaWiki-Docker which includes tideways_xhprof, and set the
snippet in LocalSettings to set $wgProfiler:
<https://www.mediawiki.org/wiki/MediaWiki-Docker/Configuration_recipes/Profiling>
* Confirm that view-source:/wiki/Main_Page contains no profiler output.
* Confirm that view-source:/wiki/Main_Page?forceprofile=1 does.
* Confirm that `php maintenance/showJobs.php` and
`php maintenance/showJobs.php --profile text` both don't print
a profile today.
* Apply this change.
* `php maintenance/showJobs.php --profile text` now prints a profile.
Change-Id: Ia1a86f0443bf7ae746811e9de5dda89f20ad446f
This makes it easy to create alerts based on graphite metrics.
Each (event name, HTTP method) pair will have a counter metric,
with *.rate measuring the rate of requests violating the rule.
Bug: T258125
Change-Id: I7de56fbdfde25fa8f695416ddf27e2fe357b71dc
Follows-up I58ff3c193190d78a. Small step toward not run-time reading
the global (and using Config here is non-trivial/unsafe).
Change-Id: Ic527e493baabe700c50f75fadaa5b51615a5e597
This was breaking HttpRequestFactoryTest for me, because it adds
$wgProfiler to an array and $wgProfiler is null in unit tests. The
suppressed PHAN warning was actually quite correct -- there was no
guarantee that $wgProfiler was set!
What I'm not clear on is how this test worked for anyone else.
Change-Id: I58ff3c193190d78a2591d9450cb7f2dae5d4a997
Make phan stricter about conditional variable declaration
Remaining false positive issues are suppressed.
The suppression and the setting change can only be done together
Bug: T259172
Change-Id: I1f200ac37df7448453688bf464a8250c97313e5d
I intent to remove Profiler::getContext/setContext after a week
without deprecation. I consider these methods as internal (they
predate the stable interface policy, and we forgot to triage this
class, it has neither `@stable` nor `@internal`).
The hard-deprecation in this commit is to detect any use that may
have gone unnoticed in WMF production from Codesearch analysis alone,
where no usage was found.
Bug: T292269
Change-Id: Id40679f21cc7a3f77a1b96a4bbd55daeaea16892
* Use the "profiler" channel consistently within this component,
and set it in the constructor of the base classes.
* Fold legacy "profilererror" channel into "profiler".
Previously, the wfDebugLog wrapper was using the INFO severity,
which is the default given wfDebugLog does not support severity.
Change-Id: I1e7dcbc221b395a4ea792e18f4d4da36b5ee40df
A terminating line break has not been required in wfDebug() since 2014,
however no migration was done. Some of these line breaks found their way
into LoggerInterface::debug() calls, where they mess up the formatting
of the debug log.
So, remove terminating line breaks from wfDebug() and
LoggerInterface::debug() calls.
Also:
* Fix the stripping of leading line breaks from the log header emitted
by Setup.php. This feature, accidentally broken in 2014, allows
requests to be distinguished in the log file.
* Avoid using the global variable $self.
* Move the logging of the client IP back to Setup.php. It was moved to
WebRequest in the hopes that it would not always be needed, however
$wgRequest->getIP() is now called unconditionally a few lines up in
Setup.php. This means that it is put in its proper place after the
"start request" message.
* Wrap the log header code in a closure so that variables like $name do
not leak into global scope.
* In Linker.php, remove a few instances of an unnecessary second
parameter to wfDebug().
Change-Id: I96651d3044a95b9d210b51cb8368edc76bebbb9e
* Remove redundant file description for files that only define
a class where the class description suffices.
* Ensure the file has a license header and @file.
* Remove any @ingroup from the file comment block.
These clutter the Doxygen pages with duplicate entries.
* Ensure the class block has an @ingroup set.
* Remove @since when @internal is set.
* Add any missing @since to public classes that were created
recently enough to easily find out when:
- ProfilerExcimer was introduced in 1.33 (6373e3d1d4).
Change-Id: I6b18289a15a3085857acd7c9004ec819f7914b29
Make it Profiler.php's responsibility to enforce this, based on the
existing signal from ProfilerOutput::logsToOutput().
The ProfilerOutputText class should not have to double-check this
a second time.
Long-term, I'd like even this check in Profiler::logDataPageOutputOnly
to be removed, because really the external caller of that should
know whether it is safe to output stuff or not rather than stashing
its own state inside Profiler::$allowOutput and then implicitly
reading it back out again later on. But, that's for another time.
Also:
* Remove use of deprecated Profiler::setTemplated while at it.
* Make 'visible' parameter explicit, as for other parameters.
Change-Id: Iaa3fc4ea25a059b90235d769db60c04b8f152f05
This is set from three places:
1) SkinTemplate.php, 2) Maintenance.php, and 3) load.php.
These last two are very much *not* HTML-templated output.
Rename these this method pair to getAllowOutput/setAllowOutput instead,
which is less confusing going forward. No known callers outside of
core (updated in the next commit), but I'll keep compat for one
release cycle just in case.
Change-Id: I828f95332dca3c6766b2b485ffb71762542b42d7
phpdbg is a gdb-style debugger for PHP that is run from the command
line. However, it has a different PHP_SAPI value, so it was impossible
to run maintenance scripts with it (until now).
To avoid having to check both PHP_SAPI values in a bunch of places,
introduce wfIsCLI() to easily check whether running from the
command-line or not.
We're (CI team) interested in generating code coverage with phpdbg
instead of xdebug, hence this patch.
Bug: T184043
Change-Id: Id1f994ca146d7858cd8bb6ab6cdbb7718ff524fb
Avoids "Argument 1 passed to Profiler::scopedProfileOut() must
be an instance of ScopedCallback, SectionProfileCallback given"
Change-Id: I92713de71df9722d8a5d7e5cd04460aff71cf096
This uses a non-standard output and requires a custom
collector that wmf does not maintain nor use anymore.
Change-Id: I41a68f7061465417fbdc5ca41f8eb6e1f99f1111
* Added doPreOutputCommit() and doPostOutputShutdown(),
which most entry points just using the later
* Also fixed problem where text profiling did not show up
* Avoid calling triggerJobs() in the file streaming
entry points
Bug: T100127
Bug: T100085
Change-Id: Ibc7e768fd483389a01847f08cdeba4058c853d3f
Instead of maintaining a mapping of short names to class names ('db' =>
'ProfilerOutputDb', etc.), let us adopt the convention of using the full
class name to indicate the output type. We can maintain backward-compatibility
by using simple string manipulation to transform short names to the full class
names.
Change-Id: I976e0da2873d88b9892fb41823cfe3af0a2d3974
* Associate Profiler objects with a request context by adding a $context
property with a getter and a setter.
* Introduce ProfilerOutputStats, which writes profiling data to the stats
buffer associated with the current request context.
* Make it the Profiler class's responsibility to enforce $wgProfilerLimit.
* Deprecate $wgProfilerLimit in favor of the (more aptly named, IMO)
$wgProfiler['threshold'] config setting.
* Tidy up Profiler instance creation code in Profiler::instance().
* Add Profiler::getOutputs, which returns an array of ProfilerOutput instances
which are configured for the current profiler and whose canUse() method
returns true.
* Make ProfilerStub not log by creating a stub ProfilerStub::logData() method
which does not call the parent. Previously the parent class checked if $this
was an instance of ProfilerStub and returned early if so.
Task: T90623
Task: T85641
Change-Id: Icf644ad3435c1f30d0a49957a97b481808a3153d
* This can happen well over 10k times per request due to the message
hooks. Avoiding the object construction seems prudent.
Change-Id: I45ff7b8c10851f15a25cbea9a2df3669ec21dbd3