Skip to content

Commit 1481580

Browse files
authored
Replaced influxdb/influxdb-php with influxdata/influxdb-client-php (#7462)
1 parent 30855f3 commit 1481580

File tree

5 files changed

+200
-41
lines changed

5 files changed

+200
-41
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
"hyperf/http-server": "Required to capture routes in middleware.",
3232
"hyperf/process": "Required to use standalone process, or you have to roll your own",
3333
"hyperf/retry": "Required to use back-off retry implementation.",
34-
"influxdb/influxdb-php": "Required to use InfluxDB driver.",
34+
"influxdata/influxdb-client-php": "Required to use InfluxDB driver.",
3535
"promphp/prometheus_client_php": "Required to use Prometheus driver.(2.2.*)",
3636
"slickdeals/statsd": "Required to use StatdD driver."
3737
},

publish/metric.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,10 @@
5555
'namespace' => env('APP_NAME', 'skeleton'),
5656
'host' => env('INFLUXDB_HOST', '127.0.0.1'),
5757
'port' => env('INFLUXDB_PORT', '8086'),
58-
'username' => env('INFLUXDB_USERNAME', ''),
59-
'password' => env('INFLUXDB_PASSWORD', ''),
60-
'dbname' => env('INFLUXDB_DBNAME', true),
58+
'token' => env('INFLUXDB_TOKEN', ''),
59+
'bucket' => env('INFLUXDB_BUCKET', 'default'),
60+
'org' => env('INFLUXDB_ORG', 'default'),
6161
'push_interval' => env('INFLUXDB_PUSH_INTERVAL', 5),
62-
'auto_create_db' => env('INFLUXDB_AUTO_CREATE_DB', true),
6362
],
6463
'noop' => [
6564
'driver' => Hyperf\Metric\Adapter\NoOp\MetricFactory::class,

src/Adapter/InfluxDB/MetricFactory.php

Lines changed: 45 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,20 @@
2424
use Hyperf\Metric\Contract\HistogramInterface;
2525
use Hyperf\Metric\Contract\MetricFactoryInterface;
2626
use Hyperf\Stringable\StrCache;
27-
use InfluxDB\Client;
28-
use InfluxDB\Database;
29-
use InfluxDB\Database\RetentionPolicy;
30-
use InfluxDB\Driver\DriverInterface;
31-
use InfluxDB\Point;
27+
use InfluxDB2\Client;
28+
use InfluxDB2\Point;
29+
use InfluxDB2\WriteApi;
3230
use Prometheus\CollectorRegistry;
3331
use Prometheus\Sample;
3432

35-
use function Hyperf\Support\make;
36-
3733
class MetricFactory implements MetricFactoryInterface
3834
{
3935
private string $name;
4036

37+
private ?Client $client = null;
38+
39+
private ?WriteApi $writeApi = null;
40+
4141
public function __construct(
4242
private ConfigInterface $config,
4343
private CollectorRegistry $registry,
@@ -81,25 +81,9 @@ public function makeHistogram(string $name, ?array $labelNames = []): HistogramI
8181

8282
public function handle(): void
8383
{
84-
$host = $this->config->get("metric.metric.{$this->name}.host");
85-
$port = $this->config->get("metric.metric.{$this->name}.port");
86-
$username = $this->config->get("metric.metric.{$this->name}.username");
87-
$password = $this->config->get("metric.metric.{$this->name}.password");
88-
$dbname = $this->config->get("metric.metric.{$this->name}.dbname");
84+
$this->initializeClient();
8985
$interval = (float) $this->config->get("metric.metric.{$this->name}.push_interval", 5);
90-
$create = $this->config->get("metric.metric.{$this->name}.auto_create_db");
91-
$client = new Client($host, $port, $username, $password);
92-
$guzzleClient = $this->guzzleClientFactory->create([
93-
'connect_timeout' => $client->getConnectTimeout(),
94-
'timeout' => $client->getTimeout(),
95-
'base_uri' => $client->getBaseURI(),
96-
'verify' => $client->getVerifySSL(),
97-
]);
98-
$client->setDriver(make(DriverInterface::class, ['client' => $guzzleClient]));
99-
$database = $client->selectDB($dbname);
100-
if (! $database->exists() && $create) {
101-
$database->create(new RetentionPolicy($dbname, '1d', 1, true));
102-
}
86+
10387
while (true) {
10488
$workerExited = CoordinatorManager::until(Constants::WORKER_EXIT)->yield($interval);
10589
if ($workerExited) {
@@ -112,19 +96,47 @@ public function handle(): void
11296
$points[] = $this->createPoint($sample);
11397
}
11498
}
115-
$result = $database->writePoints($points, Database::PRECISION_SECONDS);
99+
$this->writeApi->write($points);
116100
}
117101
}
118102

119103
protected function createPoint(Sample $sample): Point
120104
{
121-
return new Point(
122-
$sample->getName(),
123-
$sample->getValue(),
124-
$labels = array_combine($sample->getLabelNames(), $sample->getLabelValues()),
125-
[],
126-
time()
127-
);
105+
$point = Point::measurement($sample->getName())
106+
->addField('value', $sample->getValue())
107+
->time(time());
108+
109+
$labelNames = $sample->getLabelNames();
110+
$labelValues = $sample->getLabelValues();
111+
112+
if (count($labelNames) === count($labelValues)) {
113+
for ($i = 0; $i < count($labelNames); ++$i) {
114+
$point->addTag($labelNames[$i], $labelValues[$i]);
115+
}
116+
}
117+
118+
return $point;
119+
}
120+
121+
private function initializeClient(): void
122+
{
123+
if ($this->client === null) {
124+
$host = $this->config->get("metric.metric.{$this->name}.host");
125+
$port = $this->config->get("metric.metric.{$this->name}.port");
126+
$token = $this->config->get("metric.metric.{$this->name}.token");
127+
$bucket = $this->config->get("metric.metric.{$this->name}.bucket");
128+
$org = $this->config->get("metric.metric.{$this->name}.org");
129+
$url = "http://{$host}:{$port}";
130+
131+
$this->client = new Client([
132+
'url' => $url,
133+
'token' => $token,
134+
'bucket' => $bucket,
135+
'org' => $org,
136+
]);
137+
138+
$this->writeApi = $this->client->createWriteApi();
139+
}
128140
}
129141

130142
private function getNamespace(): string

src/ConfigProvider.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@
2626
use Hyperf\Metric\Listener\OnPipeMessage;
2727
use Hyperf\Metric\Listener\OnWorkerStart;
2828
use Hyperf\Metric\Process\MetricProcess;
29-
use InfluxDB\Driver\DriverInterface;
30-
use InfluxDB\Driver\Guzzle;
3129
use Prometheus\Storage\Adapter;
3230
use Prometheus\Storage\InMemory;
3331

@@ -40,7 +38,6 @@ public function __invoke(): array
4038
MetricFactoryInterface::class => MetricFactoryPicker::class,
4139
Adapter::class => InMemory::class,
4240
Connection::class => UdpSocket::class,
43-
DriverInterface::class => Guzzle::class,
4441
MetricCollectorInterface::class => MetricCollectorFactory::class,
4542
],
4643
'aspects' => [
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
/**
5+
* This file is part of Hyperf.
6+
*
7+
* @link https://www.hyperf.io
8+
* @document https://hyperf.wiki
9+
* @contact group@hyperf.io
10+
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
11+
*/
12+
13+
namespace HyperfTest\Metric\Cases;
14+
15+
use Hyperf\Config\Config;
16+
use Hyperf\Guzzle\ClientFactory;
17+
use Hyperf\Metric\Adapter\InfluxDB\MetricFactory as InfluxDBFactory;
18+
use Hyperf\Metric\Contract\CounterInterface;
19+
use Hyperf\Metric\Contract\GaugeInterface;
20+
use Hyperf\Metric\Contract\HistogramInterface;
21+
use InfluxDB2\Point;
22+
use Mockery;
23+
use PHPUnit\Framework\Attributes\CoversNothing;
24+
use PHPUnit\Framework\TestCase;
25+
use Prometheus\CollectorRegistry;
26+
use Prometheus\Counter;
27+
use Prometheus\Gauge;
28+
use Prometheus\Histogram;
29+
use Prometheus\Sample;
30+
use ReflectionClass;
31+
32+
/**
33+
* @internal
34+
* @coversNothing
35+
*/
36+
#[CoversNothing]
37+
class InfluxDBMetricFactoryTest extends TestCase
38+
{
39+
protected function tearDown(): void
40+
{
41+
Mockery::close();
42+
}
43+
44+
public function testMakeCounter()
45+
{
46+
$registry = Mockery::mock(CollectorRegistry::class);
47+
$registry->shouldReceive('getOrRegisterCounter')
48+
->once()
49+
->andReturn(Mockery::mock(Counter::class));
50+
51+
$factory = $this->createInfluxDBFactory($registry);
52+
$counter = $factory->makeCounter('test_counter', ['label1', 'label2']);
53+
54+
$this->assertInstanceOf(CounterInterface::class, $counter);
55+
}
56+
57+
public function testMakeGauge()
58+
{
59+
$registry = Mockery::mock(CollectorRegistry::class);
60+
$registry->shouldReceive('getOrRegisterGauge')
61+
->once()
62+
->andReturn(Mockery::mock(Gauge::class));
63+
64+
$factory = $this->createInfluxDBFactory($registry);
65+
$gauge = $factory->makeGauge('test_gauge', ['label1']);
66+
67+
$this->assertInstanceOf(GaugeInterface::class, $gauge);
68+
}
69+
70+
public function testMakeHistogram()
71+
{
72+
$registry = Mockery::mock(CollectorRegistry::class);
73+
$registry->shouldReceive('getOrRegisterHistogram')
74+
->once()
75+
->andReturn(Mockery::mock(Histogram::class));
76+
77+
$factory = $this->createInfluxDBFactory($registry);
78+
$histogram = $factory->makeHistogram('test_histogram');
79+
80+
$this->assertInstanceOf(HistogramInterface::class, $histogram);
81+
}
82+
83+
public function testCreatePoint()
84+
{
85+
$factory = $this->createInfluxDBFactory();
86+
$reflection = new ReflectionClass($factory);
87+
$method = $reflection->getMethod('createPoint');
88+
89+
$sample = Mockery::mock(Sample::class);
90+
$sample->shouldReceive('getName')->andReturn('test_metric');
91+
$sample->shouldReceive('getValue')->andReturn(42.5);
92+
$sample->shouldReceive('getLabelNames')->andReturn(['label1', 'label2']);
93+
$sample->shouldReceive('getLabelValues')->andReturn(['value1', 'value2']);
94+
95+
$point = $method->invokeArgs($factory, [$sample]);
96+
97+
$this->assertInstanceOf(Point::class, $point);
98+
}
99+
100+
public function testGetNamespace()
101+
{
102+
$config = new Config([
103+
'metric' => [
104+
'default' => 'influxdb',
105+
'metric' => [
106+
'influxdb' => [
107+
'namespace' => 'Test-App_Name!',
108+
],
109+
],
110+
],
111+
]);
112+
113+
$factory = new InfluxDBFactory(
114+
$config,
115+
Mockery::mock(CollectorRegistry::class),
116+
Mockery::mock(ClientFactory::class)
117+
);
118+
119+
$reflection = new ReflectionClass($factory);
120+
$method = $reflection->getMethod('getNamespace');
121+
122+
$namespace = $method->invoke($factory);
123+
$this->assertEquals('test__app__name_', $namespace);
124+
}
125+
126+
private function createInfluxDBFactory(?CollectorRegistry $registry = null): InfluxDBFactory
127+
{
128+
$config = new Config([
129+
'metric' => [
130+
'default' => 'influxdb',
131+
'metric' => [
132+
'influxdb' => [
133+
'namespace' => 'Test-App_Name!',
134+
'host' => '127.0.0.1',
135+
'port' => '8086',
136+
'token' => 'test-token',
137+
'bucket' => 'test-bucket',
138+
'org' => 'test-org',
139+
'push_interval' => 5,
140+
],
141+
],
142+
],
143+
]);
144+
145+
return new InfluxDBFactory(
146+
$config,
147+
$registry ?: Mockery::mock(CollectorRegistry::class),
148+
Mockery::mock(ClientFactory::class)
149+
);
150+
}
151+
}

0 commit comments

Comments
 (0)