laravel-stackdriver
laravel-stackdriver copied to clipboard
Is it possible to "decorate" jsonPayload?
I'd like to add some data to all log messages, like a request id for tracing purposed for example. Any idea how I might accomplish that? I tried adding a processor to all log handlers but it seems like that data doesn't get passed to the app['log']->listen. Thanks!
If this feature is supported by the GCP Logging API then we should be able to implement this here. Otherwise, no, since this is just a wrapper for their APIs.
Or I might be misinterpreting your question.
It's not really a gcp feature, I used the request id as an example, but it could really be anything like memory usage, or some detail about the user. In short I'm looking to add extra data to the context of all log messages.
I think this is outside the scope of this package. We simply listen for calls to the Laravel log method:
$this->app['log']->listen(function () {
$args = Arr::first(func_get_args());
$this->app['Stackdriver\Logger']->log(
$args->level,
$args->message,
$args->context
);
});
So I guess it is best to find a Laravel compatible solution. So you will have to find a way to add a default context. Have you checked this?
If I'm following, I'm trying to do something very similar... I have a bunch of different queues (one per concurrently-running job) and I'm looking to isolate which job created which task. I came here to see if there was a similar question already, and well here we all are!
GCP does support structured logs, and the labels property of the LogEntry object allows for a user-defined map of key/val pairs. So it sounds exactly like what we're after... except that labels is up a level from jsonPayload. The labels property is a sibling of the jsonPayload and textPayload properties in the LogEntry object. (See here: GCP docs for LogEntry.)
I've just not yet traced things back up the stack to see that laravel-stackdriver is using the LogEntry object... or really how this sausage is made. I'm just starting that research now... but I have hope (which is rare).
It's looking like the easiest way to pull this off is to tweak the config during runtime, since the static method StackdriverExceptionHandler::report that we all had to add to App\Exceptions\Handler.php is pulling the array of labels from a the stackdriver config file. In my app I believe I'm going to be able to pull that off with some simple middleware.
Here's a gist for the middleware that I wrote to accomplish this.
Then, standard Laravel (Laravel7 for me) stuff to get it to be called...
- Register the middleware in the
$routeMiddlewarearray inside of App\Http\Kernel.php. - Decorate the appropriate routes with the call to the middleware... in my case a handful of route groups.
I ought to be in-testing this method tomorrow... and this is my first Laravel project (hell, my first MVC project) so the usual "zero-warranties" disclaimers apply.
Hey all. I've abandoned this original idea.
Last night I finally got back to the original idea, and have tried placing the "labels" associative array in a few different places , yet none worked. So I RTFM'd a bit more, and found (go easy, I'm new to Laravel) that the second parameter to all of the Log::<level> calls (which is named "context") accepts an associative array which behaves exactly as we were describing above.
What happens is that when it's consumed in Stackdriver, each of the keys end up being properties inside of the jsonPayload element, and the value of the property is (unsurprisingly) the value you gave that same property in the associative array.
So, here's what one log entry in my system looks like (where I added the "Process-Job" property):
{
insertId: "rAnd0mN01z3"
jsonPayload: {
Process-Job: "53"
message: "Publishing vendor 75 to store 151 (retailer 3183100)"
}
resource: {
type: "global"
labels: {
project_id: "names-redacted-to-protect-the-innocent"
}
}
timestamp: "2021-06-22T04:46:00.742580Z"
severity: "DEBUG"
logName: "projects/names-redacted-to-protect-the-innocent"
receiveTimestamp: "2021-06-22T04:46:15.172304700Z"
}
HTH