Un Escritor (Writer) es un objeto que hereda de Zend_Log_Writer_Abstract.
La responsabilidad de un Escritor es registrar los datos de log en un backend de almacenamiento.
Zend_Log_Writer_Stream envía los datos de log
a un flujo (stream) de PHP.
Para escribir datos de log en el búfer de salida de PHP, utilice la URL
php://output. Alternativamente, puede enviar los datos de log directamente a un
flujo como STDERR (php://stderr).
$writer = new Zend_Log_Writer_Stream('php://output');
$logger = new Zend_Log($writer);
$logger->info('Informational message');
Para escribir datos en un archivo, utilice una de las URLs del sistema de archivos:
$writer = new Zend_Log_Writer_Stream('/path/to/logfile');
$logger = new Zend_Log($writer);
$logger->info('Informational message');
Por defecto, el flujo se abre en modo de anexado ("a"). Para
abrirlo con un modo diferente, el constructor de Zend_Log_Writer_Stream
acepta un segundo parámetro opcional para el modo.
El constructor de Zend_Log_Writer_Stream también acepta un
recurso de flujo existente:
$stream = @fopen('/path/to/logfile', 'a', false);
if (! $stream) {
throw new Exception('Failed to open stream');
}
$writer = new Zend_Log_Writer_Stream($stream);
$logger = new Zend_Log($writer);
$logger->info('Informational message');
No puede especificar el modo para recursos de flujo existentes. Hacerlo
provoca que se lance una Zend_Log_Exception.
Zend_Log_Writer_Db escribe la información de log en una tabla de la base
de datos usando Zend_Db. El constructor de
Zend_Log_Writer_Db recibe una instancia de
Zend_Db_Adapter, un nombre de tabla, y una asignación de las
columnas de la base de datos a los elementos de datos del evento:
$params = array ('host' => '127.0.0.1',
'username' => 'malory',
'password' => '******',
'dbname' => 'camelot');
$db = Zend_Db::factory('PDO_MYSQL', $params);
$columnMapping = array('lvl' => 'priority', 'msg' => 'message');
$writer = new Zend_Log_Writer_Db($db, 'log_table_name', $columnMapping);
$logger = new Zend_Log($writer);
$logger->info('Informational message');
El ejemplo anterior escribe una única fila de datos de log en la tabla de la base de datos llamada 'log_table_name'. La columna de la base de datos llamada 'lvl' recibe el número de prioridad y la columna llamada 'msg' recibe el mensaje de log.
Zend_Log_Writer_Firebug envía los datos de log
a la Consola
de Firebug.
Todos los datos se envían a través del componente Zend_Wildfire_Channel_HttpHeaders
que utiliza cabeceras HTTP para asegurar que el contenido de la página no se vea alterado.
Es posible depurar peticiones AJAX que requieren respuestas JSON y
XML limpias con este enfoque.
Requisitos:
Navegador Firefox, idealmente la versión 3, aunque la versión 2 también es compatible.
La extensión Firebug para Firefox, que puede descargar desde https://addons.mozilla.org/en-US/firefox/addon/1843.
La extensión FirePHP para Firefox, que puede descargar desde https://addons.mozilla.org/en-US/firefox/addon/6149.
Ejemplo 44.1. Registro con Zend_Controller_Front
// Place this in your bootstrap file before dispatching your front controller
$writer = new Zend_Log_Writer_Firebug();
$logger = new Zend_Log($writer);
// Use this in your model, view and controller files
$logger->log('This is a log message!', Zend_Log::INFO);
Ejemplo 44.2. Registro sin Zend_Controller_Front
$writer = new Zend_Log_Writer_Firebug();
$logger = new Zend_Log($writer);
$request = new Zend_Controller_Request_Http();
$response = new Zend_Controller_Response_Http();
$channel = Zend_Wildfire_Channel_HttpHeaders::getInstance();
$channel->setRequest($request);
$channel->setResponse($response);
// Start output buffering
ob_start();
// Now you can make calls to the logger
$logger->log('This is a log message!', Zend_Log::INFO);
// Flush log data to browser
$channel->flush();
$response->sendHeaders();
Las prioridades integradas y las definidas por el usuario pueden ser estilizadas con el
método setPriorityStyle().
$logger->addPriority('FOO', 8);
$writer->setPriorityStyle(8, 'TRACE');
$logger->foo('Foo Message');
El estilo por defecto para las prioridades definidas por el usuario se puede establecer con el
método setDefaultPriorityStyle().
$writer->setDefaultPriorityStyle('TRACE');
Los estilos admitidos son los siguientes:
Tabla 44.2. Estilos de registro de Firebug
| Estilo | Descripción |
|---|---|
LOG |
Muestra un mensaje de log sencillo |
INFO |
Muestra un mensaje de log informativo |
WARN |
Muestra un mensaje de log de advertencia |
ERROR |
Muestra un mensaje de log de error que incrementa el contador de errores de Firebug |
TRACE |
Muestra un mensaje de log con una traza de pila desplegable |
EXCEPTION |
Muestra un mensaje de error largo con una traza de pila desplegable |
TABLE |
Muestra un mensaje de log con una tabla desplegable |
Aunque cualquier variable PHP puede registrarse con las prioridades integradas, se requiere un formato especial si se utilizan algunos de los estilos de log más especializados.
Los estilos LOG, INFO, WARN,
ERROR y TRACE no requieren
formato especial.
Para registrar una Zend_Exception simplemente pase el objeto de excepción al
registrador (logger). No importa qué prioridad o estilo haya establecido, ya que la excepción es
reconocida automáticamente.
$exception = new Zend_Exception('Test exception');
$logger->err($exception);
También puede registrar datos y formatearlos con estilo de tabla. Las columnas se reconocen automáticamente y la primera fila de datos se convierte automáticamente en el encabezado.
$writer->setPriorityStyle(8, 'TABLE');
$logger->addPriority('TABLE', 8);
$table = array('Summary line for the table',
array(
array('Column 1', 'Column 2'),
array('Row 1 c 1',' Row 1 c 2'),
array('Row 2 c 1',' Row 2 c 2')
)
);
$logger->table($table);
Zend_Log_Writer_Mail escribe las entradas de log en un mensaje de correo electrónico
utilizando Zend_Mail. El constructor de Zend_Log_Writer_Mail
recibe un objeto Zend_Mail, y un objeto opcional de
Zend_Layout.
El caso de uso principal de Zend_Log_Writer_Mail es notificar
a los desarrolladores, administradores de sistemas, o a cualquier parte interesada sobre errores
que puedan estar ocurriendo con scripts basados en PHP.
Zend_Log_Writer_Mail nació de la idea de que si
algo está roto, un ser humano necesita ser alertado de inmediato
para que pueda tomar medidas correctivas.
A continuación se describe el uso básico:
$mail = new Zend_Mail();
$mail->setFrom('errors@example.org')
->addTo('project_developers@example.org');
$writer = new Zend_Log_Writer_Mail($mail);
// Set subject text for use; summary of number of errors is appended to the
// subject line before sending the message.
$writer->setSubjectPrependText('Errors with script foo.php');
// Only email warning level entries and higher.
$writer->addFilter(Zend_Log::WARN);
$log = new Zend_Log();
$log->addWriter($writer);
// Something bad happened!
$log->error('unable to connect to database');
// On writer shutdown, Zend_Mail::send() is triggered to send an email with
// all log entries at or above the Zend_Log filter level.
Zend_Log_Writer_Mail renderizará el cuerpo del correo como texto
plano por defecto.
Se envía un único correo electrónico que contiene todas las entradas de log al nivel del filtro o superiores. Por ejemplo, si se van a enviar por correo las entradas de nivel de advertencia en adelante, y ocurren dos advertencias y cinco errores, el correo resultante contendrá un total de siete entradas de log.
Se puede utilizar una instancia de Zend_Layout para generar la
parte HTML de un correo multipart. Si se está utilizando una instancia de
Zend_Layout,
Zend_Log_Writer_Mail asume que se está usando para renderizar
HTML y establece el cuerpo HTML del mensaje como
el valor renderizado por Zend_Layout.
Cuando se utiliza Zend_Log_Writer_Mail con una instancia de
Zend_Layout, tiene la opción de establecer un
formateador personalizado mediante el método setLayoutFormatter().
Si no se especificó ningún formateador de entrada específico para Zend_Layout,
se utilizará el formateador actualmente en uso. A continuación se describe el uso completo
de Zend_Layout con un formateador personalizado.
$mail = new Zend_Mail();
$mail->setFrom('errors@example.org')
->addTo('project_developers@example.org');
// Note that a subject line is not being set on the Zend_Mail instance!
// Use a simple Zend_Layout instance with its defaults.
$layout = new Zend_Layout();
// Create a formatter that wraps the entry in a listitem tag.
$layoutFormatter = new Zend_Log_Formatter_Simple(
'<li>' . Zend_Log_Formatter_Simple::DEFAULT_FORMAT . '</li>'
);
$writer = new Zend_Log_Writer_Mail($mail, $layout);
// Apply the formatter for entries as rendered with Zend_Layout.
$writer->setLayoutFormatter($layoutFormatter);
$writer->setSubjectPrependText('Errors with script foo.php');
$writer->addFilter(Zend_Log::WARN);
$log = new Zend_Log();
$log->addWriter($writer);
// Something bad happened!
$log->error('unable to connect to database');
// On writer shutdown, Zend_Mail::send() is triggered to send an email with
// all log entries at or above the Zend_Log filter level. The email will
// contain both plain text and HTML parts.
El método setSubjectPrependText() puede utilizarse en lugar
de Zend_Mail::setSubject() para que la línea de asunto del correo
se escriba dinámicamente antes de enviar el correo. Por ejemplo, si
el texto anteponible al asunto dice "Errors from script", el asunto de
un correo generado por Zend_Log_Writer_Mail con dos
advertencias y cinco errores sería "Errors from script (warn = 2;
error = 5)". Si no se está utilizando texto anteponible al asunto mediante
Zend_Log_Writer_Mail, se utiliza la línea de asunto de
Zend_Mail, si la hubiera.
Enviar entradas de log por correo electrónico puede ser peligroso. Si las condiciones de error no se gestionan adecuadamente en su script, o si está haciendo un mal uso de los niveles de error, podría encontrarse en una situación en la que esté enviando cientos o miles de correos electrónicos a los destinatarios dependiendo de la frecuencia de sus errores.
Por el momento, Zend_Log_Writer_Mail no proporciona ningún
mecanismo para regular o agrupar los mensajes de otra manera.
Dicha funcionalidad debería ser implementada por el consumidor si
es necesario.
Nuevamente, el objetivo principal de Zend_Log_Writer_Mail es
notificar proactivamente a un ser humano sobre condiciones de error. Si esos
errores se están gestionando de manera oportuna, y se están implementando salvaguardas
para prevenir esas circunstancias en el futuro,
entonces la notificación de errores por correo electrónico puede ser una herramienta valiosa.
Zend_Log_Writer_Syslog escribe las entradas de log en el
log del sistema (syslog). Internamente, actúa como proxy de las funciones
openlog(),
closelog(), y
syslog() de PHP.
Un caso útil para Zend_Log_Writer_Syslog
es la agregación de logs de máquinas agrupadas (clustered) mediante la funcionalidad del log del
sistema. Muchos sistemas permiten el registro remoto de eventos del sistema, lo que
permite a los administradores de sistemas monitorizar un clúster de máquinas desde un
único archivo de log.
Por defecto, todos los mensajes de syslog generados llevan el prefijo de la cadena "Zend_Log". Puede especificar un nombre de "aplicación" diferente con el que identificar dichos mensajes de log ya sea pasando el nombre de la aplicación al constructor o al método de acceso de la aplicación:
// At instantiation, pass the "application" key in the options:
$writer = new Zend_Log_Writer_Syslog(array('application' => 'FooBar'));
// Any other time:
$writer->setApplicationName('BarBaz');
El log del sistema también le permite identificar la "facilidad" (facility), o tipo de aplicación, que registra el mensaje; muchos registradores del sistema en realidad generan diferentes archivos de log por facilidad, lo que de nuevo ayuda a los administradores a monitorizar la actividad del servidor.
Puede especificar la facilidad del log ya sea en el constructor o mediante un
método de acceso. Debe ser una de las constantes de openlog()
definidas en la página del manual de
openlog().
// At instantiation, pass the "facility" key in the options:
$writer = new Zend_Log_Writer_Syslog(array('facility' => LOG_AUTH));
// Any other time:
$writer->setFacility(LOG_USER);
Al registrar, puede seguir usando las constantes de prioridad por defecto de
Zend_Log; internamente, se asignan a las constantes de prioridad
de syslog() correspondientes.
Zend_Log_Writer_ZendMonitor le permite registrar eventos mediante la
API Monitor de Zend Server. Esto le permite agregar mensajes de log de todo su entorno
de aplicación en una única ubicación. Internamente, simplemente utiliza la
función monitor_custom_event() de la API de Zend
Monitor.
Una característica particularmente útil de la API Monitor es que le permite especificar información personalizada arbitraria junto con el mensaje de log. Por ejemplo, si desea registrar una excepción, puede registrar no solo el mensaje de la excepción, sino pasar el objeto de excepción completo a la función, y luego inspeccionar el objeto dentro del monitor de eventos de Zend Server.
![]() |
Zend Monitor debe estar instalado y habilitado |
|---|---|
Para utilizar este escritor de log, Zend Monitor debe estar instalado y habilitado.
Sin embargo, está diseñado de forma que si no se detecta Zend Monitor, simplemente actuará
como un registrador |
Instanciar el escritor de log ZendMonitor es trivial:
$writer = new Zend_Log_Writer_ZendMonitor(); $log = new Zend_Log($writer);
Luego, simplemente registre mensajes como de costumbre:
$log->info('This is a message');
Si desea especificar información adicional para registrar junto con el evento, pase esa información en un segundo parámetro:
$log->info('Exception occurred', $e);
El segundo parámetro puede ser un escalar, objeto, o array; si necesita pasar múltiples piezas de información, la mejor manera de hacerlo es pasar un array asociativo.
$log->info('Exception occurred', array(
'request' => $request,
'exception' => $e,
));
Dentro de Zend Server, su evento se registra como un "evento personalizado". Desde la pestaña "Monitor", seleccione el subelemento "Events", y luego filtre por "Custom" para ver los eventos personalizados.
Eventos en el panel Monitor de Zend Server
En esta captura de pantalla, los primeros dos eventos listados son eventos personalizados registrados mediante
el escritor de log ZendMonitor. Puede entonces hacer clic en un evento para ver toda la
información relacionada con él.
Detalle del evento en el Monitor de Zend Server
Al hacer clic en la subpestaña "Custom" se detallará cualquier información adicional que haya registrado
al pasar el segundo argumento al método de registro. Esta información se registrará como la
subclave info; puede ver que el objeto de la petición se registró en este
ejemplo.
![]() |
Integración con Zend_Application |
|---|---|
|
Por defecto, los comandos zf.sh y zf.bat añaden
la configuración para el recurso log
de
Como se señaló anteriormente, si la API Monitor no se detecta en su
instalación de PHP, el registrador simplemente actuará como un
registrador |
El Zend_Log_Writer_Null es un stub que no escribe datos de log
a ningún destino. Es útil para deshabilitar el registro o simular el registro durante las pruebas:
$writer = new Zend_Log_Writer_Null;
$logger = new Zend_Log($writer);
// goes nowhere
$logger->info('Informational message');
El Zend_Log_Writer_Mock es un escritor muy simple que registra
los datos en bruto que recibe en un array expuesto como propiedad pública.
$mock = new Zend_Log_Writer_Mock;
$logger = new Zend_Log($mock);
$logger->info('Informational message');
var_dump($mock->events[0]);
// Array
// (
// [timestamp] => 2007-04-06T07:16:37-07:00
// [message] => Informational message
// [priority] => 6
// [priorityName] => INFO
// )
Para limpiar los eventos registrados por el mock, simplemente establezca $mock->events = array().
No existe un objeto Escritor compuesto. Sin embargo, una instancia de Log puede escribir
en cualquier número de Escritores. Para hacerlo, utilice el método addWriter():
$writer1 = new Zend_Log_Writer_Stream('/path/to/first/logfile');
$writer2 = new Zend_Log_Writer_Stream('/path/to/second/logfile');
$logger = new Zend_Log();
$logger->addWriter($writer1);
$logger->addWriter($writer2);
// goes to both writers
$logger->info('Informational message');
![[Note]](images/note.png)