Skip to content
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

Is it possible to "decorate" jsonPayload? #24

Open
jdart opened this issue Jan 15, 2021 · 6 comments
Open

Is it possible to "decorate" jsonPayload? #24

jdart opened this issue Jan 15, 2021 · 6 comments

Comments

@jdart
Copy link

jdart commented Jan 15, 2021

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!

@DiederikvandenB
Copy link
Contributor

DiederikvandenB commented Jan 15, 2021

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.

@jdart
Copy link
Author

jdart commented Jan 15, 2021

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.

@DiederikvandenB
Copy link
Contributor

DiederikvandenB commented Jan 16, 2021

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?

@smoopins
Copy link

smoopins commented May 21, 2021

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).

@smoopins
Copy link

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...

  1. Register the middleware in the $routeMiddleware array inside of App\Http\Kernel.php.
  2. 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.

@smoopins
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants