Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 29 additions & 26 deletions Logging/src/Connection/Gapic.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,31 +63,32 @@ class Gapic
*/
public function __construct(private array $config = [])
{
$this->serializer = new Serializer([
'timestamp' => function ($v) {
return $this->formatTimestampFromApi($v);
},
'severity' => function ($v) {
return Logger::getLogLevelMap()[$v];
},
'json_payload' => function ($v) {
return $this->unpackStructFromApi($v);
}
], [], [
'json_payload' => function ($v) {
return $this->formatStructForApi($v);
},
'severity' => function ($v) {
return array_flip(Logger::getLogLevelMap())[strtoupper($v)];
}
], [
'google.protobuf.Duration' => function ($v) {
return $this->formatDurationForApi($v);
},
'google.protobuf.Timestamp' => function ($v) {
return $this->formatTimestampForApi($v);
}
]);
$this->serializer = new Serializer(
fieldTransformers: [
'timestamp' => function ($v) {
return $this->formatTimestampFromApi($v);
},
'severity' => function ($v) {
return Logger::getLogLevelMap()[$v];
},
'json_payload' => function ($v) {
return $this->unpackStructFromApi($v);
}
],
decodeFieldTransformers: [
'json_payload' => function ($v) {
return $this->formatStructForApi($v);
},
],
decodeMessageTypeTransformers: [
'google.protobuf.Duration' => function ($v) {
return $this->formatDurationForApi($v);
},
'google.protobuf.Timestamp' => function ($v) {
return $this->formatTimestampForApi($v);
}
]
);
$this->optionsValidator = new OptionsValidator($this->serializer);
}

Expand Down Expand Up @@ -186,11 +187,13 @@ public function getSink(array $args = [])
{
/**
* @var GetSinkRequest $getSinkRequest
* @var LogSink $_logSink
* @var array $callOptions
*/
[$getSinkRequest, $callOptions] = $this->validateOptions(
[$getSinkRequest, $_sink, $callOptions] = $this->validateOptions(
$args,
new GetSinkRequest(),
new LogSink(), // unused, for backwards compatibility
CallOptions::class
);
return $this->handleResponse(
Expand Down
15 changes: 10 additions & 5 deletions Logging/src/PsrLogger.php
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ public function debug(Stringable|string $message, array $context = []): void
*/
public function log($level, Stringable|string $message, array $context = []): void
{
$this->validateLogLevel($level);
$level = $this->validateLogLevel($level);
$options = [];

if (isset($context['exception'])
Expand Down Expand Up @@ -520,16 +520,21 @@ protected function getCallback()
* Validates whether or not the provided log level exists.
*
* @param string|int $level The severity of the log entry.
* @return bool
* @return int
* @throws \InvalidArgumentException
*/
private function validateLogLevel($level)
private function validateLogLevel($level): int
{
$map = Logger::getLogLevelMap();
$level = (string) $level;

if (isset($map[$level]) || isset(array_flip($map)[strtoupper($level)])) {
return true;
if (isset($map[$level])) {
return $level;
}

$levelFromString = array_flip($map)[strtoupper($level)] ?? null;
if (!is_null($levelFromString)) {
return $levelFromString;
}

throw new InvalidArgumentException("Severity level '$level' is not defined.");
Expand Down
43 changes: 41 additions & 2 deletions Logging/tests/Unit/Connection/GapicTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@

namespace Google\Cloud\Logging\Tests\Unit\Connection;

use Google\ApiCore\GPBType;
use Google\ApiCore\Page;
use Google\ApiCore\PagedListResponse;
use Google\Cloud\Logging\Connection\Grpc;
use Google\Cloud\Core\Testing\GrpcTestTrait;
use Google\Cloud\Core\GrpcRequestWrapper;
use Google\ApiCore\Serializer;
use Google\Cloud\Logging\Connection\Gapic;
use Google\Cloud\Logging\Logger;
use Google\Cloud\Logging\Type\LogSeverity;
use Google\Cloud\Logging\V2\Client\ConfigServiceV2Client;
use Google\Cloud\Logging\V2\Client\LoggingServiceV2Client;
use Google\Cloud\Logging\V2\Client\MetricsServiceV2Client;
Expand All @@ -45,8 +48,11 @@
use Google\Cloud\Logging\V2\UpdateSinkRequest;
use Google\Cloud\Logging\V2\WriteLogEntriesRequest;
use Google\Cloud\Logging\V2\WriteLogEntriesResponse;
use Google\Protobuf\Internal\MapField;
use Google\Protobuf\Internal\Message;
use Google\Protobuf\RepeatedField;
use Google\Protobuf\Struct;
use Google\Protobuf\Timestamp;
use Google\Protobuf\Value;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
Expand Down Expand Up @@ -167,7 +173,7 @@ public function methodProvider()
'latency' => '1.0s'
],
'timestamp' => date('Y-m-d H:i:s', 100),
'severity' => 'DEBUG',
'severity' => Logger::DEBUG,
]
]
],
Expand Down Expand Up @@ -261,4 +267,37 @@ public function methodProvider()
]
];
}

