Skip to content

Commit e95c0d5

Browse files
author
Takashi Matsuo
authored
Adding commands for log export. (GoogleCloudPlatform#160)
Adding commands for log export.
1 parent 32fa66b commit e95c0d5

11 files changed

+529
-3
lines changed

logging/README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Stackdriver Logging v2 API Samples
2+
3+
`logging.php` is a simple command-line program to demonstrate writing to a log,
4+
listing its entries, deleting it, interacting with sinks to export logs to
5+
Google Cloud Storage.
6+
7+
To use logging sinks, you will also need a Google Cloud Storage Bucket.
8+
9+
gsutil mb gs://[YOUR_PROJECT_ID]
10+
11+
You must add Cloud Logging as an owner to the bucket. To do so, add
12+
`[email protected]` as an owner to the bucket. See the
13+
[exportings logs](https://cloud.google.com/logging/docs/export/configure_export#configuring_log_sinks)
14+
docs for complete details.
15+
16+
# Running locally
17+
18+
Use the [Cloud SDK](https://cloud.google.com/sdk) to provide authentication:
19+
20+
gcloud beta auth application-default login
21+
22+
Run the samples:
23+
24+
```
25+
php logging.php list # For getting sub command list
26+
php logging.php help write # For showing help for write sub command `write`
27+
```
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,19 @@
1818

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

21+
use Google\Cloud\Samples\Logging\CreateSinkCommand;
2122
use Google\Cloud\Samples\Logging\DeleteLoggerCommand;
23+
use Google\Cloud\Samples\Logging\DeleteSinkCommand;
2224
use Google\Cloud\Samples\Logging\ListEntriesCommand;
25+
use Google\Cloud\Samples\Logging\ListSinksCommand;
2326
use Google\Cloud\Samples\Logging\WriteCommand;
2427
use Symfony\Component\Console\Application;
2528

2629
$application = new Application();
30+
$application->add(new CreateSinkCommand());
2731
$application->add(new DeleteLoggerCommand());
32+
$application->add(new DeleteSinkCommand());
2833
$application->add(new ListEntriesCommand());
34+
$application->add(new ListSinksCommand());
2935
$application->add(new WriteCommand());
3036
$application->run();

logging/src/CreateSinkCommand.php

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
/**
3+
* Copyright 2016 Google Inc. All Rights Reserved.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
namespace Google\Cloud\Samples\Logging;
19+
20+
// [START create_sink_use]
21+
use Google\Cloud\Logging\LoggingClient;
22+
// [END create_sink_use]
23+
use Symfony\Component\Console\Input\InputOption;
24+
use Symfony\Component\Console\Input\InputInterface;
25+
use Symfony\Component\Console\Output\OutputInterface;
26+
27+
/**
28+
* Class CreateSinkCommand
29+
* @package Google\Cloud\Samples\Logging
30+
*
31+
* This command simply creates a sink.
32+
*/
33+
class CreateSinkCommand extends BaseCommand
34+
{
35+
protected function configure()
36+
{
37+
$this
38+
->setName('create-sink')
39+
->setDescription('Creates a Logging sink')
40+
->addOption(
41+
'sink',
42+
null,
43+
InputOption::VALUE_OPTIONAL,
44+
'The name of the Logging sink',
45+
'my_sink'
46+
)
47+
->addOption(
48+
'bucket',
49+
null,
50+
InputOption::VALUE_REQUIRED,
51+
'The destination bucket name'
52+
)->addOption(
53+
'filter',
54+
null,
55+
InputOption::VALUE_OPTIONAL,
56+
'The filter expression for the sink',
57+
''
58+
);
59+
$this->addCommonOptions();
60+
}
61+
62+
protected function execute(InputInterface $input, OutputInterface $output)
63+
{
64+
$sinkName = $input->getOption('sink');
65+
$projectId = $input->getOption('project');
66+
$loggerName = $input->getOption('logger');
67+
$filter = $input->getOption('filter');
68+
$bucketName = $input->getOption('bucket');
69+
// [START create_sink]
70+
$destination = sprintf(
71+
'storage.googleapis.com/%s',
72+
$bucketName
73+
);
74+
$loggerFullName = sprintf(
75+
'projects/%s/logs/%s',
76+
$projectId,
77+
$loggerName
78+
);
79+
$filterString = sprintf('logName = "%s"', $loggerFullName);
80+
if (!empty($filter)) {
81+
$filterString .= ' AND ' . $filter;
82+
}
83+
$logging = new LoggingClient(['projectId' => $projectId]);
84+
$logging->createSink(
85+
$sinkName,
86+
$destination,
87+
['filter' => $filterString]
88+
);
89+
// [END create_sink]
90+
printf("Created a sink '%s'." . PHP_EOL, $sinkName);
91+
}
92+
}

logging/src/DeleteLoggerCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,6 @@ protected function execute(InputInterface $input, OutputInterface $output)
4848
$logger = $logging->logger($loggerName);
4949
$logger->delete();
5050
// [END delete_logger]
51-
printf("Deleted a logger '%s'.\n", $loggerName);
51+
printf("Deleted a logger '%s'." . PHP_EOL, $loggerName);
5252
}
5353
}

logging/src/DeleteSinkCommand.php

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
/**
3+
* Copyright 2016 Google Inc. All Rights Reserved.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
namespace Google\Cloud\Samples\Logging;
19+
20+
// [START delete_sink_use]
21+
use Google\Cloud\Logging\LoggingClient;
22+
// [END delete_sink_use]
23+
use Symfony\Component\Console\Input\InputOption;
24+
use Symfony\Component\Console\Input\InputInterface;
25+
use Symfony\Component\Console\Output\OutputInterface;
26+
27+
/**
28+
* Class DeleteSinkCommand
29+
* @package Google\Cloud\Samples\Logging
30+
*
31+
* This command simply creates a sink.
32+
*/
33+
class DeleteSinkCommand extends BaseCommand
34+
{
35+
protected function configure()
36+
{
37+
$this
38+
->setName('delete-sink')
39+
->setDescription('Deletes a Logging sink')
40+
->addOption(
41+
'sink',
42+
null,
43+
InputOption::VALUE_OPTIONAL,
44+
'The name of the Logging sink',
45+
'my_sink'
46+
);
47+
$this->addCommonOptions();
48+
}
49+
50+
protected function execute(InputInterface $input, OutputInterface $output)
51+
{
52+
$sinkName = $input->getOption('sink');
53+
$projectId = $input->getOption('project');
54+
// [START delete_sink]
55+
$logging = new LoggingClient(['projectId' => $projectId]);
56+
$logging->sink($sinkName)->delete();
57+
// [END delete_sink]
58+
printf("Deleted a sink '%s'." . PHP_EOL, $sinkName);
59+
}
60+
}

logging/src/ListEntriesCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
5252
foreach ($logging->entries($options) as $entry) {
5353
/* @var $entry \Google\Cloud\Logging\Entry */
5454
printf(
55-
"%s : %s\n",
55+
"%s : %s" . PHP_EOL,
5656
$entry->info()['timestamp'],
5757
$entry->info()['textPayload']
5858
);

logging/src/ListSinksCommand.php

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
/**
3+
* Copyright 2016 Google Inc. All Rights Reserved.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
namespace Google\Cloud\Samples\Logging;
19+
20+
// [START list_sinks_use]
21+
use Google\Cloud\Logging\LoggingClient;
22+
// [END list_sinks_use]
23+
use Symfony\Component\Console\Input\InputInterface;
24+
use Symfony\Component\Console\Output\OutputInterface;
25+
26+
/**
27+
* Class ListSinksCommand
28+
* @package Google\Cloud\Samples\Logging
29+
*
30+
* This command simply list sinks
31+
*/
32+
class ListSinksCommand extends BaseCommand
33+
{
34+
protected function configure()
35+
{
36+
$this
37+
->setName('list-sinks')
38+
->setDescription('Lists sinks');
39+
$this->addCommonOptions();
40+
}
41+
42+
protected function execute(InputInterface $input, OutputInterface $output)
43+
{
44+
$projectId = $input->getOption('project');
45+
//$loggerName = $input->getOption('logger');
46+
// [START list_sinks]
47+
$logging = new LoggingClient(['projectId' => $projectId]);
48+
foreach ($logging->sinks() as $sink) {
49+
/* @var $sink \Google\Cloud\Logging\Sink */
50+
foreach ($sink->info() as $key => $value) {
51+
print "$key:$value\n";
52+
}
53+
print PHP_EOL;
54+
}
55+
// [END list_sinks]
56+
}
57+
}

logging/src/WriteCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,6 @@ protected function execute(InputInterface $input, OutputInterface $output)
6262
]);
6363
$logger->write($entry);
6464
// [END write_log]
65-
printf("Wrote a log to a logger '%s'.\n", $loggerName);
65+
printf("Wrote a log to a logger '%s'." . PHP_EOL, $loggerName);
6666
}
6767
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
/**
3+
* Copyright 2016 Google Inc. All Rights Reserved.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
namespace Google\Cloud\Samples\Logging\Tests;
19+
20+
use Google\Cloud\Samples\Logging\CreateSinkCommand;
21+
use Google\Cloud\Samples\Logging\DeleteSinkCommand;
22+
use Symfony\Component\Console\Application;
23+
use Symfony\Component\Console\Tester\CommandTester;
24+
25+
/**
26+
* Functional tests for ListSinkCommand.
27+
*/
28+
class CreateSinkCommandTest extends \PHPUnit_Framework_TestCase
29+
{
30+
/* @var $hasCredentials boolean */
31+
protected static $hasCredentials;
32+
/* @var $sinkName string */
33+
protected static $sinkName;
34+
/* @var $projectId mixed|string */
35+
private $projectId;
36+
37+
public static function setUpBeforeClass()
38+
{
39+
$path = getenv('GOOGLE_APPLICATION_CREDENTIALS');
40+
self::$hasCredentials = $path && file_exists($path) &&
41+
filesize($path) > 0;
42+
self::$sinkName = sprintf("sink-%s", uniqid());
43+
}
44+
45+
public function setUp()
46+
{
47+
if (!self::$hasCredentials) {
48+
$this->markTestSkipped('No application credentials were found.');
49+
}
50+
51+
if (!$this->projectId = getenv('GOOGLE_PROJECT_ID')) {
52+
$this->markTestSkipped('No project ID');
53+
}
54+
}
55+
56+
public function tearDown()
57+
{
58+
// Clean up the sink after the test
59+
$application = new Application();
60+
$application->add(new DeleteSinkCommand());
61+
$commandTester = new CommandTester($application->get('delete-sink'));
62+
$commandTester->execute(
63+
[
64+
'--project' => $this->projectId,
65+
'--sink' => self::$sinkName,
66+
],
67+
['interactive' => false]
68+
);
69+
}
70+
71+
public function testCreateSink()
72+
{
73+
if (!$bucket = getenv('GOOGLE_BUCKET_NAME')) {
74+
$this->markTestSkipped('No SINK_BUCKET envvar');
75+
}
76+
$application = new Application();
77+
$application->add(new CreateSinkCommand());
78+
$commandTester = new CommandTester($application->get('create-sink'));
79+
$loggerName = 'my_test_logger';
80+
$commandTester->execute(
81+
[
82+
'--project' => $this->projectId,
83+
'--logger' => $loggerName,
84+
'--bucket' => $bucket,
85+
'--sink' => self::$sinkName,
86+
],
87+
['interactive' => false]
88+
);
89+
$this->expectOutputRegex(
90+
sprintf("/Created a sink '%s'./", self::$sinkName)
91+
);
92+
}
93+
}

0 commit comments

Comments
 (0)