google-cloud-php icon indicating copy to clipboard operation
google-cloud-php copied to clipboard

Error listing timeseries data

Open brandinchiu opened this issue 2 years ago • 2 comments

A previously working piece of code I had written has suddenly stopped working. The error returned by my system is reported from within the guzzlehttp backend used to wrap the requests from the PHP SDK to Google.

Uncaught Error: Object of class Google\Cloud\Monitoring\V3\TimeInterval could not be converted to string in /Users/misfitpixel/testing/vendor/guzzlehttp/psr7/src/Query.php:96

Environment details

  • OS: macOS Monterey 12.3.1
  • PHP version: 7.4.28
  • Framework version: Symfony 5.4.7 (not used in example)
  • Package name and version: "google/cloud-monitoring": "^1.0"

Code example

I've tried to eliminate as many variables as possible to test various components, and this is the simplest iteration I can get to, which includes only a single declared dependency as included above, and a single file called test.php with the below contents:

<?php

require __DIR__ . '/vendor/autoload.php';

use Google\Cloud\Monitoring\V3 as Monitoring;
use Google\Protobuf\Timestamp;

$googleMetricClient = new Monitoring\MetricServiceClient([
    'projectId' => 'xxxxx',
    'credentials' => 'xxxxx'
]);

$startTime = new Timestamp();
$startTime->setSeconds(time() - (60 * 20));
$endTime = new Timestamp();
$endTime->setSeconds(time());

$interval = new Monitoring\TimeInterval();
$interval->setStartTime($startTime);
$interval->setEndTime($endTime);

$result = $googleMetricClient->listTimeSeries(
    'projects/platform-production-na',
    'metric.type="cloudsql.googleapis.com/database/memory/utilization" AND resource.type="cloudsql_database" AND resource.labels.database_id="xxxxx:xxxxx"',
    $interval,
    Monitoring\ListTimeSeriesRequest\TimeSeriesView::FULL
);

print_r(
    $result
);exit;

The error returned is as follows:

PHP Fatal error:  Uncaught Error: Object of class Google\Cloud\Monitoring\V3\TimeInterval could not be converted to string in /Users/misfitpixel/testing/vendor/guzzlehttp/psr7/src/Query.php:96
Stack trace:
#0 /Users/misfitpixel/testing/vendor/google/gax/src/UriTrait.php(66): GuzzleHttp\Psr7\Query::build(Array)
#1 /Users/misfitpixel/testing/vendor/google/gax/src/RequestBuilder.php(264): Google\ApiCore\RequestBuilder->buildUriWithQuery(Object(GuzzleHttp\Psr7\Uri), Array)
#2 /Users/misfitpixel/testing/vendor/google/gax/src/RequestBuilder.php(110): Google\ApiCore\RequestBuilder->buildUri('/v3/projects/pl...', Array)
#3 /Users/misfitpixel/testing/vendor/google/gax/src/Transport/RestTransport.php(116): Google\ApiCore\RequestBuilder->build('google.monitori...', Object(Google\Cloud\Monitoring\V3\ListTimeSeriesRequest), Array)
#4 /Users/misfitpixel/testing/vendor/google/gax/src/GapicClientTrait.php(608): Google\ApiCore\Transport\RestTransport->startUnaryCall(Object(Google\ApiCore\Call), Array)
#5 /Users/misfitpixel/testing/vendor/googl in /Users/misfitpixel/testing/vendor/guzzlehttp/psr7/src/Query.php on line 96

