severb / graypy

Python logging handler for Graylog that sends messages in GELF (Graylog Extended Log Format).
https://www.graylog.org/
BSD 3-Clause "New" or "Revised" License
258 stars 90 forks source link

Support custom JSON serializer #111

Closed higherorderfunctor closed 5 years ago

higherorderfunctor commented 5 years ago

Running into an issue with certain objects not being JSON serializable using the GELFRabbitHandler and causing a crash.

Would it be possible to allow for a custom handler or handle the case of unserializable objects?

I have the following patch I use, but it is dependent on django for string references to the serializer from a dictConfig. I see BaseGELFHandler._pack_gelf_dict has the default option set that is not present in GELFRabbitHandler.makePickle. That might at least resolve the crash condition.

from django.utils.module_loading import import_string

class GELFRabbitHandler(BaseGELFHandler, SocketHandler):
    def __init__(self, url, exchange='logging.gelf', exchange_type='fanout',
                      virtual_host='/', routing_key='', serializer_class=None, **kwargs):
        ...
        self.serializer = import_string(serializer_class)

    def makePickle(self, record):
        message_dict = self._make_gelf_dict(record)
        return json.dumps(message_dict, cls=self.serializer)
nklapste commented 5 years ago

I would recommend subclassing GELFRabbitHandler and overriding makePickle method to contain your extended serialization logic.

For example:


class CustomGELFRabbitHandler(GELFRabbitHandler):
    def makePickle(self, record):
        message_dict = self._make_gelf_dict(record)
        # your custom serialization logic
        return json.dumps(message_dict) # you could also add the json.dumps `default` parameter serializer here as well

Sub-classing and method overriding should be the proper method to extending a classes behavior, not parameter passing.

Let me know if this fails to meet your needs.

higherorderfunctor commented 5 years ago

This works for me. Thank you. Closing out.