Elixir aprovecha al máximo la infraestructura de registro de Erlang para crear registros. A partir de la versión 1.10 , que se lanzará próximamente, tenemos disponibles nuevas funciones de registro de usuarios que aparecieron en Erlang / OTP 21+ .
Si bien OTP proporciona toda la infraestructura para entregar eventos de diario (eventos) a los suscriptores, la aplicación debe implementar el registro en sí mismo, si se entiende que almacena y / o muestra eventos de diario. Para este propósito, Logger.Backend
la abstracción correspondiente de Logger.Backend
.
Aquí hay un extracto de la documentación oficial:
Logger
registrador admite varios backends donde se escriben los mensajes de registro.
Los backends disponibles por defecto están limitados a uno:
:console
- registra mensajes en la consola (habilitado por defecto)
Cualquier desarrollador puede crear su propia cosecha como un backend para Logger
. Dado que Logger
es un administrador de eventos que implementa el comportamiento Erlang :gen_event
, escribir un nuevo backend es solo cuestión de crear su propio controlador de eventos, como se describe en la documentación de :gen_event
.
Los backends usados se cargan a través de la sección :backends
en el archivo de configuración, que debe procesarse antes de iniciar la aplicación :logger
.
El enfoque más común que ha dado origen a muchas del mismo tipo de bibliotecas hex.pm
es crear un Logger.Backend
que comprende y escupe la consola JSON, y atornilla algún tipo de entrega de registro donde lo necesita (generalmente es algún tipo de LaaS
) . Por lo tanto, todos los registros generalmente terminan en una base de datos NoSQL , como Elastic , o algo similar.
No nos convertimos en originales, y también almacenamos nuestros registros en Elastic , pero ahora los registros por sí solos no son suficientes: los niños modernos de moda se aferran a todos los mensajes en los registros: métricas para todo sobre todo. El estándar de facto para trabajar con métricas en aplicaciones OTP ha sido recientemente la biblioteca de Telemetría , un proyecto de código abierto relativamente reciente destinado a unificar y estandarizar cómo se instrumentan y controlan las bibliotecas y aplicaciones BEAM.
El enfoque adoptado por Telemetry es simple hasta el :telemetry.execute/2
horror: llamamos :telemetry.execute/2
siempre que sea necesario medir algo en la aplicación, y la biblioteca responde con la devolución de llamada registrada al inicio de la aplicación. Además, es posible adjuntar Telemetry.Poller
y realizar solicitudes métricas periódicamente. El ejemplo en el artículo al que le di el enlace anterior sugiere llamar a Logger.log/3
desde el controlador interno de eventos de telemetría .
Gelato
Odio el código repetitivo que tienes que arrastrar copiar y pegar de un proyecto a otro, de un archivo a otro. Quiero que todo lo que pueda hacer el compilador, el planificador y los trabajadores se haga para que ni siquiera lo piense. Para hacer esto, a menudo empaco el código repetitivo en pequeñas bibliotecas que ocultan toda la repetitiva necesaria debajo del capó y proporcionan interfaces limpias para realizar las acciones necesarias para nuestra aplicación. Solo me gustaría algo que pueda llamarse como report("message", payload)
para crear un registro, agregar datos de telemetría y enviar este registro a nuestro repositorio elástico.
Resulta que esto no es tan difícil de hacer.
Decidimos usar las llamadas estándar de Logger
como una interfaz, de modo que simplemente cambiando las configuraciones pudiéramos introducir la funcionalidad deseada en los proyectos existentes. Simplemente agregue un nuevo Logger.Backend
a un proyecto existente:
config :logger, backends: [Our.Fancy.Logger.Backend]
- y voilà - los registros con telemetría ahora se envían a un búnker elástico.
Y así surgió la biblioteca de Gelato
. Sé que a los desarrolladores realmente duros y reflexivos les gusta que las bibliotecas se llamen un poco menos esotéricamente, pero no soy un desarrollador real. Es decir, tienes que llegar a un acuerdo. Aunque, gelato (en español - helado, por cierto) está incluso un poco en sintonía con la elasticidad.
La biblioteca está muy centrada en cómo veo el mundo correcto, y en la cola y la melena utiliza el enfoque de "convención por encima de la configuración". Empaqueta todo lo que pueda necesitar en un JSON y lo envía a un servidor elástico preconfigurado con una simple solicitud HTTP. También adjunta todos los metadatos que puede alcanzar, como las métricas obtenidas mediante Process.info/1
, etc.
Para comenzar a usar esta biblioteca en un proyecto, debe agregar lo siguiente a su archivo config/releases.exs
:
config :gelato, uri: "http://127.0.0.1:9200",
Después de eso, cualquier llamada de Logger.log/3
como la siguiente se transmitirá por telemetry
y se enviará al servidor elástico configurado.
Logger.info "foo", question: "why?", answer: 42, now: System.monotonic_time(:microsecond)
La biblioteca también presenta la macro Gelato.bench/4
, que toma un bloque y realiza dos llamadas a Logger.log/3
: una antes de que se ejecute el bloque y la otra inmediatamente después, por tipo de aspectos en Java.
Gelato
insiste discretamente en una mejor organización de las interfaces dentro de los proyectos utilizando la macro Gelato.defdelegatelog/2
, la composición simple Gelato.bench/4
y Kernel.defdelegate/2
. Con esta macro, puede extraer todas las interfaces del proyecto en un conjunto limitado de módulos de nivel superior y hacer que estas llamadas se registren con telemetría lista para usar.
Envío.Log
Otra implementación de Logger.Backend
que nació en nuestro rincón de la pasión tecnológica es Envío.Log
. Utiliza la biblioteca de Envío
para enviar mensajes a un canal dedicado de Slack . Este registrador tiene su propia configuración log_level
, cuyo valor generalmente se establece en :warn
o :error
, para evitar que el canal Slack sea spam, y todas las llamadas a niveles inferiores a los configurados se eliminarán de BEAM durante la compilación.
Una configuración típica se vería así:
config :envio, :log, level: :warn,
Después de la configuración, todas las llamadas al Logger.{warn,error}/2
se enviarán al canal Slack correspondiente. Es muy conveniente para monitorear procesos de trabajo en producción en tiempo real.
Que tenga un buen registro!