Django - Logging - ¿Cómo obtener el nombre de clase al ejecutar la función Obtener dentro de ella?

Así que intenté crear un registro para mi código:

views.py

class name_of_API(generics.GenericAPIView):
    @my_logging
    @swagger_auto_schema
    def get(self, request):
        **running something
        return ...

my_logging.py

def func_detail(func):
    @wraps(func)
    def func_wrapper(request, *args, **kwargs):
        ex = None 
        try: 
            
            response = func(request, *args, **kwargs)
            log = logging.getLogger('main')
            log.info(str(func.__class__.__name__)+ ' Called success')
            print(func.__class__.__name__)
            return response
        except:
            log = logging.getLogger('internal')
            ex = Exception
            ex_type, ex_value, ex_traceback = sys.exc_info()
            log.debug(ex_type(ex_value).with_traceback(ex_traceback))
            raise  ex_type(ex_value).with_traceback(ex_traceback)
    return func_wrapper  

formato en settings.py

'format': '%(asctime)s.%(msecs)03d|%(levelname)s|%(process)d:%(thread)d|%(filename)s:%(lineno)d|%(module)s.%(funcName)s|%(message)s'

info.log:

2020-12-21 10:30:04.845 vidas infligidasInfórmese de éxito

El problema aquí: Esta fila abajo

func.__class__.__name__  

Regreso function en lugar de name_of_API

Pregunta hecha hace 3 años, 4 meses, 26 días - Por binarybard1cc8


2 Respuestas:

  • El problema que estás experimentando es que estás intentando obtener el nombre de la clase a la que pertenece la función decorada, pero en realidad estás obteniendo el nombre de la clase a la que pertenece la función wrapper que estás creando en tu decorador my_logging.

    Para obtener el nombre de la clase a la que pertenece la función original que estás decorando, puedes acceder al atributo __qualname__ de la función en lugar de __class__.__name__.

    Aquí te muestro cómo puedes modificar tu decorador my_logging.py para obtener el nombre de la clase en la función get dentro de tu vista name_of_API:

    python
    from functools import wraps
    
    def my_logging(func):
        @wraps(func)
        def func_wrapper(self, request, args, kwargs):
            ex = None 
            try: 
                response = func(self, request, args, **kwargs)
                log = logging.getLogger('main')
                log.info(f'{func.__qualname__} Called success')
                return response
            except:
                log = logging.getLogger('internal')
                ex = Exception
                ex_type, ex_value, ex_traceback = sys.exc_info()
                log.debug(ex_type(ex_value).with_traceback(ex_traceback))
                raise ex_type(ex_value).with_traceback(ex_traceback)
        return func_wrapper  
    

    Con este cambio, ahora deberías ser capaz de obtener el nombre de la función "get" dentro de la clase name_of_API en lugar de obtener el nombre de la función wrapper generada por el decorador.

    Respondida el Dec 22, 2020 a las 03:46 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • El problema es que func es una función decorada, no la clase que define el método get. Para obtener el nombre de la clase, debes acceder a la clase padre de func. Aquí tienes el código actualizado:

    python
    def func_detail(func):
        @wraps(func)
        def func_wrapper(request, args, kwargs):
            ex = None 
            try: 
    
                response = func(request, args, **kwargs)
                log = logging.getLogger('main')
                log.info(str(func.__class__.__base__.__name__)+ ' Called success')
                print(func.__class__.__base__.__name__)
                return response
            except:
                log = logging.getLogger('internal')
                ex = Exception
                ex_type, ex_value, ex_traceback = sys.exc_info()
                log.debug(ex_type(ex_value).with_traceback(ex_traceback))
                raise  ex_type(ex_value).with_traceback(ex_traceback)
        return func_wrapper  
    

    Al acceder a func.__class__.__base__.__name__, estás obteniendo el nombre de la clase que define el método get.

    Respondida el Dec 22, 2020 a las 04:01 - por Gemini

    Votos positivos: 0 | Votos negativos: 0