npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@nalv/logger

v2.0.0-rc.1

Published

Creación de loggers para guardar información en los distintos formatos disponibles.

Downloads

3

Readme

@nalv/logger

Un logger de uso general. Desarrollado en Typescript y publicado en npmjs.com compilado junto a las definiciones del código (files.d.ts).

npm version

Tabla de contenidos

Uso

/* Javascript */
const nalvLogger = require('@nalv/logger')
//const { Logger, SimpleFormat, JSONFormat, ConsolePlugin, FilePlugin } = require('@nalv/logger')

/*
 * Crea la instancia del logger
 * */
const logger = new nalvLogger.Logger({
  level: 'debug', // Nivel con el que se 
  //levels: [...], // Ocupar los niveles por defecto
  //format: new nalvLogger.SimpleFormat({ datetime: true, console: { colors: false} }), // Para plugins sin "format"
  plugins: [
  new nalvLogger.ConsolePlugin({
    //level: 'debug', // Se hereda
    format: new nalvLogger.SimpleFormat({
      datetime: false,
      console: {
        colors: true
      }
    })
  }),
    new nalvLogger.FilePlugin({
    level: 'warning', // Se cambia el nivel desde donde se inician a guardar los logs en este plugin
      filename: path.join(__dirname, 'logs.txt'),
      format: new nalvLogger.JSONFormat({
        beautify: false
      })
    })
  ]
})
/* Typescript / ES6 (quitar el tipado) */
import { Logger, SimpleFormat, JSONFormat, ConsolePlugin, FilePlugin } from '@nalv/logger'

/*
 * Crea la instancia del logger
 * */
const logger: Logger = new Logger({
  level: 'debug', // Nivel con el que se 
  //levels: [...], // Ocupar los niveles por defecto
  //format: new SimpleFormat({ datetime: true, console: { colors: false} }), // Para plugins sin "format"
  plugins: [
  new ConsolePlugin({
    //level: 'debug', // Se hereda
    format: new SimpleFormat({
      datetime: false,
      console: {
        colors: true
      }
    })
  }),
    new FilePlugin({
    level: 'warning', // Se cambia el nivel desde donde se inician a guardar los logs en este plugin
      filename: path.join(__dirname, 'logs.txt'),
      format: new JSONFormat({
        beautify: false
      })
    })
  ]
})

Logging

En @nalv/logger el logger corresponde a un objeto para contener la instancia que se usará gestionar el logging en la aplicación.

Crear un logger

Para crear una instancia de logger, debes usar:

/* Javascript */
const nalvLogger = require('@nalv/logger')
//const { Logger, SimpleFormat } = require('@nalv/logger')
const logger = new nalvLogger.Logger({
  format: new nalvLogger.SimpleFormat(),
  level: 'debug'
})
/* Typescript / ES6 (quitar el tipado) */
import { Logger, SimpleFormat } from '@nalv/logger'

const logger: Logger = new Logger({
  format: new SimpleFormat(),
  level: 'debug'
})

Donde el objeto new Logger({...}) tiene un formato del tipo:

| Llave (key) | Tipo | Valor inicial | Descripción | |-|-|-|-| | levels | Array<level> | Niveles por defecto | Los niveles de logs que tendrá. | | level | String | 'debug' | Desde que nivel se registrarán los logs. | | format | BaseFormat | new BaseFormat() | Formato que se usará para mostrar los logs. | | plugins | Array<plugin> | [ new ConsolePlugin() ] | Plugins que usará el logger.

Usar un logger

Para usar un logger simplemente se debe llamar al level desde la instancia creada.

// Forma de uso
log(level: string, message: string, data?: object, ...args: any[])
levelName(message: string, data?: any, ...args: any[])
info(message: string, data?: any, ...args: any[])
// Mismo resultado
logger.log('info', 'Registro para los plugins registrados.', { obj: 'info adicional (para plugins y formats)' }, ...args)
logger.levelName('Registro para los plugins registrados.', { obj: 'info adicional (para plugins y formats)' }, ...args)
logger.info('Registro para los plugins registrados.', { obj: 'info adicional (para plugins y formats)' }, ...args)

| Parametro | Valor inicial | Descripción | Función | |-|-|-|-| | level | undefined | Nivel para el que se generará el log. | logger.log | | message | undefined | Mensaje que se enviará al log. | logger.loglogger.levelName | | data? | null | Información adicional que se le enviará al log.Esta información la recibe el plugin y el formater, por lo que la puede ocupar para generar condiciones. | logger.loglogger.levelName | | ...args | [] | Información adicional. Al igual que data esta información la recibirán los plugins y formaters. | logger.loglogger.levelName |

Niveles

Los niveles de log son esas "paredes" que se van "saltando" cuando se necesita llegar mas lejos. Osea, si se tienen 4 paredes (niveles):

  • pared1 (level1)
  • pared2 (level2)
  • pared3 (level3)
  • pared4 (level4)

Al saltar la pared4, también se saltarán las paredes inferiores 1-2-3, pero si se salta la pared2, solo se saltarán 1 y 2 (que son sus inferiores).

Niveles por defecto

Cada vez que se crea una instancia de logger, éste tiene un argumento para establecer los niveles que tendrá. En caso de que no se envíen (como es el valor por defecto) se usarán los que establece el paquete:

levels: [
  { code: 0, name: 'Emergency', alias: 'emergency', extra: { color: 'magenta'} },
  { code: 1, name: 'Alert', alias: 'alert', extra: { color: 'red' } },
  { code: 2, name: 'Critical', alias: 'critical', extra: { color: 'red' } },
  { code: 3, name: 'Error', alias: 'error', extra: { color: 'red' } },
  { code: 4, name: 'Warning', alias: 'warning', extra: { color: 'yellow' } },
  { code: 5, name: 'Notice', alias: 'notice', extra: { color: 'cyan' } },
  { code: 6, name: 'Information', alias: 'info', extra: { color: 'green' } },
  { code: 7, name: 'Debug', alias: 'debug', extra: { color: 'grey' } }
],

Los niveles por defecto para los loggers estan definidos en RFC 5424.

Niveles personalizados

También es posible crear niveles personalizados, para ello se debe seguir el formato:

{ code: 0, name: 'Nombre nivel', alias: 'newlevel', extra: { color: 'magenta'} }

| Llave (key) | Descripción | |-|-| | code | El código que tendrá el nuevo nivel. Si se ejecuta un log con este código, se ejecutarán los plugins que tengan igual o menos código. | | name | Nombre del código. | | alias | Alias del código. Además, es el nombre de la función que se usará con el logger: new Logger().alias. | | extra.color | Color que representará al nivel. Ciertos plugins pueden utilizarlo (como ConsolePlugin).Los colores disponibles se rigen por el paquete colors en npm.

Donde su inserción sería en la creación del logger:

/* Javascript */
const nalvLogger = require('@nalv/logger')
//const { Logger, SimpleFormat } = require('@nalv/logger')
const logger = new nalvLogger.Logger({
  format: new nalvLogger.SimpleFormat(),
  level: 'debug',
  levels: [
    { code: 0, name: 'Emergency', alias: 'emergency', extra: { color: 'magenta'} },
    { code: 1, name: 'Alert', alias: 'alert', extra: { color: 'red' } },
    { code: 2, name: 'Critical', alias: 'critical', extra: { color: 'red' } },
    { code: 3, name: 'Error', alias: 'error', extra: { color: 'red' } },
    { code: 4, name: 'Warning', alias: 'warning', extra: { color: 'yellow' } },
    { code: 5, name: 'Notice', alias: 'notice', extra: { color: 'cyan' } },
    { code: 6, name: 'Information', alias: 'info', extra: { color: 'green' } },
    { code: 7, name: 'Debug', alias: 'debug', extra: { color: 'grey' } }
  ],
})
/* Typescript / ES6 (quitar el tipado) */
import { Logger, SimpleFormat } from '@nalv/logger'

