Gergő Tisza has uploaded a new change for review.
https://gerrit.wikimedia.org/r/226641
Change subject: Update liuggio/statsd-php-client: v1.0.12 -> v1.0.16
......................................................................
Update liuggio/statsd-php-client: v1.0.12 -> v1.0.16
core patch: I6e013485175c63a984d2de205dc45704483d149b
Bug: T106457
Change-Id: I307b58f4abe4d615ac9b2f86f50d0c5d6b906d83
---
M composer.json
M composer.lock
M composer/autoload_classmap.php
M composer/installed.json
A liuggio/statsd-php-client/CHANGELOG.md
R liuggio/statsd-php-client/README.md
M liuggio/statsd-php-client/composer.json
R liuggio/statsd-php-client/phpunit.xml
M liuggio/statsd-php-client/src/Liuggio/StatsdClient/Entity/StatsdData.php
M
liuggio/statsd-php-client/src/Liuggio/StatsdClient/Entity/StatsdDataInterface.php
A liuggio/statsd-php-client/src/Liuggio/StatsdClient/Service/StatsdService.php
M liuggio/statsd-php-client/src/Liuggio/StatsdClient/StatsdClient.php
A
liuggio/statsd-php-client/tests/Liuggio/StatsdClient/Service/StatsdServiceTest.php
13 files changed, 408 insertions(+), 77 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/vendor
refs/changes/41/226641/1
diff --git a/composer.json b/composer.json
index 58cb882..f39dadc 100644
--- a/composer.json
+++ b/composer.json
@@ -2,7 +2,7 @@
"require": {
"cssjanus/cssjanus": "1.1.1",
"leafo/lessphp": "0.5.0",
- "liuggio/statsd-php-client": "1.0.12",
+ "liuggio/statsd-php-client": "1.0.16",
"kzykhys/pygments": "1.0",
"php": ">=5.3.3",
"psr/log": "1.0.0",
diff --git a/composer.lock b/composer.lock
index 2687e5c..fbb6606 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at
https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "hash": "af634b8b312618a08a2034c5ced2d1e2",
+ "hash": "88a5c97aa15fe4a052b5a37bb6bc12c1",
"packages": [
{
"name": "cssjanus/cssjanus",
@@ -115,20 +115,20 @@
},
{
"name": "liuggio/statsd-php-client",
- "version": "v1.0.12",
+ "version": "v1.0.16",
"source": {
"type": "git",
"url": "https://github.com/liuggio/statsd-php-client.git",
- "reference": "a8c9ccd2a3af6cc49c7fc4f5f689d7b148ab19d7"
+ "reference": "a84fbef1a7afbfafd0ca4f1ebae4935bd1a7d920"
},
"dist": {
"type": "zip",
- "url":
"https://api.github.com/repos/liuggio/statsd-php-client/zipball/a8c9ccd2a3af6cc49c7fc4f5f689d7b148ab19d7",
- "reference": "a8c9ccd2a3af6cc49c7fc4f5f689d7b148ab19d7",
+ "url":
"https://api.github.com/repos/liuggio/statsd-php-client/zipball/a84fbef1a7afbfafd0ca4f1ebae4935bd1a7d920",
+ "reference": "a84fbef1a7afbfafd0ca4f1ebae4935bd1a7d920",
"shasum": ""
},
"require": {
- "php": ">=5.2"
+ "php": ">=5.3.2"
},
"require-dev": {
"monolog/monolog": ">=1.2.0"
@@ -160,7 +160,7 @@
"php",
"statsd"
],
- "time": "2014-09-17 21:37:49"
+ "time": "2015-04-27 08:12:26"
},
{
"name": "mediawiki/at-ease",
diff --git a/composer/autoload_classmap.php b/composer/autoload_classmap.php
index b346fe7..a8d8445 100644
--- a/composer/autoload_classmap.php
+++ b/composer/autoload_classmap.php
@@ -343,6 +343,7 @@
'Liuggio\\StatsdClient\\Sender\\SenderInterface' => $vendorDir .
'/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Sender/SenderInterface.php',
'Liuggio\\StatsdClient\\Sender\\SocketSender' => $vendorDir .
'/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Sender/SocketSender.php',
'Liuggio\\StatsdClient\\Sender\\SysLogSender' => $vendorDir .
'/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Sender/SysLogSender.php',
+ 'Liuggio\\StatsdClient\\Service\\StatsdService' => $vendorDir .
'/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Service/StatsdService.php',
'Liuggio\\StatsdClient\\StatsdClient' => $vendorDir .
'/liuggio/statsd-php-client/src/Liuggio/StatsdClient/StatsdClient.php',
'Liuggio\\StatsdClient\\StatsdClientInterface' => $vendorDir .
'/liuggio/statsd-php-client/src/Liuggio/StatsdClient/StatsdClientInterface.php',
'Monolog\\ErrorHandler' => $vendorDir .
'/monolog/monolog/src/Monolog/ErrorHandler.php',
diff --git a/composer/installed.json b/composer/installed.json
index 5965594..2734067 100644
--- a/composer/installed.json
+++ b/composer/installed.json
@@ -227,57 +227,6 @@
"homepage": "https://www.mediawiki.org/wiki/CDB"
},
{
- "name": "liuggio/statsd-php-client",
- "version": "v1.0.12",
- "version_normalized": "1.0.12.0",
- "source": {
- "type": "git",
- "url": "https://github.com/liuggio/statsd-php-client.git",
- "reference": "a8c9ccd2a3af6cc49c7fc4f5f689d7b148ab19d7"
- },
- "dist": {
- "type": "zip",
- "url":
"https://api.github.com/repos/liuggio/statsd-php-client/zipball/a8c9ccd2a3af6cc49c7fc4f5f689d7b148ab19d7",
- "reference": "a8c9ccd2a3af6cc49c7fc4f5f689d7b148ab19d7",
- "shasum": ""
- },
- "require": {
- "php": ">=5.2"
- },
- "require-dev": {
- "monolog/monolog": ">=1.2.0"
- },
- "suggest": {
- "monolog/monolog": "Monolog, in order to do generate statistic
from log >=1.2.0)"
- },
- "time": "2014-09-17 21:37:49",
- "type": "library",
- "installation-source": "dist",
- "autoload": {
- "psr-0": {
- "Liuggio": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Giulio De Donato",
- "email": "[email protected]"
- }
- ],
- "description": "Statsd (Object Oriented) client library for PHP",
- "homepage": "https://github.com/liuggio/statsd-php-client/",
- "keywords": [
- "etsy",
- "monitoring",
- "php",
- "statsd"
- ]
- },
- {
"name": "wikimedia/utfnormal",
"version": "v1.0.2",
"version_normalized": "1.0.2.0",
@@ -760,5 +709,56 @@
],
"description": "Provides library of common widgets, layouts, and
windows.",
"homepage": "https://www.mediawiki.org/wiki/OOjs_UI"
+ },
+ {
+ "name": "liuggio/statsd-php-client",
+ "version": "v1.0.16",
+ "version_normalized": "1.0.16.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/liuggio/statsd-php-client.git",
+ "reference": "a84fbef1a7afbfafd0ca4f1ebae4935bd1a7d920"
+ },
+ "dist": {
+ "type": "zip",
+ "url":
"https://api.github.com/repos/liuggio/statsd-php-client/zipball/a84fbef1a7afbfafd0ca4f1ebae4935bd1a7d920",
+ "reference": "a84fbef1a7afbfafd0ca4f1ebae4935bd1a7d920",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.2"
+ },
+ "require-dev": {
+ "monolog/monolog": ">=1.2.0"
+ },
+ "suggest": {
+ "monolog/monolog": "Monolog, in order to do generate statistic
from log >=1.2.0)"
+ },
+ "time": "2015-04-27 08:12:26",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-0": {
+ "Liuggio": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Giulio De Donato",
+ "email": "[email protected]"
+ }
+ ],
+ "description": "Statsd (Object Oriented) client library for PHP",
+ "homepage": "https://github.com/liuggio/statsd-php-client/",
+ "keywords": [
+ "etsy",
+ "monitoring",
+ "php",
+ "statsd"
+ ]
}
]
diff --git a/liuggio/statsd-php-client/CHANGELOG.md
b/liuggio/statsd-php-client/CHANGELOG.md
new file mode 100644
index 0000000..e7ee9a4
--- /dev/null
+++ b/liuggio/statsd-php-client/CHANGELOG.md
@@ -0,0 +1,17 @@
+CHANGELOG for 1.x.x
+===================
+
+This changelog references the relevant changes (bug and security fixes) done
+in 1.x.x minor.
+
+To get the diff for a specific change, go to
https://github.com/liuggio/statsd-php-client/commit/XXX where XXX is the change
hash
+To get the diff between two versions, go to
https://github.com/liuggio/statsd-php-client/compare/v1.0.12...v1.0.13
+
+### 1.0.14, 1.0.16
+ * fix minor casing issue
+ * php 5.3.2 instead of php5.2
+
+### 1.0.13
+ * add changelog
+ * feature StatsdService abstracting Client/Factory usage
+ * feature Deal with sampling in StatsdService
diff --git a/liuggio/statsd-php-client/Readme.md
b/liuggio/statsd-php-client/README.md
similarity index 90%
rename from liuggio/statsd-php-client/Readme.md
rename to liuggio/statsd-php-client/README.md
index 81083e0..e7c6f67 100644
--- a/liuggio/statsd-php-client/Readme.md
+++ b/liuggio/statsd-php-client/README.md
@@ -46,24 +46,27 @@
```php
use Liuggio\StatsdClient\StatsdClient,
Liuggio\StatsdClient\Factory\StatsdDataFactory,
- Liuggio\StatsdClient\Sender\SocketSender;
+ Liuggio\StatsdClient\Sender\SocketSender,
+ Liuggio\StatsdClient\Service\StatsdService;
// use Liuggio\StatsdClient\Sender\SysLogSender;
$sender = new SocketSender(/*'localhost', 8126, 'udp'*/);
// $sender = new SysLogSender(); // enabling this, the packet will not send
over the socket
-$client = new StatsdClient($sender);
+$client = new StatsdClient($sender);
$factory = new StatsdDataFactory('\Liuggio\StatsdClient\Entity\StatsdData');
+$service = new StatsdService($client, $factory);
-// create the data with the factory
-$data[] = $factory->timing('usageTime', 100);
-$data[] = $factory->increment('visitor');
-$data[] = $factory->decrement('click');
-$data[] = $factory->gauge('gaugor', 333);
-$data[] = $factory->set('uniques', 765);
+// create the metrics with the service
+$service->timing('usageTime', 100);
+$service->increment('visitor');
+$service->decrement('click');
+$service->gauge('gaugor', 333);
+$service->set('uniques', 765);
-// send the data as array or directly as object
-$client->send($data);
+// send the data to statsd
+$service->flush();
+
```
### Usage with Monolog
diff --git a/liuggio/statsd-php-client/composer.json
b/liuggio/statsd-php-client/composer.json
index 705dbdf..b47e0fd 100644
--- a/liuggio/statsd-php-client/composer.json
+++ b/liuggio/statsd-php-client/composer.json
@@ -6,7 +6,7 @@
"type": "library",
"license": "MIT",
"require": {
- "php": ">=5.2"
+ "php": ">=5.3.2"
},
"authors": [
{
diff --git a/liuggio/statsd-php-client/phpunit.xml.dist
b/liuggio/statsd-php-client/phpunit.xml
similarity index 100%
rename from liuggio/statsd-php-client/phpunit.xml.dist
rename to liuggio/statsd-php-client/phpunit.xml
diff --git
a/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Entity/StatsdData.php
b/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Entity/StatsdData.php
index 9c6203d..2f03085 100755
--- a/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Entity/StatsdData.php
+++ b/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Entity/StatsdData.php
@@ -10,6 +10,7 @@
private $key;
private $value;
private $metric;
+ private $sampleRate = 1;
/**
* @param string $key
@@ -55,6 +56,22 @@
}
/**
+ * @param float $sampleRate
+ */
+ public function setSampleRate($sampleRate)
+ {
+ $this->sampleRate = $sampleRate;
+ }
+
+ /**
+ * @return float
+ */
+ public function getSampleRate()
+ {
+ return $this->sampleRate;
+ }
+
+ /**
* @param bool $withMetric
*
* @return string
@@ -62,10 +79,17 @@
public function getMessage($withMetric = true)
{
if (!$withMetric) {
- return sprintf('%s:%s', $this->getKey(), $this->getValue());
+ $result = sprintf('%s:%s', $this->getKey(), $this->getValue());
} else {
- return sprintf('%s:%s|%s', $this->getKey(), $this->getValue(),
$this->getMetric());
+ $result = sprintf('%s:%s|%s', $this->getKey(), $this->getValue(),
$this->getMetric());
}
+
+ $sampleRate = $this->getSampleRate();
+ if($sampleRate < 1){
+ $result.= "|@$sampleRate";
+ }
+
+ return $result;
}
/**
diff --git
a/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Entity/StatsdDataInterface.php
b/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Entity/StatsdDataInterface.php
index 846bc7c..d7b07a8 100755
---
a/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Entity/StatsdDataInterface.php
+++
b/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Entity/StatsdDataInterface.php
@@ -35,6 +35,12 @@
/**
* @abstract
+ * @return float
+ */
+ function getSampleRate();
+
+ /**
+ * @abstract
* @return string
*/
function __toString();
diff --git
a/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Service/StatsdService.php
b/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Service/StatsdService.php
new file mode 100644
index 0000000..061e351
--- /dev/null
+++
b/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Service/StatsdService.php
@@ -0,0 +1,196 @@
+<?php
+
+namespace Liuggio\StatsdClient\Service;
+
+use Liuggio\StatsdClient\Entity\StatsdDataInterface;
+use Liuggio\StatsdClient\Factory\StatsdDataFactory;
+use Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface;
+use Liuggio\StatsdClient\StatsdClient;
+use Liuggio\StatsdClient\Entity\StatsdData;
+
+/**
+ * Simplifies access to StatsD client and factory, buffers all data.
+ */
+class StatsdService implements StatsdDataFactoryInterface
+{
+ /**
+ * @var \Liuggio\StatsdClient\StatsdClient
+ */
+ protected $client;
+
+ /**
+ * @var \Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface
+ */
+ protected $factory;
+
+ /**
+ * @var StatsdData[]
+ */
+ protected $buffer = array();
+
+ /**
+ * @var float
+ */
+ protected $samplingRate;
+
+ private $samplingFunction;
+
+ /**
+ * @param StatsdClient $client
+ * @param StatsdDataFactoryInterface $factory
+ * @param float $samplingRate see setSamplingRate
+ */
+ public function __construct(
+ StatsdClient $client,
+ StatsdDataFactoryInterface $factory = null,
+ $samplingRate = 1
+ ) {
+ $this->client = $client;
+ if (is_null($factory)) {
+ $factory = new StatsdDataFactory();
+ }
+ $this->factory = $factory;
+ $this->setSamplingRate($samplingRate);
+ }
+
+ /**
+ * Actually defines the sampling rate used by the service.
+ * If set to 0.1, the service will automatically discard 10%
+ * of the incoming metrics. It will also automatically flag these
+ * as sampled data to statsd.
+ *
+ * @param float $samplingRate
+ */
+ public function setSamplingRate($samplingRate)
+ {
+ if ($samplingRate <= 0.0 || 1.0 < $samplingRate) {
+ throw new \LogicException('Sampling rate shall be within ]0, 1]');
+ }
+ $this->samplingRate = $samplingRate;
+ $this->samplingFunction = function($min, $max){
+ return rand($min, $max);
+ };
+ }
+
+ /**
+ * @return float
+ */
+ public function getSamplingRate()
+ {
+ return $this->samplingRate;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function timing($key, $time)
+ {
+ $this->appendToBuffer(
+ $this->factory->timing($key, $time)
+ );
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function gauge($key, $value)
+ {
+ $this->appendToBuffer(
+ $this->factory->gauge($key, $value)
+ );
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function set($key, $value)
+ {
+ $this->appendToBuffer(
+ $this->factory->set($key, $value)
+ );
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function increment($key)
+ {
+ $this->appendToBuffer(
+ $this->factory->increment($key)
+ );
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function decrement($key)
+ {
+ $this->appendToBuffer(
+ $this->factory->decrement($key)
+ );
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function updateCount($key, $delta)
+ {
+ $this->appendToBuffer(
+ $this->factory->updateCount($key, $delta)
+ );
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function produceStatsdData($key, $value = 1, $metric =
StatsdDataInterface::STATSD_METRIC_COUNT)
+ {
+ throw new \BadFunctionCallException('produceStatsdData is not
implemented');
+ }
+
+ /**
+ * @param callable $samplingFunction rand() function by default.
+ */
+ public function setSamplingFunction(\Closure $samplingFunction)
+ {
+ $this->samplingFunction = $samplingFunction;
+ }
+
+ private function appendToBuffer(StatsdData $data)
+ {
+ if($this->samplingRate < 1){
+ $data->setSampleRate($this->samplingRate);
+ $result = call_user_func($this->samplingFunction, 0 , floor(1 /
$this->samplingRate));
+ if ($result == 0) {
+ array_push($this->buffer, $data);
+ };
+ } else {
+ array_push($this->buffer, $data);
+ }
+ }
+
+ /**
+ * Send all buffered data to statsd.
+ *
+ * @return $this
+ */
+ public function flush()
+ {
+ $this->client->send($this->buffer);
+ $this->buffer = array();
+
+ return $this;
+ }
+}
diff --git
a/liuggio/statsd-php-client/src/Liuggio/StatsdClient/StatsdClient.php
b/liuggio/statsd-php-client/src/Liuggio/StatsdClient/StatsdClient.php
index a1d232a..c5c16fe 100644
--- a/liuggio/statsd-php-client/src/Liuggio/StatsdClient/StatsdClient.php
+++ b/liuggio/statsd-php-client/src/Liuggio/StatsdClient/StatsdClient.php
@@ -109,12 +109,10 @@
*/
public function appendSampleRate($data, $sampleRate = 1)
{
- $sampledData = array();
if ($sampleRate < 1) {
- foreach ($data as $key => $message) {
- $sampledData[$key] = sprintf('%s|@%s', $message, $sampleRate);
- }
- $data = $sampledData;
+ array_walk($data, function(&$message, $key) use ($sampleRate) {
+ $message = sprintf('%s|@%s', $message, $sampleRate);
+ });
}
return $data;
diff --git
a/liuggio/statsd-php-client/tests/Liuggio/StatsdClient/Service/StatsdServiceTest.php
b/liuggio/statsd-php-client/tests/Liuggio/StatsdClient/Service/StatsdServiceTest.php
new file mode 100644
index 0000000..dcf2710
--- /dev/null
+++
b/liuggio/statsd-php-client/tests/Liuggio/StatsdClient/Service/StatsdServiceTest.php
@@ -0,0 +1,86 @@
+<?php
+
+namespace Liuggio\StatsdClient\Entity;
+
+use Liuggio\StatsdClient\Service\StatsdService;
+
+class StatsdServiceTest extends \PHPUnit_Framework_TestCase
+{
+ private $clientMock;
+ private $factoryMock;
+
+ public function setUp()
+ {
+ $this->clientMock =
$this->getMockBuilder('Liuggio\StatsdClient\StatsdClient')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->factoryMock =
$this->getMockBuilder('Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface')
+ ->disableOriginalConstructor()
+ ->getMock();
+ }
+
+ public function testConstructorWithoutFactory()
+ {
+ $dut = new StatsdService($this->clientMock);
+ $dut->timing('foo.bar', 123);
+ }
+
+ public function testFactoryImplementation()
+ {
+ $data = new StatsdData();
+
+ // Configure the client mock.
+
$this->factoryMock->expects($this->once())->method('timing')->willReturn($data);
+
$this->factoryMock->expects($this->once())->method('gauge')->willReturn($data);
+
$this->factoryMock->expects($this->once())->method('set')->willReturn($data);
+
$this->factoryMock->expects($this->once())->method('increment')->willReturn($data);
+
$this->factoryMock->expects($this->once())->method('decrement')->willReturn($data);
+
$this->factoryMock->expects($this->once())->method('updateCount')->willReturn($data);
+
+ // Actual test
+ $dut = new StatsdService($this->clientMock, $this->factoryMock);
+ $dut->timing('foo.bar', 123);
+ $dut->gauge('foo.bar', 123);
+ $dut->set('foo.bar', 123);
+ $dut->increment('foo.bar');
+ $dut->decrement('foo.bar');
+ $dut->updateCount('foo.bar', 123);
+ }
+
+ public function testFlush()
+ {
+ $data = new StatsdData();
+
$this->factoryMock->expects($this->once())->method('timing')->willReturn($data);
+ $this->clientMock->expects($this->once())->method('send')
+ ->with($this->equalTo(array($data)));
+
+ // Actual test
+ $dut = new StatsdService($this->clientMock, $this->factoryMock);
+ $dut->timing('foobar', 123);
+ $dut->flush();
+ }
+
+ public function testSampling()
+ {
+ $tries = false;
+ $closure = function($a, $b) use (&$tries) {
+ $tries = !$tries;
+ return $tries ? 1 : 0;
+ };
+
+ $data = new StatsdData();
+
$this->factoryMock->expects($this->exactly(2))->method('timing')->willReturn($data);
+ $this->clientMock->expects($this->once())->method('send')
+ ->with($this->equalTo(array($data)));
+
+ // Actual test
+ $dut = new StatsdService($this->clientMock, $this->factoryMock);
+ $dut->setSamplingRate(0.1);
+ $dut->setSamplingFunction($closure);
+ $dut->timing('foo', 123);
+ $dut->timing('bar', 123);
+ $dut->flush();
+
+ $this->assertSame(0.1, $data->getSampleRate());
+ }
+}
--
To view, visit https://gerrit.wikimedia.org/r/226641
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I307b58f4abe4d615ac9b2f86f50d0c5d6b906d83
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/vendor
Gerrit-Branch: master
Gerrit-Owner: Gergő Tisza <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits