Skip to content

Commit ea34628

Browse files
authored
docs: add getting started to help docs (#8085)
1 parent e651206 commit ea34628

8 files changed

Lines changed: 795 additions & 9 deletions

File tree

.kokoro/docs/publish.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ $PROJECT_DIR/dev/google-cloud docfx \
6363
# Add product-neutral guides
6464
$PROJECT_DIR/dev/google-cloud docfx \
6565
--generate-product-neutral-guides \
66+
--out help-out \
6667
--metadata-version 1.0.0 \
6768
$STAGING_FLAG \
6869
$VERBOSITY_FLAG

dev/src/Command/DocFxCommand.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ class DocFxCommand extends Command
5151
];
5252

5353
private static array $productNeutralGuides = [
54+
'README.md' => 'Getting Started',
5455
'AUTHENTICATION.md' => 'Authentication',
5556
'DEBUG.md' => 'Debug Logging',
5657
'MIGRATING.md' => 'Migrating to V2',

dev/tests/Unit/Command/DocFxCommandTest.php

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -194,22 +194,39 @@ public function testNewClientMagicMethods()
194194
$this->assertGreaterThan(0, count($asyncMethods));
195195
}
196196

197-
public function testProductNeutralGuides()
197+
public function provideProductNeutralGuides()
198198
{
199199
self::getCommandTester()->execute([
200200
'--generate-product-neutral-guides' => true,
201201
'--out' => $tmpDir = sys_get_temp_dir() . '/' . rand(),
202202
'--metadata-version' => '1.0.0',
203203
]);
204204

205-
$generatedFiles = array_diff(scandir($tmpDir), ['..', '.']);
206-
$this->assertEquals([
207-
'authentication.md',
208-
'debug.md',
209-
'docs.metadata',
210-
'migrating.md',
211-
'toc.yml',
212-
], array_values($generatedFiles));
205+
$generatedFiles = array_filter(
206+
array_diff(scandir($tmpDir), ['..', '.']),
207+
fn ($file) => $file !== 'docs.metadata'
208+
);
209+
210+
return array_map(
211+
fn ($file) => [$tmpDir . '/' . $file],
212+
$generatedFiles
213+
);
214+
}
215+
216+
/**
217+
* @dataProvider provideProductNeutralGuides
218+
*/
219+
public function testProductNeutralGuides(string $filepath)
220+
{
221+
$file = basename($filepath);
222+
$this->assertTrue(
223+
file_exists(self::$fixturesDir . '/docfx/ProductNeutralGuides/' . basename($file)),
224+
sprintf(self::$fixturesDir . '/docfx/ProductNeutralGuides/%s does not exist (%s)', $file, self::$tmpDir . '/' . $file)
225+
);
226+
227+
$left = self::$fixturesDir . '/docfx/ProductNeutralGuides/' . $file;
228+
$right = $filepath;
229+
$this->assertFileEqualsWithDiff($left, $right, '1' === getenv('UPDATE_FIXTURES'));
213230
}
214231

215232
private function assertFileEqualsWithDiff(string $left, string $right, bool $updateFixtures = false)
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# Authentication
2+
3+
The recommended way to authenticate to the Google Cloud PHP library is to use
4+
[Application Default Credentials (ADC)](https://cloud.google.com/docs/authentication/application-default-credentials),
5+
which discovers your credentials automatically, based on the environment where your code is running.
6+
To review all of your authentication options see [Credential Lookup](#credential-lookup).
7+
8+
For more information about authentication at Google, see [the authentication guide](https://cloud.google.com/docs/authentication).
9+
Specific instructions and environment variables for each individual service are linked from the README documents listed below for each service.
10+
11+
## Credential Lookup
12+
13+
The Google Cloud PHP library provides several mechanisms to configure your system without providing
14+
**Service Account Credentials** directly in code.
15+
16+
**Credentials** are discovered in the following order:
17+
18+
1. Credentials specified in code
19+
2. Path to credential file in environment variables
20+
3. Credentials specified in a local ADC file
21+
4. Credentials from an attached service account (for code running on Google Cloud Platform)
22+
23+
### Google Cloud Platform environments
24+
25+
While running on Google Cloud Platform environments such as Google Compute Engine, Google App Engine
26+
and Google Kubernetes Engine, no extra work is needed. The **Credentials** and are discovered
27+
automatically from the attached service account. Code should be written as if already authenticated.
28+
29+
For more information, see
30+
[Set up ADC for Google Cloud services](https://cloud.google.com/docs/authentication/provide-credentials-adc#attached-sa).
31+
32+
### Environment Variables
33+
34+
**NOTE**: This library uses [`getenv`](https://www.php.net/manual/en/function.getenv.php), so if
35+
your environemnt variables are set in PHP, they must use
36+
[`putenv`](https://www.php.net/manual/en/function.putenv.php),
37+
38+
```php
39+
putenv("GOOGLE_APPLICATION_CREDENTIALS=" . __DIR__ . '/your-credentials-file.json');
40+
```
41+
The **Credentials JSON** can be placed in environment variables instead of
42+
declaring them directly in code.
43+
44+
Here are the environment variables that Google Cloud PHP checks for credentials:
45+
46+
1. `GOOGLE_APPLICATION_CREDENTIALS` - Path to JSON file
47+
48+
The JSON file can contain credentials created for
49+
[workload identity federation](https://cloud.google.com/iam/docs/workload-identity-federation),
50+
[workforce identity federation](https://cloud.google.com/iam/docs/workforce-identity-federation), or a
51+
[service account key](https://cloud.google.com/docs/authentication/provide-credentials-adc#local-key).
52+
53+
Note: Service account keys are a security risk if not managed correctly. You should
54+
[choose a more secure alternative to service account keys](https://cloud.google.com/docs/authentication#auth-decision-tree)
55+
whenever possible.
56+
57+
### Project ID detection
58+
59+
Some libraries support setting up the project ID via the `GOOGLE_CLOUD_PROJECT` environment variable.
60+
```php
61+
putenv("GOOGLE_CLOUD_PROJECT=<YOUR_PROJECT_ID>");
62+
```
63+
The libraries that support this environment variable are:
64+
- Bigtable
65+
- PubSub
66+
- Storage
67+
- Spanner
68+
- BigQuery
69+
- Datastore
70+
- Firestore
71+
- Debugger
72+
- Logging
73+
- Trace
74+
- Translate
75+
76+
### Client Authentication
77+
78+
Each Google Cloud PHP client may be authenticated in code when creating a client library instance.
79+
80+
Most clients use the `credentials` option for providing credentials as a constructor option:
81+
82+
```php
83+
require 'vendor/autoload.php';
84+
85+
use Google\Cloud\VideoIntelligence\V1\VideoIntelligenceServiceClient;
86+
87+
// Authenticating with keyfile data.
88+
$video = new VideoIntelligenceServiceClient([
89+
'credentials' => json_decode(file_get_contents('/path/to/credential-file.json'), true)
90+
]);
91+
92+
// Authenticating with a keyfile path.
93+
$video = new VideoIntelligenceServiceClient([
94+
'credentials' => '/path/to/credential-file.json'
95+
]);
96+
```
97+
98+
### Local ADC file
99+
100+
This option allows for an easy way to authenticate in a local environment during development. If
101+
credentials are not provided in code or in environment variables, then your user credentials can be
102+
discovered from your local ADC file.
103+
104+
To set up a local ADC file:
105+
106+
1. [Download, install, and initialize the Cloud SDK](https://cloud.google.com/sdk)
107+
2. Create your local ADC file:
108+
109+
```sh
110+
gcloud auth application-default login
111+
```
112+
113+
3. Write code as if already authenticated.
114+
115+
**NOTE:** Because this method relies on your user credentials, it is _not_ recommended for running
116+
in production.
117+
118+
For more information about setting up authentication for a local development environment, see
119+
[Set up Application Default Credentials](https://cloud.google.com/docs/authentication/provide-credentials-adc#local-dev).
120+
121+
## Troubleshooting
122+
123+
If you're having trouble authenticating open a
124+
[Github Issue](https://github.com/googleapis/google-cloud-php/issues/new?title=Authentication+question)
125+
to get help. Also consider searching or asking
126+
[questions](http://stackoverflow.com/questions/tagged/google-cloud-platform+php) on
127+
[StackOverflow](http://stackoverflow.com).
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
# Debugging
2+
3+
There are a few features built into the Google Cloud PHP client libraries which can help you debug
4+
your application. This guide will show you how to log client library requests and responses.
5+
6+
> :warning:
7+
>
8+
> These logs are not intended to be used in production and are meant to be used only for quickly
9+
> debugging a project. The logs consists of basic logging to STDOUT, which may or may not include
10+
> sensitive information. Make sure that once you are done debugging to disable the debugging flag or
11+
> configuration used to avoid leaking sensitive user data. This may also include authentication
12+
> tokens.
13+
14+
## Log examples
15+
16+
```php
17+
// debug-logging-example.php
18+
use Google\Cloud\Translate\V3\Client\TranslationServiceClient;
19+
use Google\Cloud\Translate\V3\TranslateTextRequest;
20+
21+
$client = new TranslationServiceClient();
22+
23+
$request = new TranslateTextRequest();
24+
$request->setTargetLanguageCode('en-US');
25+
$request->setContents(['こんにちは']);
26+
$request->setParent('projects/php-docs-samples-kokoro');
27+
28+
// The request and response will be logged to STDOUT when the environment
29+
// variable GOOGLE_SDK_PHP_LOGGING=true
30+
$response = $client->translateText($request);
31+
```
32+
33+
```sh
34+
$ GOOGLE_SDK_PHP_LOGGING=true php debug-logging-example.php
35+
{"timestamp":"2024-12-11T19:40:00+00:00","severity":"DEBUG","processId":44180,"jsonPayload":{"serviceName":"google.cloud.translation.v3.TranslationService","clientConfiguration":[]}}
36+
{"timestamp":"2024-12-11T19:40:00+00:00","severity":"DEBUG","processId":44180,"requestId":3821560043,"jsonPayload":{"request.method":"POST","request.url":"https://oauth2.googleapis.com/token","request.headers":{"Host":["oauth2.googleapis.com"],"Cache-Control":["no-store"],"Content-Type":["application/x-www-form-urlencoded"],"x-goog-api-client":["gl-php/8.3.14 auth/1.45.0 auth-request-type/at cred-type/u"]},"request.payload":"grant_type=refresh_token&refresh_token=<REFRESH_TOKEN>&client_id=<CLIENT_ID>&client_secret=<CLIENT_SECRET>"}}
37+
{"timestamp":"2024-12-11T19:40:00+00:00","severity":"DEBUG","processId":44180,"requestId":3821560043,"jsonPayload":{"response.status":200,"response.headers":{"x-google-esf-cloud-client-params":["backend_service_name: \"oauth2.googleapis.com\" backend_fully_qualified_method: \"google.identity.oauth2.OAuth2Service.GetToken\""],"X-Google-Session-Info":["<SESSION_INFO>"],"Date":["Wed, 11 Dec 2024 19:40:00 GMT"],"Pragma":["no-cache"],"Expires":["Mon, 01 Jan 1990 00:00:00 GMT"],"Cache-Control":["no-cache, no-store, max-age=0, must-revalidate"],"Content-Type":["application/json; charset=utf-8"],"X-Google-Security-Signals":["FRAMEWORK=ONE_PLATFORM,ENV=borg,ENV_DEBUG=borg_user:identity-oauth2-proxy;borg_job:prod.identity-oauth2-proxy","FRAMEWORK=HTTPSERVER2,BUILD=GOOGLE3,BUILD_DEBUG=cl:694072944,ENV=borg,ENV_DEBUG=borg_user:identity-oauth2-proxy;borg_job:prod.identity-oauth2-proxy"],"Vary":["X-Origin","Referer","Origin,Accept-Encoding"],"Server":["scaffolding on HTTPServer2"],"X-Google-Netmon-Label":["/bns/dz/borg/dz/bns/identity-oauth2-proxy/prod.identity-oauth2-proxy/4"],"X-XSS-Protection":["0"],"X-Frame-Options":["SAMEORIGIN"],"X-Content-Type-Options":["nosniff"],"X-Google-GFE-Service-Trace":["google-identity-oauth2-oauth2proxyservice-prod"],"X-Google-Backends":["unix:/tmp/esfbackend.1733439890.116447.177528,/bns/dz/borg/dz/bns/identity-oauth2-proxy/prod.identity-oauth2-proxy/4,/bns/ncsfoa/borg/ncsfoa/bns/blue-layer1-gfe-prod-edge/prod.blue-layer1-gfe.sfo03s27/15"],"X-Google-GFE-Request-Trace":["acsfon13:443,/bns/dz/borg/dz/bns/identity-oauth2-proxy/prod.identity-oauth2-proxy/4,acsfon13:443"],"X-Google-DOS-Service-Trace":["main:google-identity-oauth2-oauth2proxyservice-prod,main:GLOBAL_all_non_cloud"],"X-Google-GFE-Handshake-Trace":["GFE: /bns/ncsfoa/borg/ncsfoa/bns/blue-layer1-gfe-prod-edge/prod.blue-layer1-gfe.sfo03s27/15,Mentat oracle: [2002:a05:635e:38e:b0:178:f5eb:ee40]:9801"],"X-Google-Service":["google-identity-oauth2-oauth2proxyservice-prod"],"X-Google-GFE-Response-Code-Details-Trace":["response_code_set_by_backend"],"X-Google-GFE-Response-Body-Transformations":["gunzipped,chunked"],"X-Google-Shellfish-Status":["CA0gBEBG"],"X-Google-GFE-Version":["2.903.2"],"Alt-Svc":["h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000"],"Accept-Ranges":["none"],"Transfer-Encoding":["chunked"]},"response.payload":"{\n \"access_token\": \"<ACCESS_TOKEN>\",\n \"expires_in\": 3599,\n \"scope\": \"https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/sqlservice.login https://www.googleapis.com/auth/cloud-platform openid\",\n \"token_type\": \"Bearer\",\n \"id_token\": \"<ID_TOKEN>","latencyMillis":114}}
38+
{"timestamp":"2024-12-11T19:40:00+00:00","severity":"DEBUG","processId":44180,"requestId":4274868307,"jsonPayload":{"request.headers":{"x-goog-api-client":["gl-php/8.3.14 gapic/1.20.0 gax/1.36.0 grpc/1.59.1 rest/1.36.0 pb/+n"],"User-Agent":["gcloud-php-new/1.20.0"],"X-Goog-User-Project":["<YOUR_PROJECT>"],"x-goog-request-params":["parent=projects%2F<YOUR_PROJECT>"]},"request.payload":"{\"contents\":[\"こんにちは\"],\"targetLanguageCode\":\"en-US\",\"parent\":\"projects\\/<YOUR_PROJECT>\"}"}}
39+
{"timestamp":"2024-12-11T19:40:00+00:00","severity":"DEBUG","processId":44180,"requestId":4274868307,"jsonPayload":{"response.status":0,"response.headers":{"pc-high-bwd-bin":["KgIYJQ"]},"response.payload":"{\"translations\":[{\"translatedText\":\"Hello\",\"detectedLanguageCode\":\"ja\"}]}","latencyMillis":242}}
40+
```
41+
42+
<details>
43+
<summary>Request example log (expanded)</summary>
44+
45+
```json
46+
{
47+
"timestamp": "2024-12-03T15:21:47-05:00",
48+
"severity": "DEBUG",
49+
"processId": 44180,
50+
"requestId": 3821560043,
51+
"jsonPayload": {
52+
"request.method": "POST",
53+
"request.url": "https://translate.googleapis.com/v3/projects/<YOUR_PROJECT",
54+
"request.headers": {
55+
"Host": [
56+
"translate.googleapis.com"
57+
],
58+
"Content-Type": [
59+
"application/json"
60+
],
61+
"x-goog-api-client": [
62+
"gl-php/8.2.24 gapic/1.20.0 gax/1.35.0 grpc/1.66.0 rest/1.35.0 pb/+n"
63+
],
64+
"User-Agent": [
65+
"gcloud-php-new/1.20.0"
66+
],
67+
"X-Goog-User-Project": [
68+
"<YOUR_PROJECT>"
69+
],
70+
"x-goog-request-params": [
71+
"parent=projects%2F<YOUR_PROJECT>"
72+
],
73+
"authorization": [
74+
"Bearer <YOUR_AUTHORIZATION_TOKEN>"
75+
]
76+
},
77+
"request.payload": "{\"contents\":[\"こんにちは\"],\"targetLanguageCode\":\"en-US\",\"parent\":\"projects\\/<YOUR_PROJECT>\"}"
78+
}
79+
}
80+
```
81+
82+
</details>
83+
<details>
84+
<summary>Response example log (expanded)</summary>
85+
86+
```json
87+
{
88+
"timestamp": "2024-12-03T15:21:47-05:00",
89+
"severity": "DEBUG",
90+
"processId": 44180,
91+
"requestId": 3821560043,
92+
"jsonPayload": {
93+
"response.headers": {
94+
"Content-Type": [
95+
"application/json; charset=UTF-8"
96+
],
97+
"Vary": [
98+
"X-Origin",
99+
"Referer",
100+
"Origin,Accept-Encoding"
101+
],
102+
"Date": [
103+
"Tue, 03 Dec 2024 20:21:47 GMT"
104+
],
105+
"Server": [
106+
"ESF"
107+
],
108+
"Cache-Control": [
109+
"private"
110+
],
111+
"X-XSS-Protection": [
112+
"0"
113+
],
114+
"X-Frame-Options": [
115+
"SAMEORIGIN"
116+
],
117+
"X-Content-Type-Options": [
118+
"nosniff"
119+
],
120+
"Accept-Ranges": [
121+
"none"
122+
],
123+
"Transfer-Encoding": [
124+
"chunked"
125+
]
126+
},
127+
"response.payload": "{\"translations\":[{\"translatedText\": \"Hello\",\"detectedLanguageCode\":\"ja\"}]}",
128+
"latencyMillis": 152
129+
}
130+
}
131+
```
132+
133+
</details>
134+
135+
## Configuration
136+
137+
There are a few ways to configure debug logging which we will go through in this document.
138+
139+
### The `GOOGLE_SDK_PHP_LOGGING` environment variable
140+
141+
You can enable logging on all the different clients on your code by using this environment variable
142+
to `true`. Once this environment variable is set, all the clients used on your code will start
143+
logging the requests into `STDOUT`.
144+
145+
```php
146+
putenv('GOOGLE_SDK_PHP_LOGGING=true');
147+
148+
$client = new TranslationServiceClient();
149+
```
150+
151+
Logs usually come with a request log and a response log the exception being streaming requests
152+
where depending on the type of streaming it logs each stream packet. This means that if the client
153+
performs a request to the auth server it will also log that request-response pair before the main
154+
request.
155+
156+
157+
### Passing a PSR-3 compliant logger
158+
159+
The debugging code has been made to comply with the PSR-3 logging interface. With in mind we can
160+
pass a compatible logger to the client configuration.
161+
162+
```php
163+
use Monolog\Handler\StreamHandler;
164+
use Monolog\Level;
165+
use Monolog\Logger;
166+
167+
$monologLogger = new Logger('sdk client');
168+
$monologLogger->pushHandler(new StreamHandler('php://stdout', Level::Debug));
169+
170+
$client = new TranslationServiceClient([
171+
'logger' => $monologLogger
172+
]);
173+
```
174+
175+
With this you now you will be using Monolog's logger instead of the internal one. This also opens
176+
the opportunity to extend the capabilities of logging in case that you have specific needs, a PSR-3
177+
logger implementation can be passed to manage the logs in any way that are needed.
178+
179+
### Passing `false` to the configuration
180+
181+
The `logger` option on the client configuration options disables any logging for that specific
182+
client.
183+
184+
```php
185+
$client = new TranslationServiceClient([
186+
'logger' => false
187+
]);
188+
```
189+
190+
With this you can have different clients and either log in only one or disable individual clients
191+
from logging to avoid excessive noise.
192+
193+
```php
194+
putenv('GOOGLE_SDK_PHP_LOGGING=true');
195+
196+
// The Big Table client will log all the requests
197+
$client = new BigtableClient();
198+
199+
// The TranslationServiceClient will not log any requests
200+
$client = new TranslationServiceClient([
201+
'logger' => false
202+
]);
203+
```

0 commit comments

Comments
 (0)