const logger: Logger = new Logger({
  format: new SimpleFormat(),
  level: 'debug',
  levels: [
    { code: 0, name: 'Emergency', alias: 'emergency', extra: { color: 'magenta'} },
    { code: 1, name: 'Alert', alias: 'alert', extra: { color: 'red' } },
    { code: 2, name: 'Critical', alias: 'critical', extra: { color: 'red' } },
    { code: 3, name: 'Error', alias: 'error', extra: { color: 'red' } },
    { code: 4, name: 'Warning', alias: 'warning', extra: { color: 'yellow' } },
    { code: 5, name: 'Notice', alias: 'notice', extra: { color: 'cyan' } },
    { code: 6, name: 'Information', alias: 'info', extra: { color: 'green' } },
    { code: 7, name: 'Debug', alias: 'debug', extra: { color: 'grey' } }
  ],
})

Formatos

Los "formats" o formatos son los objetos e instancias de éstos que son los encargados de darle partes al logging. Es posible usar los formats que vienen incluidos en el paquete, además también se pueden crear formats personalizados en caso de que los disponibles no cumplan con los requerimientos del proyecto.

La construcción de la instancia para un formato se establecería así (ejemplo en base al formato JSONFormat):

/* Javascript */
const nalvLogger = require('@nalv/logger')
//const { Logger, JSONFormat } = require('@nalv/logger')

// En la creación del logger
const logger = new nalvLogger.Logger({
  format: new nalvLogger.JSONFormat(),
  level: 'debug'
})

// Una vez ya creado el logger, junto a un plugin
logger.addPlugin(
  new nalvLogger.ConsolePlugin({
    format: new nalvLogger.JSONFormat()
  })
)
/* Typescript / ES6 (quitar el tipado) */
import { Logger, JSONFormat, ConsolePlugin } from '@nalv/logger'

const logger: Logger = new Logger({
  format: new JSONFormat(),
  level: 'debug'
})

// Una vez ya creado el logger, junto a un plugin
logger.addPlugin(
  new ConsolePlugin({
    format: new JSONFormat()
  })
)

Formato: JSON

Este formato transforma a JSON la información recibida por el logger.

// Agregar el format
logger.addPlugin(new ConsolePlugin({ format: new JSONFormat({ beautify: false }) }))
// Log
logger.notice('Actualizando la información del sistema.')
// Resultado
{"datetime":"2018/02/05 06:32:53","level":"notice","message":"Actualizando la información del sistema."}
// Agregar el format
logger.addPlugin(new ConsolePlugin({ format: new JSONFormat({ beautify: true }) }))
// Log
logger.notice('Actualizando la información del sistema.')
// Resultado
{
  "datetime": "2018/02/05 06:48:06",
  "level": "notice",
  "message": "Los paquetes fueron actualizados correctamente!"
}

Opciones de construcción de new JSONFormat({ }): | Llave (key) | Valor inicial | Descripción | |-|-|-| | beautify | false | Transformar a un formato JSON ordenado. |

Formato: Simple

Mostrar el log de una manera simple y entendible.

// Agregar el format
logger.addPlugin(new ConsolePlugin({ format: new SimpleFormat({ datetime: false }) }))
// Log
logger.notice('Actualizando la información del sistema.')
// Resultado
[  NOTICE   ] Actualizando la información del sistema!
// Agregar el format
logger.addPlugin(new ConsolePlugin({ format: new SimpleFormat({ datetime: true }) }))
// Log
logger.notice('Actualizando la información del sistema.')
// Resultado
[2018/02/05 06:57:10] [  NOTICE   ] Actualizando la información del sistema.

Opciones de construcción de new SimpleFormat({ }): | Llave (key) | Valor inicial | Descripción | |-|-|-| | datetime | true | Mostrar la fecha y hora en que fue enviado el log. | | console.colors | false | Mostrar colores en los mensajes.Si se establece en true pintará el texto según el color correspondiente al nivel. |

