Changeset View
Changeset View
Standalone View
Standalone View
lib/Kolab/Utils/DAVLogger.php
Show All 27 Lines | |||||
use Kolab\DAV\Auth\HTTPBasic; | use Kolab\DAV\Auth\HTTPBasic; | ||||
/** | /** | ||||
* Utility class to log debug information about processed DAV requests | * Utility class to log debug information about processed DAV requests | ||||
*/ | */ | ||||
class DAVLogger extends DAV\ServerPlugin | class DAVLogger extends DAV\ServerPlugin | ||||
{ | { | ||||
const CONSOLE = 1; | const CONSOLE = 1; | ||||
const HTTP_REQUEST = 2; | const HTTP_REQUEST = 2; | ||||
const HTTP_RESPONSE = 4; | const HTTP_RESPONSE = 4; | ||||
private $rcube; | private $rcube; | ||||
private $server; | private $server; | ||||
private $method; | private $method; | ||||
private $loglevel; | private $loglevel; | ||||
/** | /** | ||||
* Default constructor | * Default constructor | ||||
*/ | */ | ||||
public function __construct($level = 1) | public function __construct($level = 1) | ||||
{ | { | ||||
$this->rcube = rcube::get_instance(); | $this->rcube = rcube::get_instance(); | ||||
$this->loglevel = $level; | $this->loglevel = $level; | ||||
} | } | ||||
/** | /** | ||||
* This initializes the plugin. | * This initializes the plugin. | ||||
* This method should set up the required event subscriptions. | * This method should set up the required event subscriptions. | ||||
* | * | ||||
* @param Server $server | * @param Server $server | ||||
Show All 13 Lines | class DAVLogger extends DAV\ServerPlugin | ||||
/** | /** | ||||
* Handler for 'beforeMethod' events | * Handler for 'beforeMethod' events | ||||
*/ | */ | ||||
public function _beforeMethod($request, $response) | public function _beforeMethod($request, $response) | ||||
{ | { | ||||
$this->method = $request->getMethod(); | $this->method = $request->getMethod(); | ||||
// turn on per-user http logging if the destination file exists | // turn on per-user http logging if the destination file exists | ||||
if ($this->loglevel < 2 && $this->rcube->config->get('kolabdav_user_debug', false) | if ($this->loglevel < 2 && $this->rcube->config->get('per_user_logging', false) | ||||
&& ($log_dir = $this->user_log_dir()) && file_exists($log_dir . '/httpraw')) { | && ($log_dir = $this->user_log_dir()) && file_exists($log_dir . '/httpraw') | ||||
) { | |||||
$this->loglevel |= (self::HTTP_REQUEST | self::HTTP_RESPONSE); | $this->loglevel |= (self::HTTP_REQUEST | self::HTTP_RESPONSE); | ||||
} | } | ||||
// log full HTTP request data | // log full HTTP request data | ||||
if ($this->loglevel & self::HTTP_REQUEST) { | if ($this->loglevel & self::HTTP_REQUEST) { | ||||
$content_type = $request->getHeader('Content-Type'); | $content_type = $request->getHeader('Content-Type'); | ||||
if (strpos($content_type, 'text/') === 0 || strpos($content_type, 'application/xml') === 0) { | if (strpos($content_type, 'text/') === 0 || strpos($content_type, 'application/xml') === 0) { | ||||
$http_body = $request->getBodyAsString(); | $http_body = $request->getBodyAsString(); | ||||
Show All 11 Lines | public function _beforeMethod($request, $response) | ||||
foreach ($this->get_request_headers() as $hdr => $value) { | foreach ($this->get_request_headers() as $hdr => $value) { | ||||
if (strtolower($hdr) == 'authorization') { | if (strtolower($hdr) == 'authorization') { | ||||
$method = preg_match('/^((basic|digest)\s+)/i', $value, $m) ? $m[1] : ''; | $method = preg_match('/^((basic|digest)\s+)/i', $value, $m) ? $m[1] : ''; | ||||
$value = $method . str_repeat('*', strlen($value) - strlen($method)); | $value = $method . str_repeat('*', strlen($value) - strlen($method)); | ||||
} | } | ||||
$http_headers[$hdr] = "$hdr: $value"; | $http_headers[$hdr] = "$hdr: $value"; | ||||
} | } | ||||
$this->write_log('httpraw', $request->getMethod() . ' ' . $request->getUrl() . ' ' . $_SERVER['SERVER_PROTOCOL'] . "\n" . | rcube::write_log('httpraw', $request->getMethod() . ' ' . $request->getUrl() . ' ' . $_SERVER['SERVER_PROTOCOL'] . "\n" . | ||||
join("\n", $http_headers) . "\n\n" . $http_body); | join("\n", $http_headers) . "\n\n" . $http_body); | ||||
} | } | ||||
// log to console | // log to console | ||||
if ($this->loglevel & self::CONSOLE) { | if ($this->loglevel & self::CONSOLE) { | ||||
$this->write_log('console', $this->method . ' ' . $request->getUrl()); | rcube::write_log('console', $this->method . ' ' . $request->getUrl()); | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* Wrapper function in case apache_request_headers() is not available | * Wrapper function in case apache_request_headers() is not available | ||||
* | * | ||||
* @return array | * @return array | ||||
*/ | */ | ||||
Show All 31 Lines | class DAVLogger extends DAV\ServerPlugin | ||||
* Handler for 'exit' events | * Handler for 'exit' events | ||||
*/ | */ | ||||
public function _exit() | public function _exit() | ||||
{ | { | ||||
if ($this->loglevel & self::CONSOLE) { | if ($this->loglevel & self::CONSOLE) { | ||||
$time = microtime(true) - KOLAB_DAV_START; | $time = microtime(true) - KOLAB_DAV_START; | ||||
if (function_exists('memory_get_usage')) | if (function_exists('memory_get_usage')) | ||||
$mem = round(memory_get_usage() / 1024 / 1024, 1) . 'MB'; | $mem = round(memory_get_usage() / 1024 / 1024, 1) . 'MB'; | ||||
if (function_exists('memory_get_peak_usage')) | if (function_exists('memory_get_peak_usage')) | ||||
$mem .= '/' . round(memory_get_peak_usage() / 1024 / 1024, 1) . 'MB'; | $mem .= '/' . round(memory_get_peak_usage() / 1024 / 1024, 1) . 'MB'; | ||||
$this->write_log('console', sprintf("/%s: %0.4f sec; %s", $this->method, $time, $mem)); | rcube::write_log('console', sprintf("/%s: %0.4f sec; %s", $this->method, $time, $mem)); | ||||
} | } | ||||
// log full HTTP reponse | // log full HTTP reponse | ||||
if ($this->loglevel & self::HTTP_RESPONSE) { | if ($this->loglevel & self::HTTP_RESPONSE) { | ||||
$this->write_log('httpraw', "RESPONSE: " . $this->server->httpResponse->dump()); | rcube::write_log('httpraw', "RESPONSE: " . $this->server->httpResponse->dump()); | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Wrapper for rcube::cosole() to write per-user logs | * Wrapper for rcube::cosole() to write per-user logs | ||||
*/ | */ | ||||
public function console(/* ... */) | public function console(/* ... */) | ||||
{ | { | ||||
if ($this->loglevel & self::CONSOLE) { | if ($this->loglevel & self::CONSOLE) { | ||||
$msg = array(); | $msg = array(); | ||||
foreach (func_get_args() as $arg) { | foreach (func_get_args() as $arg) { | ||||
$msg[] = !is_string($arg) ? var_export($arg, true) : $arg; | $msg[] = !is_string($arg) ? var_export($arg, true) : $arg; | ||||
} | } | ||||
$this->write_log('console', join(";\n", $msg)); | rcube::write_log('console', join(";\n", $msg)); | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Wrapper for rcube::write_log() that can write per-user logs | |||||
*/ | |||||
public function write_log($filename, $msg) | |||||
{ | |||||
// dump data per user | |||||
if ($this->rcube->config->get('kolabdav_user_debug', false)) { | |||||
if ($this->user_log_dir()) { | |||||
$filename = HTTPBasic::$current_user . '/' . $filename; | |||||
} | |||||
else { | |||||
return; // don't log | |||||
} | |||||
} | |||||
rcube::write_log($filename, $msg); | |||||
} | |||||
/** | |||||
* Get the per-user log directory | * Get the per-user log directory | ||||
*/ | */ | ||||
private function user_log_dir() | private function user_log_dir() | ||||
{ | { | ||||
$log_dir = $this->rcube->config->get('log_dir', RCUBE_INSTALL_PATH . 'logs'); | $log_dir = $this->rcube->config->get('log_dir', RCUBE_INSTALL_PATH . 'logs'); | ||||
$user_log_dir = $log_dir . '/' . HTTPBasic::$current_user; | $user_log_dir = $log_dir . '/' . HTTPBasic::$current_user; | ||||
return HTTPBasic::$current_user && is_writable($user_log_dir) ? $user_log_dir : false; | return HTTPBasic::$current_user && is_writable($user_log_dir) ? $user_log_dir : false; | ||||
} | } | ||||
} | } | ||||
No newline at end of file |