Make the format of UDP-logged stats configurable
authorOri Livneh <ori@wikimedia.org>
Tue, 1 Oct 2013 23:20:45 +0000 (16:20 -0700)
committerOri Livneh <ori@wikimedia.org>
Sat, 5 Oct 2013 05:52:02 +0000 (22:52 -0700)
The format of datagrams generated by StatCounter and ProfilerSimpleUDP is not
described by any standard and appears to have been designed for compatibility
with the logging setup of the Wikimedia Foundation, which limits reusability.

This patch adds two configuration variables, $wgUDPProfilerFormatString and
$wgStatsFormatString, that can be used to specify the precise format that
MediaWiki will use. The default values for these variables causes MediaWiki to
generate the same output as before.

The secret evil plan is to change the defaults so that MediaWiki emits metrics
that are compatible with the popular StatsD format (see
<https://github.com/b/statsd_spec>). This would allow us to replace udpprofiler
with a generic StatsD instance instead.

Change-Id: Iaf00811d3f8d6b89c1c68e84fc1f2c93425d5a2d

RELEASE-NOTES-1.22
includes/DefaultSettings.php
includes/StatCounter.php
includes/profiler/ProfilerSimpleUDP.php

index 7933e06..66fde1a 100644 (file)
@@ -58,6 +58,9 @@ production.
   default Sidebar.
 * The 'vector-simplesearch' preference is now enabled by default. Previously
   it was only enabled if the Vector extension was installed.
+* The precise format of metric datagrams produced by the UDP profiler and stats counter
+  may now be specified as $wgUDPProfilerFormatString and $wgStatsFormatString,
+  respectively.
 
 === New features in 1.22 ===
 * (bug 44525) mediawiki.jqueryMsg can now parse (whitelisted) HTML elements and attributes.
index 19b2f41..a577f71 100644 (file)
@@ -5052,6 +5052,17 @@ $wgUDPProfilerHost = '127.0.0.1';
  */
 $wgUDPProfilerPort = '3811';
 
+/**
+ * Format string for the UDP profiler. The UDP profiler invokes sprintf() with
+ * (profile id, count, cpu, cpu_sq, real, real_sq, entry name) as arguments.
+ * You can use sprintf's argument numbering/swapping capability to repeat,
+ * re-order or omit fields.
+ *
+ * @see $wgStatsFormatString
+ * @since 1.22
+ */
+$wgUDPProfilerFormatString = "%s - %d %f %f %f %f %s\n";
+
 /**
  * Detects non-matching wfProfileIn/wfProfileOut calls
  */
@@ -5078,6 +5089,19 @@ $wgStatsMethod = 'cache';
  */
 $wgAggregateStatsID = false;
 
+/**
+ * When $wgStatsMethod is 'udp', this variable specifies how stats should be
+ * formatted. Its value should be a format string suitable for a sprintf()
+ * invocation with (id, count, key) arguments, where 'id' is either
+ * $wgAggregateStatsID or the DB name, 'count' is the value by which the metric
+ * is being incremented, and 'key' is the metric name.
+ *
+ * @see $wgUDPProfilerFormatString
+ * @see $wgAggregateStatsID
+ * @since 1.22
+ */
+$wgStatsFormatString = "stats/%s - %s 1 1 1 1 %s\n";
+
 /**
  * Whereas to count the number of time an article is viewed.
  * Does not work if pages are cached (for example with squid).
index 374d5ca..1373f3d 100644 (file)
@@ -91,20 +91,20 @@ class StatCounter {
         * @return void
         */
        protected function sendDeltasUDP( array $deltas ) {
-               global $wgUDPProfilerHost, $wgUDPProfilerPort, $wgAggregateStatsID;
+               global $wgUDPProfilerHost, $wgUDPProfilerPort, $wgAggregateStatsID,
+                       $wgStatsFormatString;
 
                $id = strlen( $wgAggregateStatsID ) ? $wgAggregateStatsID : wfWikiID();
 
                $lines = array();
                foreach ( $deltas as $key => $count ) {
-                       $lines[] = "stats/{$id} - {$count} 1 1 1 1 {$key}\n";
+                       $lines[] = sprintf( $wgStatsFormatString, $id, $count, $key );
                }
 
                if ( count( $lines ) ) {
                        static $socket = null;
                        if ( !$socket ) {
                                $socket = socket_create( AF_INET, SOCK_DGRAM, SOL_UDP );
-                               array_unshift( $lines, "stats/{$id} - 1 1 1 1 1 -total\n" );
                        }
                        $packet = '';
                        $packets = array();
index 9204763..0a1f3b1 100644 (file)
@@ -32,7 +32,7 @@ class ProfilerSimpleUDP extends ProfilerSimple {
        }
 
        public function logData() {
-               global $wgUDPProfilerHost, $wgUDPProfilerPort;
+               global $wgUDPProfilerHost, $wgUDPProfilerPort, $wgUDPProfilerFormatString;
 
                $this->close();
 
@@ -57,7 +57,7 @@ class ProfilerSimpleUDP extends ProfilerSimple {
                                || !isset( $pfdata['real_sq'] ) ) {
                                continue;
                        }
-                       $pfline = sprintf( "%s %s %d %f %f %f %f %s\n", $this->getProfileID(), "-", $pfdata['count'],
+                       $pfline = sprintf( $wgUDPProfilerFormatString, $this->getProfileID(), $pfdata['count'],
                                $pfdata['cpu'], $pfdata['cpu_sq'], $pfdata['real'], $pfdata['real_sq'], $entry );
                        $length = strlen( $pfline );
                        /* printf("<!-- $pfline -->"); */