public function testSerializedEntry()
{
$map = new MapField(GPBType::STRING, GPBType::MESSAGE, Value::class);
$map['message'] = new Value(['string_value' => 'aPayload']);

$entry = new LogEntry([
'severity' => LogSeverity::DEBUG,
'timestamp' => new Timestamp(['seconds' => 100]),
'json_payload' => new Struct(['fields' => $map]),
]);

$page = $this->prophesize(Page::class);
$page->getResponseObject()->willReturn(new ListLogEntriesResponse(['entries' => [$entry]]));
$pagedListResponse = $this->prophesize(PagedListResponse::class);
$pagedListResponse->getPage()
->willReturn($page->reveal());

$this->loggingGapicClient->listLogEntries(
new ListLogEntriesRequest(['filter' => 'logName=foo']),
Argument::type('array')
)
->shouldBeCalledOnce()
->willReturn($pagedListResponse->reveal());

$connection = new Gapic(['loggingGapicClient' => $this->loggingGapicClient->reveal()]);

$entries = $connection->listLogEntries(['filter' => 'logName=foo']);
$info = $entries['entries'][0];
$this->assertEquals('DEBUG', $info['severity']);
$this->assertEquals(date('Y-m-d\TH:i:s.u\Z', 100), $info['timestamp']);
$this->assertEquals(['message' => 'aPayload'], $info['jsonPayload']);
}
}
70 changes: 57 additions & 13 deletions Logging/tests/Unit/PsrLoggerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,21 @@

namespace Google\Cloud\Logging\Tests\Unit;

use Google\Api\MonitoredResource;
use Google\Cloud\Core\Batch\OpisClosureSerializerV4;
use Google\Cloud\Core\Report\EmptyMetadataProvider;
use Google\Cloud\Logging\Logger;
use Google\Cloud\Logging\PsrLogger;
use Google\Cloud\Logging\Connection\Gapic;
use Google\Cloud\Logging\V2\Client\LoggingServiceV2Client;
use Google\Cloud\Logging\V2\LogEntry;
use Google\Cloud\Logging\V2\WriteLogEntriesRequest;
use Google\Cloud\Logging\V2\WriteLogEntriesResponse;
use Google\Protobuf\Internal\GPBType;
use Google\Protobuf\Internal\MapField;
use Google\Protobuf\Struct;
use Google\Protobuf\Timestamp;
use Google\Protobuf\Value;
use PHPUnit\Framework\TestCase;
use Psr\Log\InvalidArgumentException;
use Prophecy\PhpUnit\ProphecyTrait;
Expand Down Expand Up @@ -49,7 +59,7 @@ public function setUp(): void

public function getPsrLogger($connection, ?array $resource = null, ?array $labels = null, $messageKey = 'message')
{
$logger = new Logger($connection->reveal(), $this->logName, $this->projectId, $resource, $labels);
$logger = new Logger($connection, $this->logName, $this->projectId, $resource, $labels);
return new PsrLogger($logger, $messageKey, ['metadataProvider' => new EmptyMetadataProvider()]);
}

Expand All @@ -71,7 +81,7 @@ public function testWritesEntryWithDefinedLevels($level)
])
->willReturn([])
->shouldBeCalledTimes(1);
$psrLogger = $this->getPsrLogger($this->connection);
$psrLogger = $this->getPsrLogger($this->connection->reveal());

