-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Trace Context for GoogleCloudLoggingFormatter #1877
base: main
Are you sure you want to change the base?
Conversation
8134a04
to
5efa13b
Compare
Not sure if we need this support directly at monolog level, but I've been able to use https://github.com/googleapis/google-cloud-php-logging, which is a PSR logger which is supported as a "Handler" by monolog, e.g. in this laravel snippet:
And this already includes the trace id to each log entry: https://github.com/googleapis/google-cloud-php-core/blob/686ffd0bb1328cd2ee963c4444e2ab4b111ba3ba/src/Report/GAEMetadataProvider.php#L39 This works out of the box for app engine. For cloud run you might want to look at So this could be an alternative, if monolog prefers to stay agnostic towards formatting and let other modules define their own format to be used by monolog. |
Thanks @sonnysasaka , This came about from a conversation with @sl0wik who said his Firevel project was using this:
in the environmental configuration for Laravel on App Engine Standard. This method of logging more closely matches what is desirable in a containerised environment (logging via
Although I was concerned he & his users were missing out on logs being tagged together against the request that generated them, which our developers consistently say is their favourite developer friendly feature of GCP. I believe that Using the Personally, we have our own log formatter as part of our GaeSupportLaravel package, however, adding the required stuff into here (since exists anyway) will hopefully bring this functionality to more people. |
Thanks for providing more context. With that, I think it makes sense for the google cloud formatter to live in monolog repo itself. I don't have a particular concern with the code except one small suggestion inline in the patch. |
} | ||
|
||
if (class_exists('\Google\Cloud\Core\Compute\Metadata')) { | ||
return (new \Google\Cloud\Core\Compute\Metadata())->getProjectId(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also, it looks like the implementation of Google\Cloud\Core\Compute\Metadata::getProjectId()
does not do caching, so maybe it's better to retrieve the project id just once at the constructor of this GoogleCloudLoggingFormatter
as not to incur HTTP round trip every time there is a new log entry to format.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You'll hopefully see further up, we set the static property $this->traceID
and once set, we always return that static value.
The project ID is only retrieved to construct that value the single time it is constructed, so hopefully this is already accounted for.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Caching $this->traceID
may be fine if it's guaranteed that GoogleCloudLoggingFormatter
is always created new for each request. I think this is the case with PHP app with nginx + php-fpm but may not be the case with other kind of deployment (like with Laravel Octane where objects are created just once when the app starts and reused across multiple requests).
I am not familiar enough with monolog + octane to confidently say whether Octane reuses the formatter object across different requests, but to be safe I would not cache the trace id but only the project id.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah it's probably safer not to cache, as retrieving the trace id doesn't seem that expensive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And I would definitely not cache this as a static property. Cache on an instance property then a new instance would at least refetch from a clean state. Static property will definitely cause issues in some envs.
5efa13b
to
a0b5b3c
Compare
a0b5b3c
to
05ae45f
Compare
@@ -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(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this really be set at all if getTraceID returns null?
return $_SERVER['GOOGLE_CLOUD_PROJECT']; | ||
} | ||
|
||
if (class_exists('\Google\Cloud\Core\Compute\Metadata')) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (class_exists('\Google\Cloud\Core\Compute\Metadata')) { | |
if (class_exists('Google\Cloud\Core\Compute\Metadata')) { |
Add Cloud Trace context to log entries formatted with GoogleCloudLoggingFormatter.
This allows log entries to be grouped with the HTTP request that generated them in GCP's Log Explorer:
@sl0wik @sonnysasaka - two big users of PHP on GCP, RFC please.