diff --git a/monitoring/README.md b/monitoring/README.md
new file mode 100644
index 0000000000..16d17f3d65
--- /dev/null
+++ b/monitoring/README.md
@@ -0,0 +1,99 @@
+Stackdriver Monitoring PHP Samples
+==================================
+
+This directory contains samples for Stackdriver Monitoring.
+[Stackdriver Monitoring][monitoring] collects metrics, events, and metadata from
+Google Cloud Platform, Amazon Web Services (AWS), hosted uptime probes,
+application instrumentation, and a variety of common application components
+including Cassandra, Nginx, Apache Web Server, Elasticsearch and many others.
+
+[monitoring]: https://cloud.google.com/monitoring/docs
+
+## Setup
+
+### Authentication
+
+Authentication is typically done through [Application Default Credentials][adc]
+which means you do not have to change the code to authenticate as long as
+your environment has credentials. You have a few options for setting up
+authentication:
+
+1. When running locally, use the [Google Cloud SDK][google-cloud-sdk]
+
+ gcloud auth application-default login
+
+1. When running on App Engine or Compute Engine, credentials are already
+ set-up. However, you may need to configure your Compute Engine instance
+ with [additional scopes][additional_scopes].
+
+1. You can create a [Service Account key file][service_account_key_file]. This file can be used to
+ authenticate to Google Cloud Platform services from any environment. To use
+ the file, set the ``GOOGLE_APPLICATION_CREDENTIALS`` environment variable to
+ the path to the key file, for example:
+
+ export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service_account.json
+
+[adc]: https://cloud.google.com/docs/authentication#getting_credentials_for_server-centric_flow
+[additional_scopes]: https://cloud.google.com/compute/docs/authentication#using
+[service_account_key_file]: https://developers.google.com/identity/protocols/OAuth2ServiceAccount#creatinganaccount
+
+## Install Dependencies
+
+1. Ensure the [gRPC PHP Extension][php_grpc] is installed and enabled on your machine.
+1. [Enable the Stackdriver Monitoring API](https://console.cloud.google.com/flows/enableapi?apiid=monitoring.googleapis.com).
+
+1. **Install dependencies** via [Composer](http://getcomposer.org/doc/00-intro.md).
+ Run `php composer.phar install` (if composer is installed locally) or `composer install`
+ (if composer is installed globally).
+
+1. Create a service account at the
+[Service account section in the Cloud Console](https://console.cloud.google.com/iam-admin/serviceaccounts/)
+
+1. Download the json key file of the service account.
+
+1. Set `GOOGLE_APPLICATION_CREDENTIALS` environment variable pointing to that file.
+
+## Samples
+
+To run the Stackdriver Monitoring Samples:
+
+ $ php monitoring.php
+
+ Stackdriver Monitoring
+
+ Usage:
+ command [options] [arguments]
+
+ Options:
+ -h, --help Display this help message
+ -q, --quiet Do not output any message
+ -V, --version Display this application version
+ --ansi Force ANSI output
+ --no-ansi Disable ANSI output
+ -n, --no-interaction Do not ask any interactive question
+ -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+
+ Available commands:
+ create-metric Creates a logging metric.
+ delete-metric Deletes a logging metric.
+ get-descriptor Gets a logging descriptor.
+ help Displays help for a command
+ list Lists commands
+ list-descriptors Lists logging descriptors.
+ read-timeseries-align Aggregates metrics for each timeseries.
+ read-timeseries-fields Reads Timeseries fields.
+ read-timeseries-reduce Aggregates metrics across multiple timeseries.
+ read-timeseries-simple Reads a timeseries.
+ write-timeseries Writes a timeseries.
+
+## The client library
+
+This sample uses the [Google Cloud Client Library for PHP][google-cloud-php].
+You can read the documentation for more details on API usage and use GitHub
+to [browse the source][google-cloud-php-source] and [report issues][google-cloud-php-issues].
+
+[php_grpc]: http://cloud.google.com/php/grpc
+[google-cloud-php]: https://googlecloudplatform.github.io/google-cloud-php
+[google-cloud-php-source]: https://github.com/GoogleCloudPlatform/google-cloud-php
+[google-cloud-php-issues]: https://github.com/GoogleCloudPlatform/google-cloud-php/issues
+[google-cloud-sdk]: https://cloud.google.com/sdk/
diff --git a/monitoring/composer.json b/monitoring/composer.json
index 8d9eac5c38..d2a4e014b0 100644
--- a/monitoring/composer.json
+++ b/monitoring/composer.json
@@ -1,9 +1,23 @@
{
"require": {
- "google/cloud-monitoring": "^0.4"
+ "google/cloud-monitoring": "^0.4",
+ "symfony/console": "^3.3"
+ },
+ "autoload": {
+ "files": [
+ "src/create_metric.php",
+ "src/delete_metric.php",
+ "src/get_descriptor.php",
+ "src/list_descriptors.php",
+ "src/read_timeseries_align.php",
+ "src/read_timeseries_fields.php",
+ "src/read_timeseries_reduce.php",
+ "src/read_timeseries_simple.php",
+ "src/write_timeseries.php"
+ ]
},
"require-dev": {
- "phpunit/phpunit": "4.8.*",
- "squizlabs/php_codesniffer": "2.*"
+ "phpunit/phpunit": "^4",
+ "google/cloud-tools": "^0.6"
}
}
diff --git a/monitoring/composer.lock b/monitoring/composer.lock
index 6a63a7447d..1e747437a2 100644
--- a/monitoring/composer.lock
+++ b/monitoring/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"
],
- "content-hash": "af3d3990e6d429812aa9e055464e3408",
+ "content-hash": "c8c2ea6ecb321239de558ce69ea15f04",
"packages": [
{
"name": "firebase/php-jwt",
@@ -264,16 +264,16 @@
},
{
"name": "grpc/grpc",
- "version": "v1.4.1",
+ "version": "v1.4.2",
"source": {
"type": "git",
"url": "https://github.com/grpc/grpc.git",
- "reference": "844d5940035b6d96022076f89d6602faab464390"
+ "reference": "5cb6a1f86129fc2833de9a27cfe174260934342b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/grpc/grpc/zipball/844d5940035b6d96022076f89d6602faab464390",
- "reference": "844d5940035b6d96022076f89d6602faab464390",
+ "url": "https://api.github.com/repos/grpc/grpc/zipball/5cb6a1f86129fc2833de9a27cfe174260934342b",
+ "reference": "5cb6a1f86129fc2833de9a27cfe174260934342b",
"shasum": ""
},
"require": {
@@ -301,7 +301,7 @@
"keywords": [
"rpc"
],
- "time": "2017-06-27T19:46:01+00:00"
+ "time": "2017-07-11T21:11:30+00:00"
},
{
"name": "guzzlehttp/guzzle",
@@ -579,6 +579,237 @@
"response"
],
"time": "2016-08-06T14:39:51+00:00"
+ },
+ {
+ "name": "psr/log",
+ "version": "1.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
+ "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Log\\": "Psr/Log/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for logging libraries",
+ "homepage": "https://github.com/php-fig/log",
+ "keywords": [
+ "log",
+ "psr",
+ "psr-3"
+ ],
+ "time": "2016-10-10T12:19:37+00:00"
+ },
+ {
+ "name": "symfony/console",
+ "version": "v3.3.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/console.git",
+ "reference": "a97e45d98c59510f085fa05225a1acb74dfe0546"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/console/zipball/a97e45d98c59510f085fa05225a1acb74dfe0546",
+ "reference": "a97e45d98c59510f085fa05225a1acb74dfe0546",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9",
+ "symfony/debug": "~2.8|~3.0",
+ "symfony/polyfill-mbstring": "~1.0"
+ },
+ "conflict": {
+ "symfony/dependency-injection": "<3.3"
+ },
+ "require-dev": {
+ "psr/log": "~1.0",
+ "symfony/config": "~3.3",
+ "symfony/dependency-injection": "~3.3",
+ "symfony/event-dispatcher": "~2.8|~3.0",
+ "symfony/filesystem": "~2.8|~3.0",
+ "symfony/http-kernel": "~2.8|~3.0",
+ "symfony/process": "~2.8|~3.0"
+ },
+ "suggest": {
+ "psr/log": "For using the console logger",
+ "symfony/event-dispatcher": "",
+ "symfony/filesystem": "",
+ "symfony/process": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Console\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Console Component",
+ "homepage": "https://symfony.com/",
+ "time": "2017-07-03T13:19:36+00:00"
+ },
+ {
+ "name": "symfony/debug",
+ "version": "v3.3.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/debug.git",
+ "reference": "63b85a968486d95ff9542228dc2e4247f16f9743"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/debug/zipball/63b85a968486d95ff9542228dc2e4247f16f9743",
+ "reference": "63b85a968486d95ff9542228dc2e4247f16f9743",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9",
+ "psr/log": "~1.0"
+ },
+ "conflict": {
+ "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2"
+ },
+ "require-dev": {
+ "symfony/http-kernel": "~2.8|~3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Debug\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Debug Component",
+ "homepage": "https://symfony.com/",
+ "time": "2017-07-05T13:02:37+00:00"
+ },
+ {
+ "name": "symfony/polyfill-mbstring",
+ "version": "v1.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
+ "reference": "f29dca382a6485c3cbe6379f0c61230167681937"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/f29dca382a6485c3cbe6379f0c61230167681937",
+ "reference": "f29dca382a6485c3cbe6379f0c61230167681937",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "suggest": {
+ "ext-mbstring": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Mbstring\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for the Mbstring extension",
+ "homepage": "https://symfony.com/",
+ "keywords": [
+ "compatibility",
+ "mbstring",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "time": "2017-06-09T14:24:12+00:00"
}
],
"packages-dev": [
@@ -636,6 +867,56 @@
],
"time": "2015-06-14T21:17:01+00:00"
},
+ {
+ "name": "google/cloud-tools",
+ "version": "v0.6.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/GoogleCloudPlatform/php-tools.git",
+ "reference": "90ecc5e371673078cf0fc71d442fd21415c277c3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/GoogleCloudPlatform/php-tools/zipball/90ecc5e371673078cf0fc71d442fd21415c277c3",
+ "reference": "90ecc5e371673078cf0fc71d442fd21415c277c3",
+ "shasum": ""
+ },
+ "require": {
+ "guzzlehttp/guzzle": "~5.3|~6.0",
+ "php": ">=5.5",
+ "phpunit/phpunit": "~4|~5",
+ "symfony/browser-kit": "~2|~3",
+ "symfony/process": "~2|~3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Google\\Cloud\\TestUtils\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "Takashi Matsuo",
+ "email": "tmatsuo@google.com",
+ "homepage": "https://wp.gaeflex.ninja/"
+ }
+ ],
+ "description": "PHP tools for Google Cloud Platform",
+ "homepage": "https://github.com/GoogleCloudPlatform/php-tools",
+ "keywords": [
+ "appengine",
+ "gcp",
+ "test"
+ ],
+ "time": "2017-02-23T22:19:51+00:00"
+ },
{
"name": "phpdocumentor/reflection-common",
"version": "1.0",
@@ -1594,82 +1875,166 @@
"time": "2015-06-21T13:59:46+00:00"
},
{
- "name": "squizlabs/php_codesniffer",
- "version": "2.9.1",
+ "name": "symfony/browser-kit",
+ "version": "v3.3.4",
"source": {
"type": "git",
- "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
- "reference": "dcbed1074f8244661eecddfc2a675430d8d33f62"
+ "url": "https://github.com/symfony/browser-kit.git",
+ "reference": "3a4435e79a8401746e8525e98039199d0924b4e5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/dcbed1074f8244661eecddfc2a675430d8d33f62",
- "reference": "dcbed1074f8244661eecddfc2a675430d8d33f62",
+ "url": "https://api.github.com/repos/symfony/browser-kit/zipball/3a4435e79a8401746e8525e98039199d0924b4e5",
+ "reference": "3a4435e79a8401746e8525e98039199d0924b4e5",
"shasum": ""
},
"require": {
- "ext-simplexml": "*",
- "ext-tokenizer": "*",
- "ext-xmlwriter": "*",
- "php": ">=5.1.2"
+ "php": ">=5.5.9",
+ "symfony/dom-crawler": "~2.8|~3.0"
},
"require-dev": {
- "phpunit/phpunit": "~4.0"
+ "symfony/css-selector": "~2.8|~3.0",
+ "symfony/process": "~2.8|~3.0"
},
- "bin": [
- "scripts/phpcs",
- "scripts/phpcbf"
+ "suggest": {
+ "symfony/process": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\BrowserKit\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
],
+ "description": "Symfony BrowserKit Component",
+ "homepage": "https://symfony.com/",
+ "time": "2017-06-24T09:29:48+00:00"
+ },
+ {
+ "name": "symfony/dom-crawler",
+ "version": "v3.3.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/dom-crawler.git",
+ "reference": "fc2c588ce376e9fe04a7b8c79e3ec62fe32d95b1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/fc2c588ce376e9fe04a7b8c79e3ec62fe32d95b1",
+ "reference": "fc2c588ce376e9fe04a7b8c79e3ec62fe32d95b1",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9",
+ "symfony/polyfill-mbstring": "~1.0"
+ },
+ "require-dev": {
+ "symfony/css-selector": "~2.8|~3.0"
+ },
+ "suggest": {
+ "symfony/css-selector": ""
+ },
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.x-dev"
+ "dev-master": "3.3-dev"
}
},
"autoload": {
- "classmap": [
- "CodeSniffer.php",
- "CodeSniffer/CLI.php",
- "CodeSniffer/Exception.php",
- "CodeSniffer/File.php",
- "CodeSniffer/Fixer.php",
- "CodeSniffer/Report.php",
- "CodeSniffer/Reporting.php",
- "CodeSniffer/Sniff.php",
- "CodeSniffer/Tokens.php",
- "CodeSniffer/Reports/",
- "CodeSniffer/Tokenizers/",
- "CodeSniffer/DocGenerators/",
- "CodeSniffer/Standards/AbstractPatternSniff.php",
- "CodeSniffer/Standards/AbstractScopeSniff.php",
- "CodeSniffer/Standards/AbstractVariableSniff.php",
- "CodeSniffer/Standards/IncorrectPatternException.php",
- "CodeSniffer/Standards/Generic/Sniffs/",
- "CodeSniffer/Standards/MySource/Sniffs/",
- "CodeSniffer/Standards/PEAR/Sniffs/",
- "CodeSniffer/Standards/PSR1/Sniffs/",
- "CodeSniffer/Standards/PSR2/Sniffs/",
- "CodeSniffer/Standards/Squiz/Sniffs/",
- "CodeSniffer/Standards/Zend/Sniffs/"
+ "psr-4": {
+ "Symfony\\Component\\DomCrawler\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-3-Clause"
+ "MIT"
],
"authors": [
{
- "name": "Greg Sherwood",
- "role": "lead"
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
- "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
- "homepage": "http://www.squizlabs.com/php-codesniffer",
- "keywords": [
- "phpcs",
- "standards"
+ "description": "Symfony DomCrawler Component",
+ "homepage": "https://symfony.com/",
+ "time": "2017-05-25T23:10:31+00:00"
+ },
+ {
+ "name": "symfony/process",
+ "version": "v3.3.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/process.git",
+ "reference": "5ab8949b682b1bf9d4511a228b5e045c96758c30"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/process/zipball/5ab8949b682b1bf9d4511a228b5e045c96758c30",
+ "reference": "5ab8949b682b1bf9d4511a228b5e045c96758c30",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Process\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
],
- "time": "2017-05-22T02:43:20+00:00"
+ "description": "Symfony Process Component",
+ "homepage": "https://symfony.com/",
+ "time": "2017-07-03T08:12:02+00:00"
},
{
"name": "symfony/yaml",
diff --git a/monitoring/monitoring.php b/monitoring/monitoring.php
new file mode 100644
index 0000000000..bfce086a3a
--- /dev/null
+++ b/monitoring/monitoring.php
@@ -0,0 +1,137 @@
+add(new Command('create-metric'))
+ ->setDefinition($inputDefinition)
+ ->setDescription('Creates a logging metric.')
+ ->setCode(function ($input, $output) {
+ create_metric(
+ $input->getArgument('project_id')
+ );
+ });
+
+$application->add(new Command('delete-metric'))
+ ->setDefinition(clone $inputDefinition)
+ ->addArgument('metric_id', InputArgument::REQUIRED, 'The metric descriptor id')
+ ->setDescription('Deletes a logging metric.')
+ ->setCode(function ($input, $output) {
+ delete_metric(
+ $input->getArgument('project_id'),
+ $input->getArgument('metric_id')
+ );
+ });
+
+$application->add(new Command('get-descriptor'))
+ ->setDefinition(clone $inputDefinition)
+ ->addArgument('metric_id', InputArgument::REQUIRED, 'The metric descriptor id')
+ ->setDescription('Gets a logging descriptor.')
+ ->setCode(function ($input, $output) {
+ get_descriptor(
+ $input->getArgument('project_id'),
+ $input->getArgument('metric_id')
+ );
+ });
+
+$application->add(new Command('list-descriptors'))
+ ->setDefinition($inputDefinition)
+ ->setDescription('Lists logging descriptors.')
+ ->setCode(function ($input, $output) {
+ list_descriptors(
+ $input->getArgument('project_id')
+ );
+ });
+
+$application->add(new Command('read-timeseries-align'))
+ ->setDefinition(clone $inputDefinition)
+ ->addOption('minutes-ago', null, InputOption::VALUE_REQUIRED, 20,
+ 'How many minutes in the past to start the time series.')
+ ->setDescription('Aggregates metrics for each timeseries.')
+ ->setCode(function ($input, $output) {
+ read_timeseries_align(
+ $input->getArgument('project_id'),
+ $input->getOption('minutes-ago')
+ );
+ });
+
+$application->add(new Command('read-timeseries-fields'))
+ ->setDefinition(clone $inputDefinition)
+ ->addOption('minutes-ago', null, InputOption::VALUE_REQUIRED, 20,
+ 'How many minutes in the past to start the time series.')
+ ->setDescription('Reads Timeseries fields.')
+ ->setCode(function ($input, $output) {
+ read_timeseries_fields(
+ $input->getArgument('project_id'),
+ $input->getOption('minutes-ago')
+ );
+ });
+
+$application->add(new Command('read-timeseries-reduce'))
+ ->setDefinition(clone $inputDefinition)
+ ->addOption('minutes-ago', null, InputOption::VALUE_REQUIRED, 20,
+ 'How many minutes in the past to start the time series.')
+ ->setDescription('Aggregates metrics across multiple timeseries.')
+ ->setCode(function ($input, $output) {
+ read_timeseries_reduce(
+ $input->getArgument('project_id'),
+ $input->getOption('minutes-ago')
+ );
+ });
+
+$application->add(new Command('read-timeseries-simple'))
+ ->setDefinition(clone $inputDefinition)
+ ->addOption('minutes-ago', null, InputOption::VALUE_REQUIRED, 20,
+ 'How many minutes in the past to start the time series.')
+ ->setDescription('Reads a timeseries.')
+ ->setCode(function ($input, $output) {
+ read_timeseries_simple(
+ $input->getArgument('project_id'),
+ $input->getOption('minutes-ago')
+ );
+ });
+
+$application->add(new Command('write-timeseries'))
+ ->setDefinition($inputDefinition)
+ ->setDescription('Writes a timeseries.')
+ ->setCode(function ($input, $output) {
+ write_timeseries(
+ $input->getArgument('project_id')
+ );
+ });
+
+// for testing
+if (getenv('PHPUNIT_TESTS') === '1') {
+ return $application;
+}
+
+$application->run();
diff --git a/monitoring/phpunit.xml.dist b/monitoring/phpunit.xml.dist
index 70fd0bed56..9d297ccb03 100644
--- a/monitoring/phpunit.xml.dist
+++ b/monitoring/phpunit.xml.dist
@@ -25,4 +25,7 @@
quickstart.php
+
+
+
diff --git a/monitoring/src/create_metric.php b/monitoring/src/create_metric.php
new file mode 100644
index 0000000000..0080b8b0c9
--- /dev/null
+++ b/monitoring/src/create_metric.php
@@ -0,0 +1,68 @@
+ $projectId,
+ ]);
+
+ $projectName = $metrics->formatProjectName($projectId);
+
+ $descriptor = new MetricDescriptor();
+ $descriptor->setDescription('Daily sales records from all branch stores.');
+ $descriptor->setDisplayName('Daily Sales');
+ $descriptor->setType('custom.googleapis.com/stores/daily_sales');
+ $descriptor->setMetricKind(MetricDescriptor_MetricKind::GAUGE);
+ $descriptor->setValueType(MetricDescriptor_ValueType::DOUBLE);
+ $descriptor->setUnit('{USD}');
+ $label = new LabelDescriptor();
+ $label->setKey('store_id');
+ $label->setValueType(LabelDescriptor_ValueType::STRING);
+ $label->setDescription('The ID of the store.');
+ $labels = [$label];
+ $descriptor->setLabels($labels);
+
+ $descriptor = $metrics->createMetricDescriptor($projectName, $descriptor);
+ printf('Created a metric: ' . $descriptor->getName() . PHP_EOL);
+}
+// [END monitoring_create_metric]
diff --git a/monitoring/src/delete_metric.php b/monitoring/src/delete_metric.php
new file mode 100644
index 0000000000..884d3eee46
--- /dev/null
+++ b/monitoring/src/delete_metric.php
@@ -0,0 +1,50 @@
+ $projectId,
+ ]);
+
+ $metricPath = $metrics->formatMetricDescriptorName($projectId, $metricId);
+ $ret = $metrics->deleteMetricDescriptor($metricPath);
+
+ printf('Deleted a metric: ' . $metricPath . PHP_EOL);
+}
+// [END monitoring_delete_metric]
diff --git a/monitoring/src/get_descriptor.php b/monitoring/src/get_descriptor.php
new file mode 100644
index 0000000000..a481e01c5b
--- /dev/null
+++ b/monitoring/src/get_descriptor.php
@@ -0,0 +1,62 @@
+ $projectId,
+ ]);
+
+ $metricName = $metrics->formatMetricDescriptorName($projectId, $metricId);
+ $descriptor = $metrics->getMetricDescriptor($metricName);
+
+ printf('Name: ' . $descriptor->getDisplayName() . PHP_EOL);
+ printf('Description: ' . $descriptor->getDescription() . PHP_EOL);
+ printf('Type: ' . $descriptor->getType() . PHP_EOL);
+ printf('Metric Kind: ' . $descriptor->getMetricKind() . PHP_EOL);
+ printf('Value Type: ' . $descriptor->getValueType() . PHP_EOL);
+ printf('Unit: ' . $descriptor->getUnit() . PHP_EOL);
+ printf('Labels:' . PHP_EOL);
+ foreach ($descriptor->getLabels() as $labels) {
+ printf(' %s (%s) - %s' . PHP_EOL,
+ $labels->getKey(),
+ $labels->getValueType(),
+ $labels->getDescription());
+ }
+}
+// [END monitoring_get_descriptor]
diff --git a/monitoring/src/list_descriptors.php b/monitoring/src/list_descriptors.php
new file mode 100644
index 0000000000..72a606f649
--- /dev/null
+++ b/monitoring/src/list_descriptors.php
@@ -0,0 +1,52 @@
+ $projectId,
+ ]);
+
+ $projectName = $metrics->formatProjectName($projectId);
+ $descriptors = $metrics->listMetricDescriptors($projectName);
+
+ printf('Metric Descriptors:' . PHP_EOL);
+ foreach ($descriptors->iterateAllElements() as $descriptor) {
+ printf($descriptor->getName() . PHP_EOL);
+ }
+}
+// [END monitoring_list_descriptors]
diff --git a/monitoring/src/read_timeseries_align.php b/monitoring/src/read_timeseries_align.php
new file mode 100644
index 0000000000..f1efe1a90f
--- /dev/null
+++ b/monitoring/src/read_timeseries_align.php
@@ -0,0 +1,88 @@
+ $projectId,
+ ]);
+
+ $projectName = $metrics->formatProjectName($projectId);
+ $filter = 'metric.type="compute.googleapis.com/instance/cpu/utilization"';
+
+ $startTime = new Timestamp();
+ $startTime->setSeconds(time() - (60 * $minutesAgo));
+ $endTime = new Timestamp();
+ $endTime->setSeconds(time());
+
+ $interval = new TimeInterval();
+ $interval->setStartTime($startTime);
+ $interval->setEndTime($endTime);
+
+ $alignmentPeriod = new Duration();
+ $alignmentPeriod->setSeconds(600);
+ $aggregation = new Aggregation();
+ $aggregation->setAlignmentPeriod($alignmentPeriod);
+ $aggregation->setPerSeriesAligner(Aggregation_Aligner::ALIGN_MEAN);
+
+ $view = ListTimeSeriesRequest_TimeSeriesView::FULL;
+
+ $result = $metrics->listTimeSeries(
+ $projectName,
+ $filter,
+ $interval,
+ $view,
+ ['aggregation' => $aggregation]);
+
+ printf('CPU utilization:' . PHP_EOL);
+ foreach ($result->iterateAllElements() as $timeSeries) {
+ printf($timeSeries->getMetric()->getLabels()['instance_name'] . PHP_EOL);
+ printf(' Now: ');
+ printf($timeSeries->getPoints()[0]->getValue()->getDoubleValue() . PHP_EOL);
+ if (count($timeSeries->getPoints()) > 1) {
+ printf(' 10 minutes ago: ');
+ printf($timeSeries->getPoints()[1]->getValue()->getDoubleValue() . PHP_EOL);
+ }
+ }
+}
+// [END monitoring_read_timeseries_align]
diff --git a/monitoring/src/read_timeseries_fields.php b/monitoring/src/read_timeseries_fields.php
new file mode 100644
index 0000000000..19f2c2fc0c
--- /dev/null
+++ b/monitoring/src/read_timeseries_fields.php
@@ -0,0 +1,72 @@
+ $projectId,
+ ]);
+
+ $projectName = $metrics->formatProjectName($projectId);
+ $filter = 'metric.type="compute.googleapis.com/instance/cpu/utilization"';
+
+ $startTime = new Timestamp();
+ $startTime->setSeconds(time() - (60 * $minutesAgo));
+ $endTime = new Timestamp();
+ $endTime->setSeconds(time());
+
+ $interval = new TimeInterval();
+ $interval->setStartTime($startTime);
+ $interval->setEndTime($endTime);
+
+ $view = ListTimeSeriesRequest_TimeSeriesView::HEADERS;
+
+ $result = $metrics->listTimeSeries(
+ $projectName,
+ $filter,
+ $interval,
+ $view);
+
+ printf('Found data points for the following instances:' . PHP_EOL);
+ foreach ($result->iterateAllElements() as $timeSeries) {
+ printf($timeSeries->getMetric()->getLabels()['instance_name'] . PHP_EOL);
+ }
+}
+// [END monitoring_read_timeseries_fields]
diff --git a/monitoring/src/read_timeseries_reduce.php b/monitoring/src/read_timeseries_reduce.php
new file mode 100644
index 0000000000..6680fac5a6
--- /dev/null
+++ b/monitoring/src/read_timeseries_reduce.php
@@ -0,0 +1,88 @@
+ $projectId,
+ ]);
+
+ $projectName = $metrics->formatProjectName($projectId);
+ $filter = 'metric.type="compute.googleapis.com/instance/cpu/utilization"';
+
+ $startTime = new Timestamp();
+ $startTime->setSeconds(time() - (60 * $minutesAgo));
+ $endTime = new Timestamp();
+ $endTime->setSeconds(time());
+
+ $interval = new TimeInterval();
+ $interval->setStartTime($startTime);
+ $interval->setEndTime($endTime);
+
+ $alignmentPeriod = new Duration();
+ $alignmentPeriod->setSeconds(600);
+ $aggregation = new Aggregation();
+ $aggregation->setAlignmentPeriod($alignmentPeriod);
+ $aggregation->setCrossSeriesReducer(Aggregation_Reducer::REDUCE_MEAN);
+ $aggregation->setPerSeriesAligner(Aggregation_Aligner::ALIGN_MEAN);
+
+ $view = ListTimeSeriesRequest_TimeSeriesView::FULL;
+
+ $result = $metrics->listTimeSeries(
+ $projectName,
+ $filter,
+ $interval,
+ $view,
+ ['aggregation' => $aggregation]);
+
+ $reductions = $result->iterateAllElements()->current()->getPoints();
+ printf('Average CPU utilization across all GCE instances:' . PHP_EOL);
+ printf(' Last 10 minutes: ');
+ printf($reductions[0]->getValue()->getDoubleValue() . PHP_EOL);
+ if (count($reductions) > 1) {
+ printf(' 10-20 minutes ago: ');
+ printf($reductions[1]->getValue()->getDoubleValue() . PHP_EOL);
+ }
+}
+// [END monitoring_read_timeseries_reduce]
diff --git a/monitoring/src/read_timeseries_simple.php b/monitoring/src/read_timeseries_simple.php
new file mode 100644
index 0000000000..bdc94f4c44
--- /dev/null
+++ b/monitoring/src/read_timeseries_simple.php
@@ -0,0 +1,77 @@
+ $projectId,
+ ]);
+
+ $projectName = $metrics->formatProjectName($projectId);
+ $filter = 'metric.type="compute.googleapis.com/instance/cpu/utilization"';
+
+ // Limit results to the last 20 minutes
+ $startTime = new Timestamp();
+ $startTime->setSeconds(time() - (60 * $minutesAgo));
+ $endTime = new Timestamp();
+ $endTime->setSeconds(time());
+
+ $interval = new TimeInterval();
+ $interval->setStartTime($startTime);
+ $interval->setEndTime($endTime);
+
+ $view = ListTimeSeriesRequest_TimeSeriesView::FULL;
+
+ $result = $metrics->listTimeSeries(
+ $projectName,
+ $filter,
+ $interval,
+ $view);
+
+ printf('CPU utilization:' . PHP_EOL);
+ 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);
+ }
+ }
+}
+// [END monitoring_read_timeseries_simple]
diff --git a/monitoring/src/write_timeseries.php b/monitoring/src/write_timeseries.php
new file mode 100644
index 0000000000..62103f24e9
--- /dev/null
+++ b/monitoring/src/write_timeseries.php
@@ -0,0 +1,88 @@
+ $projectId,
+ ]);
+
+ $projectName = $metrics->formatProjectName($projectId);
+ $filter = 'metric.type="compute.googleapis.com/instance/cpu/utilization"';
+
+ $endTime = new Timestamp();
+ $endTime->setSeconds(time());
+ $interval = new TimeInterval();
+ $interval->setEndTime($endTime);
+
+ $value = new TypedValue();
+ $value->setDoubleValue(123.45);
+
+ $point = new Point();
+ $point->setValue($value);
+ $point->setInterval($interval);
+ $points = [$point];
+
+ $metric = new Metric();
+ $metric->setType('custom.googleapis.com/stores/daily_sales');
+ $labels = ['store_id' => 'Pittsburg'];
+ $metric->setLabels($labels);
+
+ $resource = new MonitoredResource();
+ $resource->setType('global');
+ $labels = ['project_id' => $projectId];
+ $resource->setLabels($labels);
+
+ $timeSeries = new TimeSeries();
+ $timeSeries->setMetric($metric);
+ $timeSeries->setResource($resource);
+ $timeSeries->setPoints($points);
+
+ $result = $metrics->createTimeSeries(
+ $projectName,
+ [$timeSeries]);
+
+ printf('Done writing time series data.' . PHP_EOL);
+}
+// [END monitoring_write_timeseries]
diff --git a/monitoring/test/monitoringTest.php b/monitoring/test/monitoringTest.php
new file mode 100644
index 0000000000..3410af3673
--- /dev/null
+++ b/monitoring/test/monitoringTest.php
@@ -0,0 +1,141 @@
+runCommand('create-metric');
+ $this->assertContains('Created a metric', $output);
+ $this->assertContains(self::$metricId, $output);
+
+ // ensure the metric gets created
+ $this->eventuallyConsistentRetryCount = 20;
+ $this->runEventuallyConsistentTest(function () {
+ $output = $this->runCommand('get-descriptor', [
+ 'metric_id' => self::$metricId,
+ ]);
+ $this->assertContains(self::$metricId, $output);
+ });
+ }
+
+ /** @depends testCreateMetric */
+ public function testGetDescriptor()
+ {
+ $output = $this->runCommand('get-descriptor', [
+ 'metric_id' => self::$metricId,
+ ]);
+ $this->assertContains(self::$metricId, $output);
+ }
+
+ /** @depends testCreateMetric */
+ public function testListDescriptors()
+ {
+ $output = $this->runCommand('list-descriptors');
+ $this->assertContains(self::$metricId, $output);
+ }
+
+ /** @depends testCreateMetric */
+ public function testDeleteMetric()
+ {
+ $output = $this->runCommand('delete-metric', [
+ 'metric_id' => self::$metricId,
+ ]);
+ $this->assertContains('Deleted a metric', $output);
+ $this->assertContains(self::$metricId, $output);
+ }
+
+ public function testWriteTimeseries()
+ {
+ $output = $this->runCommand('write-timeseries');
+ $this->assertContains('Done writing time series data', $output);
+ }
+
+ /** @depends testWriteTimeseries */
+ public function testReadTimeseriesAlign()
+ {
+ $output = $this->runCommand('read-timeseries-align', [
+ '--minutes-ago' => self::$minutesAgo
+ ]);
+ $this->assertContains('Now', $output);
+ }
+
+ /** @depends testWriteTimeseries */
+ public function testReadTimeseriesFields()
+ {
+ $output = $this->runCommand('read-timeseries-fields', [
+ '--minutes-ago' => self::$minutesAgo
+ ]);
+ $this->assertContains('Found data points', $output);
+ $this->assertGreaterThanOrEqual(2, substr_count($output, "\n"));
+ }
+
+ /** @depends testWriteTimeseries */
+ public function testReadTimeseriesReduce()
+ {
+ $output = $this->runCommand('read-timeseries-reduce', [
+ '--minutes-ago' => self::$minutesAgo
+ ]);
+ $this->assertContains('Last 10 minutes', $output);
+ }
+
+ /** @depends testWriteTimeseries */
+ public function testReadTimeseriesSimple()
+ {
+ $output = $this->runCommand('read-timeseries-simple', [
+ '--minutes-ago' => self::$minutesAgo
+ ]);
+ $this->assertContains('CPU utilization:', $output);
+ $this->assertGreaterThanOrEqual(2, substr_count($output, "\n"));
+ }
+
+ private function runCommand($commandName, $args = [])
+ {
+ $application = require __DIR__ . '/../monitoring.php';
+ $command = $application->get($commandName);
+ $commandTester = new CommandTester($command);
+
+ ob_start();
+ $commandTester->execute(
+ ['project_id' => self::$projectId] + $args,
+ ['interactive' => false]);
+
+ return ob_get_clean();
+ }
+}