Skip to content

Commit

Permalink
GoogleCloudLoggingFormatter trace context
Browse files Browse the repository at this point in the history
  • Loading branch information
iamacarpet committed Apr 3, 2024
1 parent 479c936 commit a0b5b3c
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 0 deletions.
2 changes: 2 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"aws/aws-sdk-php": "^3.0",
"doctrine/couchdb": "~1.0@dev",
"elasticsearch/elasticsearch": "^7 || ^8",
"friendsofphp/php-cs-fixer": "^3.52",
"graylog2/gelf-php": "^1.4.2 || ^2.0",
"guzzlehttp/guzzle": "^7.4.5",
"guzzlehttp/psr7": "^2.2",
Expand All @@ -45,6 +46,7 @@
"ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)",
"mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)",
"aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
"google/cloud": "Allow inclusion of additional contextual information on GCP",
"rollbar/rollbar": "Allow sending log messages to Rollbar",
"ext-mbstring": "Allow to work properly with unicode symbols",
"ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)",
Expand Down
44 changes: 44 additions & 0 deletions src/Monolog/Formatter/GoogleCloudLoggingFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
*/
final class GoogleCloudLoggingFormatter extends JsonFormatter
{
const CONTEXT_HEADER_FORMAT = '/([0-9a-fA-F]{32})(?:\/(\d+))?(?:;o=(\d+))?/';

private static ?string $traceID = null;

protected function normalizeRecord(LogRecord $record): array
{
$normalized = parent::normalizeRecord($record);
Expand All @@ -32,9 +36,49 @@ protected function normalizeRecord(LogRecord $record): array
$normalized['severity'] = $normalized['level_name'];
$normalized['time'] = $record->datetime->format(DateTimeInterface::RFC3339_EXTENDED);

// Tag with Trace ID for request attribution
$normalized['logging.googleapis.com/trace'] = $this->getTraceID();

// Remove keys that are not used by GCP
unset($normalized['level'], $normalized['level_name'], $normalized['datetime']);

return $normalized;
}

private function getTraceID(): ?string
{
if (empty($this->traceID) && !empty($_SERVER['HTTP_X_CLOUD_TRACE_CONTEXT'])) {
$matched = preg_match(
self::CONTEXT_HEADER_FORMAT,
$_SERVER['HTTP_X_CLOUD_TRACE_CONTEXT'] ?? '',
$matches,
);

if (!$matched) {
return null;
}

$projectID = $this->getProjectID();
if (empty($projectID)) {
return null;
}

$this->traceID = 'projects/'.$projectID.'/traces/'.strtolower($matches[1]);
}

return $this->traceID;
}

private function getProjectID(): ?string
{
if (isset($_SERVER['GOOGLE_CLOUD_PROJECT'])) {
return $_SERVER['GOOGLE_CLOUD_PROJECT'];
}

if (class_exists('\Google\Cloud\Core\Compute\Metadata')) {
return (new \Google\Cloud\Core\Compute\Metadata())->getProjectId();
}

return null;
}
}

0 comments on commit a0b5b3c

Please sign in to comment.