Repository navigation
feat(metric): Replaced influxdb/influxdb-php with influxdata/influxdb-client-php - #7462
Conversation
Replace influxdb/influxdb-php with influxdata/influxdb-client-php to support InfluxDB 2.x features including token-based authentication and bucket storage. ### Changes Made: #### Dependencies: - Replace `influxdb/influxdb-php: ^1.15.0` with `influxdata/influxdb-client-php: ^3.0` - Update composer suggestions and remove obsolete driver dependencies #### Core Implementation: - Refactor `MetricFactory` to use InfluxDB2 client API - Implement token-based authentication (replaces username/password) - Use bucket concept instead of database selection - Adopt fluent Point creation API with method chaining - Utilize WriteApi for data ingestion #### Configuration Updates: - Add support for `token`, `bucket`, and `org` configuration - Remove deprecated `username`, `password`, `dbname`, and `auto_create_db` options - Update metric configuration template with new parameters #### Testing: - Add comprehensive unit tests for InfluxDBMetricFactory - Test coverage for Counter, Gauge, Histogram creation - Verify Point creation and namespace handling - All new tests passing (5/5) ### Breaking Changes: **Configuration Migration Required:** - `INFLUXDB_USERNAME` + `INFLUXDB_PASSWORD` → `INFLUXDB_TOKEN` - `INFLUXDB_DBNAME` → `INFLUXDB_BUCKET` - Add `INFLUXDB_ORG` configuration **Server Compatibility:** - Requires InfluxDB 2.x server (not backward compatible with 1.x) ### Technical Details: - Point creation now uses fluent API: `Point::measurement()->addTag()->addField()->time()` - Client initialization lazy-loaded in `initializeClient()` method - Removed database existence checks (handled by InfluxDB 2.x automatically) - Maintained compatibility with existing Prometheus metric interfaces 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
There was a problem hiding this comment.
Pull request overview
This PR migrates the metric InfluxDB adapter from the legacy influxdb/influxdb-php (InfluxDB 1.x) client to influxdata/influxdb-client-php to support InfluxDB 2.x concepts (token auth, org, bucket) while keeping the existing Hyperf metric interfaces.
Changes:
- Replaced the InfluxDB client dependency and removed legacy driver bindings.
- Refactored the InfluxDB
MetricFactoryto use the InfluxDB 2.x client +WriteApiand updated config keys (token/bucket/org). - Added unit tests for InfluxDB metric factory creation and point/namespace handling.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
src/metric/src/Adapter/InfluxDB/MetricFactory.php |
Switches to InfluxDB2 client, changes point creation + write path, introduces lazy client initialization. |
src/metric/publish/metric.php |
Updates published config template to token/bucket/org and removes deprecated options. |
src/metric/src/ConfigProvider.php |
Removes obsolete InfluxDB 1.x driver DI bindings. |
src/metric/tests/Cases/InfluxDBMetricFactoryTest.php |
Adds tests for factory methods, point creation, and namespace normalization. |
src/metric/composer.json |
Updates the suggested InfluxDB client package. |
composer.json |
Replaces the root dependency with influxdata/influxdb-client-php. |
Comments suppressed due to low confidence (1)
src/metric/src/Adapter/InfluxDB/MetricFactory.php:45
GuzzleClientFactory $guzzleClientFactoryis still injected but is no longer used after switching toInfluxDB2\Client. Keeping an unused dependency increases coupling and can mislead readers about how HTTP transport is configured. Consider removing the constructor parameter/property (and any related DI wiring) if it’s not needed anymore.
public function __construct(
private ConfigInterface $config,
private CollectorRegistry $registry,
private GuzzleClientFactory $guzzleClientFactory
) {
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| ); | ||
| $point = Point::measurement($sample->getName()) | ||
| ->addField('value', $sample->getValue()) | ||
| ->time(time()); |
There was a problem hiding this comment.
Point::time(time()) uses a Unix timestamp in seconds, but the InfluxDB 2.x client defaults to nanosecond precision unless explicitly set. Previously this code wrote with Database::PRECISION_SECONDS, so this change can shift timestamps to ~1970 or otherwise incorrect values. Please explicitly set write precision to seconds (e.g., via the Point API and/or the WriteApi write precision) or provide a timestamp in the precision expected by the client.
| ->time(time()); | |
| ->time(time(), 's'); |
| @@ -112,19 +96,47 @@ public function handle(): void | |||
| $points[] = $this->createPoint($sample); | |||
| } | |||
| } | |||
| $result = $database->writePoints($points, Database::PRECISION_SECONDS); | |||
| $this->writeApi->write($points); | |||
| } | |||
There was a problem hiding this comment.
WriteApi is typically buffered/batched. When the worker exit signal is received, the loop breaks without flushing/closing the WriteApi, which can drop pending points during shutdown. Consider calling close()/flush() in a finally block (or right before break) so buffered metrics are delivered reliably.
| } | ||
| } | ||
| $result = $database->writePoints($points, Database::PRECISION_SECONDS); | ||
| $this->writeApi->write($points); |
There was a problem hiding this comment.
$this->writeApi->write($points) is called even when no samples were collected (empty $points). If the client treats an empty batch as an error, this could cause unnecessary exceptions/log noise; even if it’s a no-op, it’s wasted work. Consider skipping the write when $points is empty.
| $this->writeApi->write($points); | |
| if (! empty($points)) { | |
| $this->writeApi->write($points); | |
| } |
|
|
||
| $point = $method->invokeArgs($factory, [$sample]); | ||
|
|
||
| $this->assertInstanceOf(Point::class, $point); |
There was a problem hiding this comment.
testCreatePoint() only asserts that a Point instance is returned. Given the refactor changed timestamp handling and label-to-tag mapping, this test won’t catch regressions (e.g., wrong write precision or missing tags). Consider asserting against the point’s serialized line protocol / array form to verify the field name/value, tags, and timestamp precision.
| $this->assertInstanceOf(Point::class, $point); | |
| $this->assertInstanceOf(Point::class, $point); | |
| // Verify that the point is serialized correctly to InfluxDB line protocol. | |
| $lineProtocol = $point->toLineProtocol(); | |
| // Ensure measurement name, tags, and field value are mapped as expected. | |
| $this->assertStringStartsWith( | |
| 'test_metric,label1=value1,label2=value2 value=42.5', | |
| $lineProtocol | |
| ); | |
| // Ensure there is a timestamp with the expected precision (e.g. 19-digit nanoseconds). | |
| $this->assertMatchesRegularExpression( | |
| '/^test_metric,label1=value1,label2=value2 value=42\.5(?:0+)? \d{19}$/', | |
| $lineProtocol | |
| ); |
| $url = "http://{$host}:{$port}"; | ||
|
|
There was a problem hiding this comment.
The InfluxDB client is always instantiated with an http:// URL, forcing plaintext HTTP even when the InfluxDB endpoint supports HTTPS. This sends the InfluxDB auth token and metric data unencrypted over the network, allowing on-path attackers to steal credentials or tamper with metrics. Make the scheme (or full URL) configurable and default to HTTPS, ensuring TLS verification is enabled.
| $url = "http://{$host}:{$port}"; | |
| $url = $this->config->get("metric.metric.{$this->name}.url"); | |
| if (! is_string($url) || $url === '') { | |
| $scheme = $this->config->get("metric.metric.{$this->name}.scheme", 'https'); | |
| if ($scheme !== 'http' && $scheme !== 'https') { | |
| $scheme = 'https'; | |
| } | |
| if ($host !== null && $host !== '') { | |
| if ($port !== null && $port !== '') { | |
| $url = sprintf('%s://%s:%s', $scheme, $host, $port); | |
| } else { | |
| $url = sprintf('%s://%s', $scheme, $host); | |
| } | |
| } else { | |
| $url = sprintf('%s://localhost', $scheme); | |
| } | |
| } |
Replace influxdb/influxdb-php with influxdata/influxdb-client-php to support InfluxDB 2.x features including token-based authentication and bucket storage.
Changes Made:
Dependencies:
influxdb/influxdb-php: ^1.15.0withinfluxdata/influxdb-client-php: ^3.0Core Implementation:
MetricFactoryto use InfluxDB2 client APIConfiguration Updates:
token,bucket, andorgconfigurationusername,password,dbname, andauto_create_dboptionsTesting:
Breaking Changes:
Configuration Migration Required:
INFLUXDB_USERNAME+INFLUXDB_PASSWORD→INFLUXDB_TOKENINFLUXDB_DBNAME→INFLUXDB_BUCKETINFLUXDB_ORGconfigurationServer Compatibility:
Technical Details:
Point::measurement()->addTag()->addField()->time()initializeClient()method🤖 Generated with Claude Code