Crear formatos personalizados

Si se requiere de un formato con características que no tengan los que trae el paquete, es posible crear sus propios formatos. Esto se hace mediante el objeto BaseFormat.

Ejemplo

Un formato básico (este ejemplo agrega espacios al principio de la cadena enviada en los logs), sería:

/* Javascript */
const nalvLogger = require('@nalv/logger')
//const { BaseFormat, Message } = require('@nalv/logger')

class PersonalFormat extends nalvLogger.BaseFormat {

  options = {}
  
  constructor(options) {
    super()
    this.options.padStart = options.padStart || 16
  }

  format(data) {
    data.message = data.message.padStart(this.options.padStart)
    return data
  }

}

exports.format = PersonalFormat
/* Typescript / ES6 (quitar el tipado y ciertas características como las interfaces, entre otras) */
import { BaseFormat, Message } from '@nalv/logger'

export interface PersonalFormatOptions {
  padStart?: number,
}

export class PersonalFormat extends BaseFormat {

  // Opciones recibidas
  options: PersonalFormatOptions = {}

  constructor(options: PersonalFormatOptions = {}) {
    super()
    this.options.padStart = options.padStart || 16
  }

  format(data: Message): Message {
    data.message = data.message.padStart(this.options.padStart)
    return data
  }

}

