Manual:Structured logging/es
Versión de MediaWiki: | ≥ 1.25 |
El registro estructurado es el registro operativo (depuración) que incluye datos estructurados para facilitar su posprocesado. Se distingue de Manual:Registrar en Especial:Registro , que es el registro para beneficio de los editores del wiki; el registro estructurado es para beneficio de los desarrolladores.
Desde MediaWiki 1.25, el estándar de registro PSR-3 ha estado disponible para su uso en el núcleo y las extensiones de MediaWiki en sustitución de las desfasadas llamadas de depuración wfDebug
y wfDebugLog
.
El estándar PSR-3 permite anexar un vector de datos contextuales a cada mensaje de registro para proporcionar pares estructurados clave-valor.
Obtener un registrador (logger) de LoggerFactory
use MediaWiki\Logger\LoggerFactory;
$logger = LoggerFactory::getInstance( 'MyCoolLoggingChannel' );
El parámetro pasado a LoggerFactory::getInstance
(aquí, MyCoolLoggingChannel
) es el nombre del canal de registro.
La forma de usar el nombre del canal depende de la configuración del registro (véase más adelante), pero en general se pueden dirigir los distintos canales de registro a distintos archivos o sus equivalentes.
Se recomienda utilizar algo único (generalmente el nombre de tu extensión) como nombre del canal para que sea más fácil separar entradas de registro sin relación entre ellas.
Enviar mensajes al registro
Una vez tengas un objeto registrador (logger), puedes utilizar sus métodos correspondientes a los niveles de gravedad de PSR-3 para registrar mensajes:
$logger->debug( 'Entered ' . __METHOD__ )
- Estos son mensajes que son útiles para el desarrollo en local y generalmente son demasiado verbosos para salir a un wiki de producción. Esto generalmente incluiría cualquier cosa que se registre en la actualidad mediante wfDebug.
$logger->info( 'Restoring page' )
- Información valiosa de cambio de estado. Este nivel es ideal para registrar información que sería útil en un entorno de producción a la hora de obtener la traza de una solicitud que dio lugar a un error. Este es en la actualidad el nivel asociado automáticamente a las llamadas de
wfDebugLog
al ser mapeado a PSR-3. $logger->warning( 'Page is protected' )
- Condición leve de error tal como un error recuperable u otra condición que generalmente no debería producirse pero que no interrumpe la operación en curso.
$logger->error( 'Page not found' )
- Un error grave tal como una excepción capturada sin ruta de recuperación.
El estándar PSR-3 incluye otros niveles de gravedad, aunque no se recomienda utilizarlos en MediaWiki.
Añadir datos estructurados al contexto de registro
Todos los métodos de registro aceptan un vector opcional de contexto, por ejemplo:
$logger->warning( 'page not found', [ 'user' => $user->getName(), 'title' => $page->getPrefixedText() ] );
Es recomendable que añadas información estructurada útil a tus mensajes de registro en este objeto de contexto que otras personas puedan utilizar para encontrar mensajes relevantes o registros relevantes de la base de datos y trazar la causa del error.
Esto es especialmente importante y útil para los mensajes de nivel warning
y error
, donde el operador del wiki puede que no conozca bien la ruta del código y aun así debe poder crear un buen informe de error.
- Si pasas un objeto Exception en el parámetro del contexto, DEBE estar en la clave 'exception' (por ejemplo,
$logger->error( 'got exception', [ 'exception' => $e ] )
)
- También puedes generar un objeto de excepción sobre la marcha, que es una buena manera de adjuntar una traza de la pila, por ejemplo, al registrar un error en una función de utilidad que es invocada en muchos sitios:
$logger->warning( 'called with a user which does not exist', [ 'user' => $user->getName(), 'exception' => new RuntimeException() ] )
- También puedes generar un objeto de excepción sobre la marcha, que es una buena manera de adjuntar una traza de la pila, por ejemplo, al registrar un error en una función de utilidad que es invocada en muchos sitios:
- Añade parámetros y otros estados de interés a los mensajes. Lo mejor es que te asegures de que los elementos del vector de contexto sean cadenas. (También pueden admitirse otros tipos, pero el comportamiento para valores que no sean cadenas a menudo no es intuitivo.) Muchas clases del núcleo de MediaWiki tienen un método
__toString
que genera alguna descripción del objeto que facilita la depuración, así que puedes simplemente utilizar elementos de tipo(string)$titleValue
.- Si decides pasar valores que no sean cadenas, trata de utilizar nombres razonablemente únicos para los campos. Esto es esencialmente necesario para la producción de Wikimedia que envía los datos de contexto a Logstash, que requiere que todos los datos de contexto que utilicen una misma clase sean del mismo tipo (de forma global, entre todos los canales de registro).
- Los parámetros estándar (nombre del wiki, nombre del servidor, etc.) serán añadidos automáticamente. Los detalles dependerán del servicio de registro que utilices, pero probablemente acabarás utilizando MediaWiki\Logger\Monolog\WikiProcessor.
- Reemplaza las estructuras falsas tales como elementos separados por tabuladores, pares etiqueta=valor/etiqueta:valor o serialización JSON.
Muchos agregadores de registros tratan de desduplicar los registros por mensaje, así que trata de separar del mensaje cualquier detalle sujeto a cambios y muévelo dentro del contexto. El registrador reemplazará cada token entre llaves por el valor correspondiente del contexto. Por ejemplo, el código
$logger->error( 'Caught exception while trying to create user {user}: {exception}', [
'user' => $user->getName(),
'exception' => $e,
] );
producirá algo similar a
Caught exception while trying to create user Foo: exception DatabaseException with message 'Unique constraint violation' in /srv/mediawiki/includes/Database.php:123
#0 /srv/mediawiki/includes/Database.php(456): Database::query()
...
Para maximizar la compatibilidad con los distintos servidores de registro, no utilices estas claves en tus datos de contexto:
message
channel
host
level
type
@timestamp
@version
Utilizar objetos compatibles con PSR-3
Genera excepciones que implementen INormalizedException
(o, si no necesitas una clase de excepción personalizada, NormalizedException
) para que los mensajes de excepción que guarden relación entre sí puedan agruparse en los registros.
Puedes convertir objetos Status y StatusValue en el estándar de PSR-3 con:
$statusFormatter = MediaWikiServices::getInstance()->getFormatterFactory()->getStatusFormatter( RequestContext::getMain() );
[ $message, $context ] = $statusFormatter->getPsr3MessageAndContext( $status );
$logger->error( $message, $context );
Esta es la mejor opción: Status tiene una estructura interna caótica, así que a veces esto acabará simplemente con algo similar a [ '{message}', 'message' => '...the error message in the Status object' ]
. Pero para los estados que contengan un solo mensaje, producirá bonitas cadenas de mensajes fáciles de agrupar.
Configurar tu wiki para el registro estructurado
Por retrocompatibilidad, si utilizas la configuración por defecto de MediaWiki y tienes configurado el registro básico, independientemente de si suministras un objeto de contexto a estos métodos de registro o a funciones globales de MediaWiki tales como wfDebugLog( 'myChannel', $someMessage, 'private', $someContext )
, la información del objeto de contexto no aparece en los archivos de registro que has configurado.
Es recomendable implementar un registrador mejor, como monolog, como «interfaz del proveedor de servicio» del registrador.
Véanse $wgMWLoggerDefaultSpi
y Manual:MonologSpi .
Véase también
- Requests for comment/Structured logging
- Norma de registro PSR-3
- Manual:Cómo depurar
- wikitech:logstash - Wikimedia alimenta la mayor parte de sus registros de MediaWiki en logstash, que entiende el registro estructurado