jenkins-bot has submitted this change and it was merged.

Change subject: Add structured API request debug logging
......................................................................


Add structured API request debug logging

Add a new "ApiRequest" PSR-3 logging channel for messages that describe
an Action API request as structured data. This logging channel can be
routed to a storage service to facilitate analysis of the requests.

The logging context is designed to match the following avro schema:

  {
      "type": "record",
      "name": "ApiRequest",
      "namespace": "org.wikimedia.mediawiki.api",
      "doc": "Describes an API request made via mediawiki ApiMain",
      "fields": [
          { "name": "dt",              "type": "string" },
          { "name": "client_ip",       "type": "string" },
          { "name": "user_agent",      "type": "string" },
          { "name": "wiki",            "type": "string" },
          { "name": "time_backend_ms", "type": "int" },
          { "name": "params",          "type": {
              "type": "map", "values": "string"
          } }
      ]
  }

Co-Author: Bryan Davis <[email protected]>
Bug: T108618
Change-Id: I38f5cdb288f332f75adca8a2d03fbe0fc36ab936
---
M includes/api/ApiMain.php
1 file changed, 27 insertions(+), 13 deletions(-)

Approvals:
  Anomie: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/includes/api/ApiMain.php b/includes/api/ApiMain.php
index 2768409..9d983d9 100644
--- a/includes/api/ApiMain.php
+++ b/includes/api/ApiMain.php
@@ -1289,31 +1289,45 @@
 
        /**
         * Log the preceding request
-        * @param int $time Time in seconds
+        * @param float $time Time in seconds
         */
        protected function logRequest( $time ) {
                $request = $this->getRequest();
-               $milliseconds = $time === null ? '?' : round( $time * 1000 );
-               $s = 'API' .
-                       ' ' . $request->getMethod() .
-                       ' ' . wfUrlencode( str_replace( ' ', '_', 
$this->getUser()->getName() ) ) .
-                       ' ' . $request->getIP() .
-                       ' T=' . $milliseconds . 'ms';
+               $logCtx = array(
+                       'dt' => date( 'c' ),
+                       'client_ip' => $request->getIP(),
+                       'user_agent' => $this->getUserAgent(),
+                       'wiki' => wfWikiId(),
+                       'time_backend_ms' => round( $time * 1000 ),
+                       'params' => array(),
+               );
+
+               // Construct space separated message for 'api' log channel
+               $msg = "API {$request->getMethod()} " .
+                       wfUrlencode( str_replace( ' ', '_', 
$this->getUser()->getName() ) ) .
+                       " {$logCtx['client_ip']} " .
+                       "T={$logCtx['time_backend_ms']}ms";
+
                foreach ( $this->getParamsUsed() as $name ) {
                        $value = $request->getVal( $name );
                        if ( $value === null ) {
                                continue;
                        }
-                       $s .= ' ' . $name . '=';
+
                        if ( strlen( $value ) > 256 ) {
-                               $encValue = $this->encodeRequestLogValue( 
substr( $value, 0, 256 ) );
-                               $s .= $encValue . '[...]';
+                               $value = substr( $value, 0, 256 );
+                               $encValue = $this->encodeRequestLogValue( 
$value ) . '[...]';
                        } else {
-                               $s .= $this->encodeRequestLogValue( $value );
+                               $encValue = $this->encodeRequestLogValue( 
$value );
                        }
+
+                       $logCtx['params'][$name] = $value;
+                       $msg .= " {$name}={$encValue}";
                }
-               $s .= "\n";
-               wfDebugLog( 'api', $s, 'private' );
+
+               wfDebugLog( 'api', $msg, 'private' );
+               // ApiRequest channel is for structured data consumers
+               wfDebugLog( 'ApiRequest', '', 'private', $logCtx );
        }
 
        /**

-- 
To view, visit https://gerrit.wikimedia.org/r/240614
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I38f5cdb288f332f75adca8a2d03fbe0fc36ab936
Gerrit-PatchSet: 10
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: EBernhardson <[email protected]>
Gerrit-Reviewer: Addshore <[email protected]>
Gerrit-Reviewer: Anomie <[email protected]>
Gerrit-Reviewer: BryanDavis <[email protected]>
Gerrit-Reviewer: CSteipp <[email protected]>
Gerrit-Reviewer: EBernhardson <[email protected]>
Gerrit-Reviewer: GergÅ‘ Tisza <[email protected]>
Gerrit-Reviewer: Ottomata <[email protected]>
Gerrit-Reviewer: Spage <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to