Se debe extender de la clase BaseFormat. El constructor será como cualquier clase, incluyendo las opciones que tendrá el nuevo "format" entre sus parámetros (esto es libre, no tiene mucho que ver con la creación en si de un format.

Método format

Para que el nuevo formato pueda hacer una transformación con la información recibida, debe tener un método público llamado format, esta función recibe un parámetro que corresponde con la información recibida al ejecutar un log logger.info('prueba'). La información que contiene este argumento es un objeto con: | Llave (key) | Descripción | Ejemplo | Valor según el ejemplo | |-|-|-|-| | level | Nivel que se esta imprimiendo | logger.info('imprimir') | 'info' | | message | Mensaje que se esta imprimiendo | logger.info('imprimir') | 'imprimir' | | data | Información adicional enviada | logger.info('mensaje', {mas: 'info'}) | {mas: 'info'} | | args | Argumentos adicionales enviados | logger.info('', {}, 'otros', {msg: 'argumentos'}) | ['otros', {msg: 'argumentos'}] |

Éste método debe retornar un objeto con el mismo formato del primer argumento, pero con la información ya modificada. Este objeto lo recibirá el plugin y hará uso de ella según corresponda.

Uso

Para usar el formato personalizado debe ser llamado como los "nativos" del paquete:

/* Javascript */
const nalvLogger = require('@nalv/logger')
const personalFormat = require('./personal-format').format

const logger = new nalvLogger.Logger({
  format: new PersonalFormat({ padStart: 32 }),
  level: 'debug'
})
/* Typescript / ES6 (quitar el tipado) */
import { Logger } from '@nalv/logger'
import { PersonalFormat } from './personal-format'

const logger: Logger = new Logger({
  format: new PersonalFormat({ padStart: 32 }),
  level: 'debug'
})

Plugins

Los "plugins" son los sujetos encargados de utilizar la información enviada cuando se ejecuta un log, para que quede en un registro según el plugin haya sido programado.

Todos los plugins tienen una configuración base que se hereda de BasePlugin: | Llave (key) | Descripción | |-|-| | level | Desde que nivel se comenzarán a ejecutar los logs para este plugin. | | format | El formato que tendrán los logs al ejecutarse en este plugin. |

Plugin: Console

Registrar los logs en la consola donde se ejecuta el proceso de la aplicación.

Opciones de construcción de new ConsolePlugin({ }): | Llave (key) | Descripción | |-|-| | - | Este plugin no tiene opciones adicionales. Solo se limita a las opciones que hereda de BasePlugin, ver aquí.

Plugin: File

Registrar los logs en archivos.

Opciones de construcción de new FilePlugin({ }): | Llave (key) | Descripción | |-|-| | filename | Path del archivo que se usará para el registro de los logs. |

Crear plugins personalizados

Ejemplo

Para el ejemplo recrearemos el plugin ConsolePlugin "nativo" del paquete, que sirve para mostrar los logs en la consola donde se este ejecutando el proceso de la aplicación.

/* Javascript */
const nalvLogger = require('@nalv/logger')

class ConsolePlugin extends nalvLogger.BasePlugin {
  
  constructor(setting, additional) {
    super(setting, additional)
  }

  log(data) {
  console.log(data.message)
  }

}

exports.plugin = ConsolePlugin
/* Typescript / ES6 (quitar el tipado) */
import { BasePlugin, Message, PluginSetting } from '@nalv/logger'

export class ConsolePlugin extends BasePlugin {

  constructor(setting: PluginSetting = {}, additional?: any) {
    super(setting, additional)
  }

  log(data: Message) {
    console.log(data.message)
  }

}

Se debe extender de la clase BasePlugin.

Método constructor

A diferencia de los formats, los plugins deben enviar información a su clase parent BasePlugin ya que todos los plugins tienen una base estricta de funcionamiento que parte desde el constructor.

Los argumentos que recibe son mínimo el primero, que corresponde con la configuración que tendrá el plugin. Por ejemplo, para el plugin FilePlugin este argumento incluiría filename que representa al path del archivo que se usará para guardar los logs.

Además de esto, el primer argumento puede recibir información "nativa" de todos los plugins (osea, que todos los plugins deben tener, por consecuencia de BasePlugin. Para ver estos argumentos, mira aquí.

Para el caso de FilePlugin, incluiríamos la configuración del plugin: | Llave (key) | Descripción | |-|-| | filename | Path del archivo que se usará para guardar la información de logs recibidos. |

Método log

El método log es el que se ejecuta cuando se llama un log. Es quien debe plasmar la información en un fichero (para el caso de FilePlugin), la consola (para ConsolePlugin) o algún otro receptor (no limitado).

Recibe un parámetro que corresponde con la información generada por el log. Este objeto es el que envía el format una vez hizo su trabajo. Para ver detalles de este objeto, revisa aquí.

Este método no esta obligado ni necesita retornar información.

Logger por defecto

El paquete incluye un logger ya creado, pensado en un uso global (una aplicación en general, compartir el mismo logger entre módulos). Para ocuparlo se debe llamar al objeto Log desde '@nalv/logger', osea:

const nalvLogger = require('@nalv/logger')
const Log = nalvLogger.Log // const { Log } = require('@nalv/logger')
// import { Log } from '@nalv/logger' // Para Typescript y ES6

Log.info('logger por defecto con info')

Métodos

Sus métodos son limitados en comparación a un logger creado de manera "oficial", aunque hay ciertos métodos que hacen que su funcionamiento sea igual al de éstos.

Método setLogger

Si quieres establecer al logger otro logger para ocupar su configuración (por ejemplo), puedes mediante el método setLogger:

let newlogger = new Logger()
Log.setLogger(newlogger)

Método getLogger

Obtener el logger que se esta ocupando. Por defecto ocupa un logger vacío, con la configuración por defecto new Logger().

Con esto, se puede ingresar al objeto logger:

Log.getLogger().log('nivelPersonalizado', 'mensaje a guardar')
Log.getLogger().nivelPersonalizado('mensaje a guardar')

Métodos de log

Existen ciertos métodos disponibles para ejecutar logs, éstos se establecieron según los niveles por defecto y no se pueden cambiar. Estos son:

  • Log.emergency
  • Log.alert
  • Log.critical
  • Log.error
  • Log.warn
  • Log.notice
  • Log.info
  • Log.debug

Si se quiere ocupar logs de niveles que no están en el log por defecto, se debe ocupar el método getLogger