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