$this->assertNull(
$psrLogger->$level($this->textPayload, [
Expand All @@ -80,6 +90,40 @@ public function testWritesEntryWithDefinedLevels($level)
);
}

/**
* @dataProvider levelProvider
*/
public function testWritesEntryRequestWithDefinedLevels($level)
{
$map = new MapField(GPBType::STRING, GPBType::MESSAGE, Value::class);
$map['message'] = new Value(['string_value' => $this->textPayload]);
$entry = new LogEntry([
'severity' => array_flip(Logger::getLogLevelMap())[$level],
'log_name' => $this->formattedName,
'resource' => new MonitoredResource($this->resource),
'timestamp' => new Timestamp(['seconds' => 100]),
'json_payload' => new Struct(['fields' => $map])
]);
$request = new WriteLogEntriesRequest(['entries' => [$entry]]);

$loggingClient = $this->prophesize(LoggingServiceV2Client::class);
$loggingClient->writeLogEntries($request, [])
->shouldBeCalledOnce()
->willReturn(new WriteLogEntriesResponse());

$connection = new Gapic([
'loggingGapicClient' => $loggingClient->reveal()
]);

$psrLogger = $this->getPsrLogger($connection);

$this->assertNull(
$psrLogger->$level($this->textPayload, [
'stackdriverOptions' => ['timestamp' => date('Y-m-d H:i:s', 100)]
])
);
}

public function levelProvider()
{
return [
Expand All @@ -99,7 +143,7 @@ public function testWritesEntry()
$this->connection->writeLogEntries([
'entries' => [
[
'severity' => $this->severity,
'severity' => array_flip(Logger::getLogLevelMap())[$this->severity],
'jsonPayload' => ['message' => $this->textPayload],
'logName' => $this->formattedName,
'resource' => $this->resource,
Expand All @@ -109,7 +153,7 @@ public function testWritesEntry()
])
->willReturn([])
->shouldBeCalledTimes(1);
$psrLogger = $this->getPsrLogger($this->connection);
$psrLogger = $this->getPsrLogger($this->connection->reveal());

$this->assertNull(
$psrLogger->log($this->severity, $this->textPayload, [
Expand All @@ -125,7 +169,7 @@ public function testPsrLoggerUsesDefaults()
$this->connection->writeLogEntries([
'entries' => [
[
'severity' => $this->severity,
'severity' => array_flip(Logger::getLogLevelMap())[$this->severity],
'jsonPayload' => ['message' => $this->textPayload],
'logName' => $this->formattedName,
'resource' => $resource,
Expand All @@ -136,7 +180,7 @@ public function testPsrLoggerUsesDefaults()
])
->willReturn([])
->shouldBeCalledTimes(1);
$psrLogger = $this->getPsrLogger($this->connection, $resource, $labels);
$psrLogger = $this->getPsrLogger($this->connection->reveal(), $resource, $labels);

$this->assertNull(
$psrLogger->log($this->severity, $this->textPayload, [
Expand All @@ -153,7 +197,7 @@ public function testOverridePsrLoggerDefaults()
$this->connection->writeLogEntries([
'entries' => [
[
'severity' => $this->severity,
'severity' => array_flip(Logger::getLogLevelMap())[$this->severity],
'jsonPayload' => ['message' => $this->textPayload],
'logName' => $this->formattedName,
'resource' => $newResource,
Expand All @@ -164,7 +208,7 @@ public function testOverridePsrLoggerDefaults()
])
->willReturn([])
->shouldBeCalledTimes(1);
$psrLogger = $this->getPsrLogger($this->connection, null, $defaultLabels);
$psrLogger = $this->getPsrLogger($this->connection->reveal(), null, $defaultLabels);

$this->assertNull(
$psrLogger->log($this->severity, $this->textPayload, [
Expand All @@ -181,7 +225,7 @@ public function testLogThrowsExceptionWithInvalidLevel()
{
$this->expectException(InvalidArgumentException::class);

$psrLogger = $this->getPsrLogger($this->connection);
$psrLogger = $this->getPsrLogger($this->connection->reveal());
$psrLogger->log('INVALID-LEVEL', $this->textPayload);
}

Expand All @@ -205,7 +249,7 @@ public function testUsesCustomMessageKey()
$this->connection->writeLogEntries([
'entries' => [
[
'severity' => $this->severity,
'severity' => array_flip(Logger::getLogLevelMap())[$this->severity],
'jsonPayload' => [$customKey => $this->textPayload],
'logName' => $this->formattedName,
'resource' => $this->resource,
Expand All @@ -215,7 +259,7 @@ public function testUsesCustomMessageKey()
])
->willReturn([])
->shouldBeCalledTimes(1);
$psrLogger = $this->getPsrLogger($this->connection, null, null, $customKey);
$psrLogger = $this->getPsrLogger($this->connection->reveal(), null, null, $customKey);
$psrLogger->log($this->severity, $this->textPayload, [
'stackdriverOptions' => ['timestamp' => null]
]);
Expand Down Expand Up @@ -278,7 +322,7 @@ private function expectLogWithExceptionInContext($throwable)
$this->connection->writeLogEntries([
'entries' => [
[
'severity' => $this->severity,
'severity' => array_flip(Logger::getLogLevelMap())[$this->severity],
'jsonPayload' => [
'message' => $this->textPayload,
'exception' => (string) $throwable
Expand All @@ -291,7 +335,7 @@ private function expectLogWithExceptionInContext($throwable)
])
->willReturn([])
->shouldBeCalledTimes(1);
$psrLogger = $this->getPsrLogger($this->connection);
$psrLogger = $this->getPsrLogger($this->connection->reveal());
$psrLogger->log($this->severity, $this->textPayload, [
'exception' => $throwable,
'stackdriverOptions' => ['timestamp' => null]
Expand Down
Loading
Loading