IAlex has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/125436

Change subject: Improve UDP logging code
......................................................................

Improve UDP logging code

- Use stream_socket_client() instead of socket_create()
  for the UDP socket in wfErrorLog(); the former is part
  of the PHP's standard extension, which, as its name
  does (not) imply, is always available whereas the latter
  is part of an optional extension.
- Split messages in chuncks of 1400 bytes in wfErrorLog(),
  so that they fit well in ethernet frames, and ensure that
  each line is part of one single packet to not confuse UDP
  logging programs
- Use wfErrorLog() in StatCounter and profilers to not have
  same code duplicated multiple times
- Add a note that $wgUDPProfilerHost now accepts IPv6
  addresses if enclosed in squre brackets

Change-Id: Idefed0946a237c6c0885464d5fa1009eb591faac
---
M includes/DefaultSettings.php
M includes/GlobalFunctions.php
M includes/StatCounter.php
M includes/profiler/ProfilerMwprof.php
M includes/profiler/ProfilerSimpleUDP.php
5 files changed, 58 insertions(+), 100 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/36/125436/1

diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php
index 8b8d75c..80603d8 100644
--- a/includes/DefaultSettings.php
+++ b/includes/DefaultSettings.php
@@ -5117,6 +5117,9 @@
 /**
  * Host for UDP profiler.
  *
+ * Either an host name or an IP address. IPv6 addresses are accepted, but must
+ * be enclosed in square brackets (like "[::1]").
+ *
  * The host should be running a daemon which can be obtained from MediaWiki
  * Git at:
  * http://git.wikimedia.org/tree/operations%2Fsoftware.git/master/udpprofile
diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php
index cef19e1..54bb6b1 100644
--- a/includes/GlobalFunctions.php
+++ b/includes/GlobalFunctions.php
@@ -1169,48 +1169,60 @@
  */
 function wfErrorLog( $text, $file ) {
        if ( substr( $file, 0, 4 ) == 'udp:' ) {
-               # Needs the sockets extension
-               if ( preg_match( 
'!^(tcp|udp):(?://)?\[([0-9a-fA-F:]+)\]:(\d+)(?:/(.*))?$!', $file, $m ) ) {
+               if ( preg_match( 
'!^(tcp|udp):(?://)?(\[[0-9a-fA-F:]+\]):(\d+)(?:/(.*))?$!', $file, $m ) ) {
                        // IPv6 bracketed host
+                       $protocol = $m[1];
                        $host = $m[2];
-                       $port = intval( $m[3] );
+                       $port = $m[3];
                        $prefix = isset( $m[4] ) ? $m[4] : false;
-                       $domain = AF_INET6;
                } elseif ( preg_match( 
'!^(tcp|udp):(?://)?([a-zA-Z0-9.-]+):(\d+)(?:/(.*))?$!', $file, $m ) ) {
+                       $protocol = $m[1];
                        $host = $m[2];
-                       if ( !IP::isIPv4( $host ) ) {
-                               $host = gethostbyname( $host );
-                       }
-                       $port = intval( $m[3] );
+                       $port = $m[3];
                        $prefix = isset( $m[4] ) ? $m[4] : false;
-                       $domain = AF_INET;
                } else {
                        throw new MWException( __METHOD__ . ': Invalid UDP 
specification' );
                }
 
-               // Clean it up for the multiplexer
-               if ( strval( $prefix ) !== '' ) {
-                       $text = preg_replace( '/^/m', $prefix . ' ', $text );
-
-                       // Limit to 64KB
-                       if ( strlen( $text ) > 65506 ) {
-                               $text = substr( $text, 0, 65506 );
-                       }
-
-                       if ( substr( $text, -1 ) != "\n" ) {
-                               $text .= "\n";
-                       }
-               } elseif ( strlen( $text ) > 65507 ) {
-                       $text = substr( $text, 0, 65507 );
-               }
-
-               $sock = socket_create( $domain, SOCK_DGRAM, SOL_UDP );
-               if ( !$sock ) {
+               $socket = stream_socket_client( "$protocol://$host:$port" );
+               if ( !$socket ) {
                        return;
                }
 
-               socket_sendto( $sock, $text, strlen( $text ), 0, $host, $port );
-               socket_close( $sock );
+               // Clean it up for the multiplexer
+               if ( $prefix !== false && $parts[1] !== '' ) {
+                       $text = preg_replace( '/^/m', $prefix . ' ', $text );
+               }
+
+               if ( substr( $text, -1 ) != "\n" ) {
+                       $text .= "\n";
+               }
+
+               if ( strlen( $text ) <= 1400 ) {
+                       fwrite( $socket, $text );
+               } else {
+                       // Remove the last item from the array since we ensured 
10 lines
+                       // above that the string was ending by a new line.
+                       $lines = array_slice( explode( "\n", $text ), 0, -1 );
+                       $packet = '';
+                       $packetLen = 0;
+                       foreach ( $lines as $line ) {
+                               // One is for the extra "\n"
+                               $lineLen = strlen( $line ) + 1;
+                               if ( $packetLen + $lineLen > 1400 ) {
+                                       fwrite( $socket, $packet );
+                                       $packet = '';
+                                       $packetLen = 0;
+                               }
+                               $packet .= $line . "\n";
+                               $packetLen += $lineLen;
+                       }
+                       if ( $packet != '' ) {
+                               fwrite( $socket, $packet );
+                       }
+               }
+
+               fclose( $socket );
        } else {
                wfSuppressWarnings();
                $exists = file_exists( $file );
diff --git a/includes/StatCounter.php b/includes/StatCounter.php
index 1373f3d..f3ef34b 100644
--- a/includes/StatCounter.php
+++ b/includes/StatCounter.php
@@ -94,43 +94,18 @@
                global $wgUDPProfilerHost, $wgUDPProfilerPort, 
$wgAggregateStatsID,
                        $wgStatsFormatString;
 
+               if ( !count( $deltas ) ) {
+                       return;
+               }
+
                $id = strlen( $wgAggregateStatsID ) ? $wgAggregateStatsID : 
wfWikiID();
 
-               $lines = array();
+               $text = '';
                foreach ( $deltas as $key => $count ) {
-                       $lines[] = sprintf( $wgStatsFormatString, $id, $count, 
$key );
+                       $text .= sprintf( $wgStatsFormatString, $id, $count, 
$key );
                }
 
-               if ( count( $lines ) ) {
-                       static $socket = null;
-                       if ( !$socket ) {
-                               $socket = socket_create( AF_INET, SOCK_DGRAM, 
SOL_UDP );
-                       }
-                       $packet = '';
-                       $packets = array();
-                       foreach ( $lines as $line ) {
-                               if ( ( strlen( $packet ) + strlen( $line ) ) > 
1450 ) {
-                                       $packets[] = $packet;
-                                       $packet = '';
-                               }
-                               $packet .= $line;
-                       }
-                       if ( $packet != '' ) {
-                               $packets[] = $packet;
-                       }
-                       foreach ( $packets as $packet ) {
-                               wfSuppressWarnings();
-                               socket_sendto(
-                                       $socket,
-                                       $packet,
-                                       strlen( $packet ),
-                                       0,
-                                       $wgUDPProfilerHost,
-                                       $wgUDPProfilerPort
-                               );
-                               wfRestoreWarnings();
-                       }
-               }
+               wfErrorLog( $text, 
"udp://$wgUDPProfilerHost:$wgUDPProfilerPort" );
        }
 
        /**
diff --git a/includes/profiler/ProfilerMwprof.php 
b/includes/profiler/ProfilerMwprof.php
index e7ed6e3..3e86adc 100644
--- a/includes/profiler/ProfilerMwprof.php
+++ b/includes/profiler/ProfilerMwprof.php
@@ -151,9 +151,6 @@
 
                $this->close();
 
-               $sock = socket_create( AF_INET, SOCK_DGRAM, SOL_UDP );
-               socket_connect( $sock, $wgUDPProfilerHost, $wgUDPProfilerPort );
-               $bufferLength = 0;
                $buffer = '';
                foreach ( $this->mCollated as $name => $entry ) {
                        $count = $entry['count'];
@@ -168,23 +165,9 @@
                                        $wall->m1, $wall->m2, $wall->min, 
$wall->max );
                        }
 
-                       $encoded = MWMessagePack::pack( $data );
-                       $length = strlen( $encoded );
+                       $buffer .= MWMessagePack::pack( $data );
+               }
 
-                       // If adding this entry would cause the size of the 
buffer to
-                       // exceed the standard ethernet MTU size less the UDP 
header,
-                       // send all pending data and reset the buffer. 
Otherwise, continue
-                       // accumulating entries into the current buffer.
-                       if ( $length + $bufferLength > 1450 ) {
-                               socket_send( $sock, $buffer, $bufferLength, 0 );
-                               $buffer = '';
-                               $bufferLength = 0;
-                       }
-                       $buffer .= $encoded;
-                       $bufferLength += $length;
-               }
-               if ( $bufferLength !== 0 ) {
-                       socket_send( $sock, $buffer, $bufferLength, 0 );
-               }
+               wfErrorLog( $text, 
"udp://$wgUDPProfilerHost:$wgUDPProfilerPort" );
        }
 }
diff --git a/includes/profiler/ProfilerSimpleUDP.php 
b/includes/profiler/ProfilerSimpleUDP.php
index 982c6ae..e56cf5d 100644
--- a/includes/profiler/ProfilerSimpleUDP.php
+++ b/includes/profiler/ProfilerSimpleUDP.php
@@ -42,14 +42,7 @@
                        return;
                }
 
-               if ( !function_exists( 'socket_create' ) ) {
-                       # Sockets are not enabled
-                       return;
-               }
-
-               $sock = socket_create( AF_INET, SOCK_DGRAM, SOL_UDP );
-               $plength = 0;
-               $packet = "";
+               $text = '';
                foreach ( $this->mCollated as $entry => $pfdata ) {
                        if ( !isset( $pfdata['count'] )
                                || !isset( $pfdata['cpu'] )
@@ -58,18 +51,10 @@
                                || !isset( $pfdata['real_sq'] ) ) {
                                continue;
                        }
-                       $pfline = sprintf( $wgUDPProfilerFormatString, 
$this->getProfileID(), $pfdata['count'],
+                       $text .= sprintf( $wgUDPProfilerFormatString, 
$this->getProfileID(), $pfdata['count'],
                                $pfdata['cpu'], $pfdata['cpu_sq'], 
$pfdata['real'], $pfdata['real_sq'], $entry );
-                       $length = strlen( $pfline );
-                       /* printf("<!-- $pfline -->"); */
-                       if ( $length + $plength > 1400 ) {
-                               socket_sendto( $sock, $packet, $plength, 0, 
$wgUDPProfilerHost, $wgUDPProfilerPort );
-                               $packet = "";
-                               $plength = 0;
-                       }
-                       $packet .= $pfline;
-                       $plength += $length;
                }
-               socket_sendto( $sock, $packet, $plength, 0x100, 
$wgUDPProfilerHost, $wgUDPProfilerPort );
+
+               wfErrorLog( $text, 
"udp://$wgUDPProfilerHost:$wgUDPProfilerPort" );
        }
 }

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Idefed0946a237c6c0885464d5fa1009eb591faac
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: IAlex <coderev...@emsenhuber.ch>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to