diff --git a/RELEASE-NOTES-1.27 b/RELEASE-NOTES-1.27
index ac19d39952f..915b93bc0e3 100644
--- a/RELEASE-NOTES-1.27
+++ b/RELEASE-NOTES-1.27
@@ -175,6 +175,12 @@ HHVM 3.1.
be a good idea, but will log out all current sessions.
* $wgEventRelayerConfig was added, for managing PubSub event relay configuration,
specifically for reliable CDN url purges.
+* Requests have unique IDs, equal to the UNIQUE_ID environment variable (when
+ MediaWiki is behind Apache+mod_unique_id or something similar) or a randomly-
+ generated 24-character string. This request ID is used to annotate log records
+ and error messages. It is available client-side via mw.config.get( 'wgRequestId' ).
+ The request ID supplants exception IDs. Accordingly, MWExceptionHandler::getLogId()
+ is deprecated.
=== External library changes in 1.27 ===
diff --git a/includes/OutputPage.php b/includes/OutputPage.php
index 0c3d60929e1..3c0dc18b6c3 100644
--- a/includes/OutputPage.php
+++ b/includes/OutputPage.php
@@ -3210,6 +3210,7 @@ class OutputPage extends ContextSource {
'wgMonthNamesShort' => $lang->getMonthAbbreviationsArray(),
'wgRelevantPageName' => $relevantTitle->getPrefixedDBkey(),
'wgRelevantArticleId' => $relevantTitle->getArticleID(),
+ 'wgRequestId' => WebRequest::getRequestId(),
];
if ( $user->isLoggedIn() ) {
diff --git a/includes/WebRequest.php b/includes/WebRequest.php
index 812a320f91c..f4b4871ee95 100644
--- a/includes/WebRequest.php
+++ b/includes/WebRequest.php
@@ -246,6 +246,25 @@ class WebRequest {
return microtime( true ) - $this->requestTime;
}
+ /**
+ * Get the unique request ID.
+ * This is either the value of the UNIQUE_ID envvar (if present) or a
+ * randomly-generated 24-character string.
+ *
+ * @return string
+ * @since 1.27
+ */
+ public static function getRequestId() {
+ static $reqId;
+
+ if ( !$reqId ) {
+ $reqId = isset( $_SERVER['UNIQUE_ID'] )
+ ? $_SERVER['UNIQUE_ID'] : wfRandomString( 24 );
+ }
+
+ return $reqId;
+ }
+
/**
* Get the current URL protocol (http or https)
* @return string
diff --git a/includes/api/ApiMain.php b/includes/api/ApiMain.php
index 63b79ac3eb5..5566d317754 100644
--- a/includes/api/ApiMain.php
+++ b/includes/api/ApiMain.php
@@ -871,7 +871,7 @@ class ApiMain extends ApiBase {
$errMessage = [
'code' => 'internal_api_error_' . get_class( $e ),
- 'info' => '[' . MWExceptionHandler::getLogId( $e ) . '] ' . $info,
+ 'info' => '[' . WebRequest::getRequestId() . '] ' . $info,
];
}
return $errMessage;
diff --git a/includes/debug/logger/monolog/WikiProcessor.php b/includes/debug/logger/monolog/WikiProcessor.php
index 7f60f2e2e79..e3c048dae52 100644
--- a/includes/debug/logger/monolog/WikiProcessor.php
+++ b/includes/debug/logger/monolog/WikiProcessor.php
@@ -21,7 +21,8 @@
namespace MediaWiki\Logger\Monolog;
/**
- * Injects `wfHostname()`, `wfWikiID()` and `$wgVersion` in all records.
+ * Annotate log records with request-global metadata, such as the hostname,
+ * wiki / request ID, and MediaWiki version.
*
* @since 1.25
* @author Bryan Davis