Fatal error: Uncaught Error: Object of class Google\Cloud\Monitoring\V3\TimeInterval could not be converted to string in /Users/misfitpixel/testing/vendor/guzzlehttp/psr7/src/Query.php:96
Stack trace:
#0 /Users/misfitpixel/testing/vendor/google/gax/src/UriTrait.php(66): GuzzleHttp\Psr7\Query::build(Array)
#1 /Users/misfitpixel/testing/vendor/google/gax/src/RequestBuilder.php(264): Google\ApiCore\RequestBuilder->buildUriWithQuery(Object(GuzzleHttp\Psr7\Uri), Array)
#2 /Users/misfitpixel/testing/vendor/google/gax/src/RequestBuilder.php(110): Google\ApiCore\RequestBuilder->buildUri('/v3/projects/pl...', Array)
#3 /Users/misfitpixel/testing/vendor/google/gax/src/Transport/RestTransport.php(116): Google\ApiCore\RequestBuilder->build('google.monitori...', Object(Google\Cloud\Monitoring\V3\ListTimeSeriesRequest), Array)
#4 /Users/misfitpixel/testing/vendor/google/gax/src/GapicClientTrait.php(608): Google\ApiCore\Transport\RestTransport->startUnaryCall(Object(Google\ApiCore\Call), Array)
#5 /Users/misfitpixel/testing/vendor/googl in /Users/misfitpixel/testing/vendor/guzzlehttp/psr7/src/Query.php on line 96

brandinchiu avatar Apr 19 '22 19:04 brandinchiu

Any updates on this? Have you been able to reproduce it at least?

brandinchiu avatar May 21 '22 12:05 brandinchiu

I have the same problem. Code snippet provided by @brandinchiu is almost identical to mine and provide same error message.

Ekimik avatar Jun 24 '22 09:06 Ekimik

I'm on the same boat, almost identical code and same error message.

Any solution?

jlcd avatar Nov 19 '22 16:11 jlcd

Did a quick debug and saw there's an additional interval query property being sent. From what I understand from the method projects.timeSeries.list, this property is not needed/used at all, so if I just:

if (isset($query['interval'])) {
    unset($query['interval']);
}

(on Google\ApiCore\UriTrait)

it works as expected.


just a quick edit: This is DEFINITELY NOT the solution. Just debugged and found it works and decided to share.

jlcd avatar Nov 19 '22 16:11 jlcd

Folks, apologies for a delay in response on this. We're trying to get better at this.

I tried to replicate this on a simple VM instance using the sample.

This is the code I used which is pretty similar to what I see here in the issue:

require __DIR__ . '/vendor/autoload.php';

use Google\Cloud\Monitoring\V3 as Monitoring;
use Google\Protobuf\Timestamp;

$projectId = 'PROJECT_ID';

$googleMetricClient = new Monitoring\MetricServiceClient([
    'projectId' => $projectId,
]);

$startTime = new Timestamp();
$startTime->setSeconds(time() - 600);
$endTime = new Timestamp();
$endTime->setSeconds(time());

$interval = new Monitoring\TimeInterval();
$interval->setStartTime($startTime);
$interval->setEndTime($endTime);

$projectName = $googleMetricClient->projectName($projectId);

$result = $googleMetricClient->listTimeSeries(
    $projectName,
    'metric.type="compute.googleapis.com/instance/cpu/utilization"',
    $interval,
    Monitoring\ListTimeSeriesRequest\TimeSeriesView::FULL
);


foreach ($result->iterateAllElements() as $timeSeries) {
    $instanceName = $timeSeries->getMetric()->getLabels()['instance_name'];
    printf($instanceName . ':' . PHP_EOL);
    foreach ($timeSeries->getPoints() as $point) {
        printf('  ' . $point->getValue()->getDoubleValue() . PHP_EOL);
    }
}

I am not seeing any errors. Hopefully this was something temporary due to a slipped bug which got resolved later. If anyone is still seeing this please let me know.

saranshdhingra avatar Jul 06 '23 07:07 saranshdhingra

Did a quick debug and saw there's an additional interval query property being sent. From what I understand from the method projects.timeSeries.list, this property is not needed/used at all, so if I just:

This is pretty surprising as the REST API reference page mentions that the interval field is required.

saranshdhingra avatar Jul 06 '23 07:07 saranshdhingra

Closing this as I haven't been able to reproduce this and have not seen any responses in a month. If anyone can reproduce this, please feel free to reopen this :)

saranshdhingra avatar Aug 07 '23 10:08 saranshdhingra