Localisation updates from https://translatewiki.net.
[mediawiki.git] / includes / http / Telemetry.php
blob231f8f274873c93cd6f859cfc4bfa6d163f23569
1 <?php
2 /**
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
18 * @file
20 namespace MediaWiki\Http;
22 use Wikimedia\Http\TelemetryHeadersInterface;
24 /**
25 * Service for handling telemetry data
26 * @unstable
27 * @since 1.41
29 class Telemetry implements TelemetryHeadersInterface {
31 /**
32 * @var Telemetry|null
34 private static ?Telemetry $instance = null;
36 /**
38 * @var string|null Request id
40 private ?string $reqId = null;
42 /**
43 * Server and execution environment information.
45 * @see https://www.php.net/manual/en/reserved.variables.server.php
46 * @var array
48 private array $server;
50 private ?bool $allowExternalReqID;
52 /**
53 * @param array $server Server and execution environment information, most likely the $_SERVER variable
55 public function __construct( array $server, ?bool $allowExternalReqID = null ) {
56 $this->server = $server;
57 $this->allowExternalReqID = $allowExternalReqID;
60 public static function getInstance(): Telemetry {
61 if ( !self::$instance ) {
62 global $wgAllowExternalReqID;
63 self::$instance = new self( $_SERVER, $wgAllowExternalReqID );
66 return self::$instance;
69 /**
70 * Get the current request ID.
72 * This is usually based on the `X-Request-Id` header, or the `UNIQUE_ID`
73 * environment variable, falling back to (process cached) randomly-generated string.
75 * @return string
77 public function getRequestId(): string {
78 // This method is called from various error handlers and MUST be kept simple and stateless.
79 if ( $this->reqId === null ) {
80 if ( $this->allowExternalReqID ) {
81 $id = ( $this->server['HTTP_X_REQUEST_ID'] ?? $this->server['UNIQUE_ID'] ?? wfRandomString( 24 ) );
82 } else {
83 $id = ( $this->server['UNIQUE_ID'] ?? wfRandomString( 24 ) );
86 $this->reqId = $id;
89 return $this->reqId;
92 /**
93 * Override the unique request ID. This is for sub-requests, such as jobs,
94 * that wish to use the same id but are not part of the same execution context.
96 * @param string $newId
98 public function overrideRequestId( string $newId ): void {
99 $this->reqId = $newId;
103 * Regenerate the request id by setting it to null, next call to `getRequestId`
104 * will refetch the request id from header/UNIQUE_ID or regenerate it.
105 * @return void
107 public function regenerateRequestId() {
108 $this->reqId = null;
112 * Get the OpenTelemetry tracestate info
113 * Returns null when not present or AllowExternalReqID is set to false
115 * @return string|null
117 public function getTracestate(): ?string {
118 return $this->allowExternalReqID ? $this->server['HTTP_TRACESTATE'] ?? null : null;
122 * Get the OpenTelemetry traceparent info,
123 * Returns null when not present or AllowExternalReqID is set to false
125 * @return string|null
127 public function getTraceparent(): ?string {
128 return $this->allowExternalReqID ? $this->server['HTTP_TRACEPARENT'] ?? null : null;
132 * Return Telemetry data in form of request headers
133 * @return array
135 public function getRequestHeaders(): array {
136 return array_filter( [
137 'tracestate' => $this->getTracestate(),
138 'traceparent' => $this->getTraceparent(),
139 'X-Request-Id' => $this->getRequestId()
140 ] );