getsentry / sentry-php

The official PHP SDK for Sentry (sentry.io)
https://sentry.io
MIT License
1.83k stars 451 forks source link

Customize fingerprint for Monolog/PSR logs #1780

Closed francislavoie closed 1 month ago

francislavoie commented 1 month ago

Problem Statement

I have a Monolog/LogInterface logger. I'd like to configure certain logs which aren't getting grouped properly by setting the fingerprint. The current APIs recommend that the code that produces the logs to have a direct dependency on the Sentry SDK by calling \Sentry\withScope();, as per https://docs.sentry.io/platforms/php/usage/sdk-fingerprinting/. I'd rather not depend on Sentry in my code and only have things configured higher level in case Sentry is not active/configured in a given environment.

Solution Brainstorm

I was thinking that Sentry\Monolog\Handler could look at $record['context']['sentry.fingerprint'] (or similar) to grab a per-log fingerprint override, which would be used inside doWrite's withScope, somewhere in here:

https://github.com/getsentry/sentry-php/blob/383514bb4326e1e229d9dff0c97ccfba55289225/src/Monolog/Handler.php#L66

Would that be an acceptable idea? Would sentry.* scoped context fields make sense? Maybe the handler could have a configurable or opt-in fingerprintContextKey (default off, otherwise user-defined key to look in context for a fingerprint override)?

Obviously I could write my own Handler which does this, but I figure this sort of thing would make more sense to be built-in to make it easier to configure per-log options for Monolog users.

stayallive commented 1 month ago

I think using before_send is a great use case for this possibly?

See: https://docs.sentry.io/platforms/php/data-management/sensitive-data/#before-send-before-send-transaction

It might make sense to allow to do this via the Monolog context or something but this gets messy real quick so I'm hesitant to add things there if we don't have to because if you add one thing you are bound to add the rest also and then we have multiple ways of doing the same thing.

francislavoie commented 1 month ago

Hm. So if I'm reading that right, you're suggesting something like this?

            'before_send' => static function (\Sentry\Event $event): ?\Sentry\Event {
                $fingerprintOverride = $event->getExtra()['monolog.context']['fingerprint'] ?? null;
                if (is_array($fingerprintOverride)) {
                    $event->setFingerprint($fingerprintOverride);
                }
                return $event;
            },

I guess that would do the trick. I'll test it out.

stayallive commented 1 month ago

Yes, exactly what I had in mind!

You could even remove the fingerprint from the extra data after that if you want to not have it end up cluttering the event UI.

francislavoie commented 1 month ago

Makes sense. It seems to work, thanks!