use Monolog via composer instead of our own implementation, @TODO MySQL logging-handler

Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
This commit is contained in:
Michael Kaufmann
2018-12-18 12:16:48 +01:00
parent fc0a495f2d
commit 9d314aaa3f
10 changed files with 354 additions and 763 deletions

View File

@@ -1,97 +0,0 @@
<?php
/**
* This file is part of the Froxlor project.
* Copyright (c) 2003-2009 the SysCP Team (see authors).
* Copyright (c) 2010 the Froxlor Team (see authors).
*
* For the full copyright and license information, please view the COPYING
* file that was distributed with this source code. You can also view the
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
*
* @copyright (c) the authors
* @author Michael Kaufmann <mkaufmann@nutime.de>
* @author Froxlor team <team@froxlor.org> (2010-)
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
* @package Logger
*
* @link http://www.nutime.de/
*
* Logger - Abstract-Logger-Class
*/
/* We're using the syslog constants for all the loggers (partly implemented)
LOG_EMERG system is unusable
LOG_ALERT action must be taken immediately
LOG_CRIT critical conditions
LOG_ERR error conditions
LOG_WARNING warning conditions
LOG_NOTICE normal, but significant, condition
LOG_INFO informational message
LOG_DEBUG debug-level message
*/
abstract class AbstractLogger {
/**
* Enable/Disable Logging
* @var boolean
*/
private $logenabled = false;
/**
* Enable/Disable Cronjob-Logging
* @var boolean
*/
private $logcronjob = false;
/**
* Loggin-Severity
* @var int
*/
private $severity = 1;
/**
* setup the main logger
*/
protected function setupLogger() {
$this->logenabled = Settings::Get('logger.enabled');
$this->logcronjob = Settings::Get('logger.log_cron');
$this->severity = Settings::Get('logger.severity');
}
/**
* return whether this logging is enabled
*
* @return bool
*/
protected function isEnabled() {
return $this->logenabled;
}
/**
* return the log severity
*
* @return int
*/
protected function getSeverity() {
return $this->severity;
}
/**
* whether to log cron-runs or not
*
* @return bool
*/
protected function logCron() {
return $this->logcronjob;
}
/**
* logs a given text
*/
abstract public function logAction();
}

View File

@@ -1,164 +0,0 @@
<?php
/**
* This file is part of the Froxlor project.
* Copyright (c) 2003-2009 the SysCP Team (see authors).
* Copyright (c) 2010 the Froxlor Team (see authors).
*
* For the full copyright and license information, please view the COPYING
* file that was distributed with this source code. You can also view the
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
*
* @copyright (c) the authors
* @author Michael Kaufmann <mkaufmann@nutime.de>
* @author Froxlor team <team@froxlor.org> (2010-)
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
* @package Logger
*
* @link http://www.nutime.de/
*
* Logger - File-Logger-Class
*/
class FileLogger extends AbstractLogger {
/**
* Userinfo
* @var array
*/
private $userinfo = array();
/**
* Logfile
* @var string
*/
private $logfile = null;
/**
* Syslogger Objects Array
* @var FileLogger[]
*/
static private $loggers = array();
/**
* Class constructor.
*
* @param array userinfo
*/
protected function __construct($userinfo) {
parent::setupLogger();
$this->userinfo = $userinfo;
$this->setLogFile(Settings::Get('logger.logfile'));
}
/**
* Singleton ftw ;-)
*/
static public function getInstanceOf($_usernfo) {
if (!isset(self::$loggers[$_usernfo['loginname']])) {
self::$loggers[$_usernfo['loginname']] = new FileLogger($_usernfo);
}
return self::$loggers[$_usernfo['loginname']];
}
/**
* logs a given text to all enabled logger-facilities
*
* @param int $action
* @param int $type
* @param string $text
*/
public function logAction($action = USR_ACTION, $type = LOG_NOTICE, $text = null) {
global $lng;
if (parent::isEnabled()) {
if (parent::getSeverity() <= 1
&& $type == LOG_NOTICE
) {
return;
}
$_action = 'unknown';
switch($action)
{
case USR_ACTION:
$_action = $lng['admin']['customer'];
break;
case RES_ACTION:
$_action = $lng['logger']['reseller'];
break;
case ADM_ACTION:
$_action = $lng['logger']['admin'];
break;
case CRON_ACTION:
$_action = $lng['logger']['cron'];
break;
case LOGIN_ACTION:
$_action = $lng['logger']['login'];
break;
case LOG_ERROR:
$_action = $lng['logger']['intern'];
break;
default:
$_action = $lng['logger']['unknown'];
break;
}
$_type = getLogLevelDesc($type);
if(!isset($this->userinfo['loginname'])
|| $this->userinfo['loginname'] == '')
{
$name = 'unknown';
}
else
{
$name = $this->userinfo['loginname'];
}
$fp = @fopen($this->logfile, 'a');
if($fp !== false)
{
$now = time();
if($text != null
&& $text != '')
{
fwrite($fp, date("d.m.Y H:i:s", $now) . " [" . $_type . "] [" . $_action . "-action " . $name . "] " . $text . "\n");
}
else
{
fwrite($fp, date("d.m.Y H:i:s", $now) . " [" . $_type . "] [" . $_action . "-action " . $name . "] No text given!!! Check scripts!\n");
}
fclose($fp);
}
else
{
if($this->logfile != null
|| $this->logfile != '')
{
throw new Exception("Cannot open logfile '" . $this->logfile . "' for writing!");
}
}
}
}
public function setLogFile($filename = null)
{
if($filename != null
&& $filename != ''
&& $filename != "."
&& $filename != ".."
&& !is_dir($filename))
{
$this->logfile = $filename;
return true;
}
return false;
}
}

View File

@@ -1,190 +0,0 @@
<?php
/**
* This file is part of the Froxlor project.
* Copyright (c) 2003-2009 the SysCP Team (see authors).
* Copyright (c) 2010 the Froxlor Team (see authors).
*
* For the full copyright and license information, please view the COPYING
* file that was distributed with this source code. You can also view the
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
*
* @copyright (c) the authors
* @author Michael Kaufmann <mkaufmann@nutime.de>
* @author Froxlor team <team@froxlor.org> (2010-)
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
* @package Logger
*
* @link http://www.nutime.de/
*
* Logger - Froxlor-Base-Logger-Class
*/
class FroxlorLogger {
/**
* Userinfo
* @var array
*/
private $userinfo = array();
/**
* LogTypes Array
* @var array
*/
static private $logtypes = null;
/**
* Logger-Object-Array
* @var FroxlorLogger[]
*/
static private $loggers = null;
/**
* whether to output log-messages to STDOUT (cron)
* @var bool
*/
static private $crondebug_flag = false;
/**
* Class constructor.
*
* @param array userinfo
*/
protected function __construct($userinfo) {
$this->userinfo = $userinfo;
self::$logtypes = array();
if ((Settings::Get('logger.logtypes') == null || Settings::Get('logger.logtypes') == '')
&& (Settings::Get('logger.enabled') !== null && Settings::Get('logger.enabled'))
) {
self::$logtypes[0] = 'syslog';
self::$logtypes[1] = 'mysql';
} else {
if (Settings::Get('logger.logtypes') !== null
&& Settings::Get('logger.logtypes') != ''
) {
self::$logtypes = explode(',', Settings::Get('logger.logtypes'));
} else {
self::$logtypes = null;
}
}
}
/**
* Singleton ftw ;-)
*
*/
static public function getInstanceOf($_usernfo) {
if (!isset($_usernfo)
|| $_usernfo == null
) {
$_usernfo = array();
$_usernfo['loginname'] = 'unknown';
}
if (!isset(self::$loggers[$_usernfo['loginname']])) {
self::$loggers[$_usernfo['loginname']] = new FroxlorLogger($_usernfo);
}
return self::$loggers[$_usernfo['loginname']];
}
/**
* logs a given text to all enabled logger-facilities
*
* @param int $action
* @param int $type
* @param string $text
*/
public function logAction ($action = USR_ACTION, $type = LOG_NOTICE, $text = null) {
if (self::$logtypes == null) {
return;
}
if (self::$crondebug_flag
|| ($action == CRON_ACTION && $type <= LOG_WARNING)) {
echo "[".getLogLevelDesc($type)."] ".$text.PHP_EOL;
}
if (Settings::Get('logger.log_cron') == '0'
&& $action == CRON_ACTION
&& $type > LOG_WARNING // warnings, errors and critical mesages WILL be logged
) {
return;
}
foreach (self::$logtypes as $logger) {
switch ($logger)
{
case 'syslog':
$_log = SysLogger::getInstanceOf($this->userinfo);
break;
case 'file':
try
{
$_log = FileLogger::getInstanceOf($this->userinfo);
}
catch(Exception $e)
{
if ($action != CRON_ACTION) {
standard_error('logerror', $e->getMessage());
} else {
echo "Log-Error: " . $e->getMessage();
}
}
break;
case 'mysql':
$_log = MysqlLogger::getInstanceOf($this->userinfo);
break;
default:
$_log = null;
break;
}
if ($_log != null) {
try {
$_log->logAction($action, $type, $text);
} catch(Exception $e) {
if ($action != CRON_ACTION) {
standard_error('logerror', $e->getMessage());
} else {
echo "Log-Error: " . $e->getMessage();
}
}
}
}
}
/**
* Set whether to log cron-runs
*
* @param bool $_cronlog
*
* @return boolean
*/
public function setCronLog($_cronlog = 0) {
$_cronlog = (int)$_cronlog;
if ($_cronlog < 0 || $_cronlog > 2) {
$_cronlog = 0;
}
Settings::Set('logger.log_cron', $_cronlog);
return $_cronlog;
}
/**
* setter for crondebug-flag
*
* @param bool $_flag
*
* @return void
*/
public function setCronDebugFlag($_flag = false) {
self::$crondebug_flag = (bool)$_flag;
}
}

View File

@@ -1,111 +0,0 @@
<?php
/**
* This file is part of the Froxlor project.
* Copyright (c) 2003-2009 the SysCP Team (see authors).
* Copyright (c) 2010 the Froxlor Team (see authors).
*
* For the full copyright and license information, please view the COPYING
* file that was distributed with this source code. You can also view the
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
*
* @copyright (c) the authors
* @author Michael Kaufmann <mkaufmann@nutime.de>
* @author Froxlor team <team@froxlor.org> (2010-)
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
* @package Logger
*
* @link http://www.nutime.de/
*
* Logger - MySQL-Logger-Class
*/
class MysqlLogger extends AbstractLogger {
/**
* Userinfo
* @var array
*/
private $userinfo = array();
/**
* Syslogger Objects Array
* @var MysqlLogger[]
*/
static private $loggers = array();
/**
* Class constructor.
*
* @param array userinfo
*/
protected function __construct($userinfo) {
parent::setupLogger();
$this->userinfo = $userinfo;
}
/**
* Singleton ftw ;-)
*/
static public function getInstanceOf($_usernfo) {
if (!isset(self::$loggers[$_usernfo['loginname']])) {
self::$loggers[$_usernfo['loginname']] = new MysqlLogger($_usernfo);
}
return self::$loggers[$_usernfo['loginname']];
}
/**
* logs a given text to all enabled logger-facilities
*
* @param int $action
* @param int $type
* @param string $text
*/
public function logAction($action = USR_ACTION, $type = LOG_NOTICE, $text = null) {
if (parent::isEnabled()) {
if (parent::getSeverity() <= 1
&& $type == LOG_NOTICE
) {
return;
}
if (!isset($this->userinfo['loginname'])
|| $this->userinfo['loginname'] == ''
) {
$name = 'unknown';
} else {
$name = $this->userinfo['loginname'];
}
$now = time();
$stmt = Database::prepare("
INSERT INTO `panel_syslog` SET
`type` = :type,
`date` = :now,
`action` = :action,
`user` = :user,
`text` = :text"
);
$ins_data = array(
'type' => $type,
'now' => $now,
'action' => $action,
'user' => $name
);
if ($text != null
&& $text != ''
) {
$ins_data['text'] = $text;
Database::pexecute($stmt, $ins_data);
} else {
$ins_data['text'] = 'No text given!!! Check scripts!';
Database::pexecute($stmt, $ins_data);
}
}
}
}

View File

@@ -1,125 +0,0 @@
<?php
/**
* This file is part of the Froxlor project.
* Copyright (c) 2003-2009 the SysCP Team (see authors).
* Copyright (c) 2010 the Froxlor Team (see authors).
*
* For the full copyright and license information, please view the COPYING
* file that was distributed with this source code. You can also view the
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
*
* @copyright (c) the authors
* @author Michael Kaufmann <mkaufmann@nutime.de>
* @author Froxlor team <team@froxlor.org> (2010-)
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
* @package Logger
*
* @link http://www.nutime.de/
*
* Logger - SysLog-Logger-Class
*/
class SysLogger extends AbstractLogger {
/**
* Userinfo
* @var array
*/
private $userinfo = array();
/**
* Syslogger Objects Array
* @var SysLogger[]
*/
static private $loggers = array();
/**
* Class constructor.
*
* @param array userinfo
*/
protected function __construct($userinfo) {
parent::setupLogger();
$this->userinfo = $userinfo;
}
/**
* Singleton ftw ;-)
*/
static public function getInstanceOf($_usernfo) {
if (!isset(self::$loggers[$_usernfo['loginname']])) {
self::$loggers[$_usernfo['loginname']] = new SysLogger($_usernfo);
}
return self::$loggers[$_usernfo['loginname']];
}
/**
* logs a given text to all enabled logger-facilities
*
* @param int $action
* @param int $type
* @param string $text
*/
public function logAction($action = USR_ACTION, $type = LOG_NOTICE, $text = null) {
global $lng;
if (parent::isEnabled()) {
if (parent::getSeverity() <= 1
&& $type == LOG_NOTICE
) {
return;
}
$_action = 'unknown';
switch($action)
{
case USR_ACTION:
$_action = $lng['admin']['customer'];
break;
case RES_ACTION:
$_action = $lng['logger']['reseller'];
break;
case ADM_ACTION:
$_action = $lng['logger']['admin'];
break;
case CRON_ACTION:
$_action = $lng['logger']['cron'];
break;
case LOGIN_ACTION:
$_action = $lng['logger']['login'];
break;
case LOG_ERROR:
$_action = $lng['logger']['intern'];
break;
default:
$_action = $lng['logger']['unknown'];
break;
}
if (!isset($this->userinfo['loginname'])
|| $this->userinfo['loginname'] == ''
) {
$name = 'unknown';
}
else
{
$name = $this->userinfo['loginname'];
}
openlog("Froxlor", LOG_NDELAY, LOG_USER);
if ($text != null
&& $text != ''
) {
syslog((int)$type, "[" . ucfirst($_action) . " Action " . $name . "] [".getLogLevelDesc($type)."] " . $text);
} else {
syslog((int)$type, "[" . ucfirst($_action) . " Action " . $name . "] [".getLogLevelDesc($type)."] No text given!!! Check scripts!");
}
closelog();
}
}
}

View File

@@ -1,300 +0,0 @@
<?php
/**
* This file is part of the Froxlor project.
* Copyright (c) 2010 the Froxlor Team (see authors).
*
* For the full copyright and license information, please view the COPYING
* file that was distributed with this source code. You can also view the
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
*
* @copyright (c) the authors
* @author Roman Schmerold <bnoize@froxlor.org>
* @author Froxlor team <team@froxlor.org> (2010-)
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
* @package Cron
*
* @since 0.9.32
*
*/
class MailLogParser {
private $startTime;
private $domainTraffic = array();
private $myDomains = array();
private $mails = array();
/**
* constructor
* @param string logFile
* @param int startTime
* @param string logFileExim
*/
public function __construct($startTime = 0) {
$this->startTime = $startTime;
// Get all domains from Database
$stmt = Database::prepare("SELECT domain FROM `" . TABLE_PANEL_DOMAINS . "`");
Database::pexecute($stmt, array());
while ($domain_row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$this->myDomains[] = $domain_row["domain"];
}
// Parse MTA traffic
if (Settings::Get("system.mtaserver") == "postfix") {
$this->_parsePostfixLog(Settings::Get("system.mtalog"));
$this->_parsePostfixLog(Settings::Get("system.mtalog") . ".1");
} elseif (Settings::Get("system.mtaserver") == "exim4") {
$this->_parseExim4Log(Settings::Get("system.mtalog"));
}
// Parse MDA traffic
if (Settings::Get("system.mdaserver") == "dovecot") {
$this->_parseDovecotLog(Settings::Get("system.mdalog"));
$this->_parsePostfixLog(Settings::Get("system.mdalog") . ".1");
} elseif (Settings::Get("system.mdaserver") == "courier") {
$this->_parseCourierLog(Settings::Get("system.mdalog"));
$this->_parsePostfixLog(Settings::Get("system.mdalog") . ".1");
}
}
/**
* parsePostfixLog
* parses the traffic from a postfix logfile
* @param logFile
*/
private function _parsePostfixLog($logFile) {
// Check if file exists
if (!file_exists($logFile)) {
return false;
}
// Open the log file
try {
$file_handle = fopen($logFile, "r");
if (!$file_handle) {
throw new Exception("Could not open the file!");
}
} catch (Exception $e) {
echo "Error (File: ".$e->getFile().", line ". $e->getLine()."): ".$e->getMessage();
return false;
}
while (!feof($file_handle)) {
unset($matches);
$line = fgets($file_handle);
$timestamp = $this->_getLogTimestamp($line);
if ($this->startTime < $timestamp) {
if (preg_match("/postfix\/qmgr.*(?::|\])\s([A-Z\d]+).*from=<?(?:.*\@([a-z\A-Z\d\.\-]+))?>?, size=(\d+),/", $line, $matches)) {
// Postfix from
$this->mails[$matches[1]] = array("domainFrom" => strtolower($matches[2]), "size" => $matches[3]);
} elseif (preg_match("/postfix\/(?:pipe|smtp).*(?::|\])\s([A-Z\d]+).*to=<?(?:.*\@([a-z\A-Z\d\.\-]+))?>?,/", $line, $matches)) {
// Postfix to
if (array_key_exists($matches[1], $this->mails)) {
$this->mails[$matches[1]]["domainTo"] = strtolower($matches[2]);
// Only mails from/to outside the system should be added
$mail = $this->mails[$matches[1]];
if (in_array($mail["domainFrom"], $this->myDomains) || in_array($mail["domainTo"], $this->myDomains)) {
// Outgoing traffic
if (array_key_exists("domainFrom", $mail)) {
$this->_addDomainTraffic($mail["domainFrom"], $mail["size"], $timestamp);
}
// Incoming traffic
if (array_key_exists("domainTo", $mail) && in_array($mail["domainTo"], $this->myDomains)) {
$this->_addDomainTraffic($mail["domainTo"], $mail["size"], $timestamp);
}
}
unset($mail);
}
}
}
}
fclose($file_handle);
return true;
}
/**
* parseExim4Log
* parses the smtp traffic from a exim4 logfile
* @param logFile
*/
private function _parseExim4Log($logFile) {
// Check if file exists
if (!file_exists($logFile)) {
return false;
}
// Open the log file
try {
$file_handle = fopen($logFile, "r");
if (!$file_handle) {
throw new Exception("Could not open the file!");
}
} catch (Exception $e) {
echo "Error (File: ".$e->getFile().", line ". $e->getLine()."): ".$e->getMessage();
return false;
}
while (!feof($file_handle)) {
unset($matches);
$line = fgets($file_handle);
$timestamp = $this->_getLogTimestamp($line);
if ($this->startTime < $timestamp) {
if (preg_match("/<= .*@([a-z0-9.\-]+) .*S=(\d+)/i", $line, $matches)) {
// Outgoing traffic
$this->_addDomainTraffic($matches[1], $matches[2], $timestamp);
} elseif (preg_match("/=> .*<?.*@([a-z0-9.\-]+)>? .*S=(\d+)/i" , $line, $matches)) {
// Incoming traffic
$this->_addDomainTraffic($matches[1], $matches[2], $timestamp);
}
}
}
fclose($file_handle);
return true;
}
/**
* parseDovecotLog
* parses the dovecot imap/pop3 traffic from logfile
* @param logFile
*/
private function _parseDovecotLog($logFile) {
// Check if file exists
if (!file_exists($logFile)) {
return false;
}
// Open the log file
try {
$file_handle = fopen($logFile, "r");
if (!$file_handle) {
throw new Exception("Could not open the file!");
}
} catch (Exception $e) {
echo "Error (File: ".$e->getFile().", line ". $e->getLine()."): ".$e->getMessage();
return false;
}
while (!feof($file_handle)) {
unset($matches);
$line = fgets($file_handle);
$timestamp = $this->_getLogTimestamp($line);
if ($this->startTime < $timestamp) {
if (preg_match("/dovecot.*(?::|\]) imap\(.*@([a-z0-9\.\-]+)\):.*(?:in=(\d+) out=(\d+)|bytes=(\d+)\/(\d+))/i", $line, $matches)) {
// Dovecot IMAP
$this->_addDomainTraffic($matches[1], (int)$matches[2] + (int)$matches[3], $timestamp);
} elseif (preg_match("/dovecot.*(?::|\]) pop3\(.*@([a-z0-9\.\-]+)\):.*in=(\d+).*out=(\d+)/i", $line, $matches)) {
// Dovecot POP3
$this->_addDomainTraffic($matches[1], (int)$matches[2] + (int)$matches[3], $timestamp);
}
}
}
fclose($file_handle);
return true;
}
/**
* parseCourierLog
* parses the dovecot imap/pop3 traffic from logfile
* @param logFile
*/
private function _parseCourierLog($logFile) {
// Check if file exists
if (!file_exists($logFile)) {
return false;
}
// Open the log file
try {
$file_handle = fopen($logFile, "r");
if (!$file_handle) {
throw new Exception("Could not open the file!");
}
} catch (Exception $e) {
echo "Error (File: ".$e->getFile().", line ". $e->getLine()."): ".$e->getMessage();
return false;
}
while (!feof($file_handle)) {
unset($matches);
$line = fgets($file_handle);
$timestamp = $this->_getLogTimestamp($line);
if ($this->startTime < $timestamp) {
if (preg_match("/(?:imapd|pop3d)(?:-ssl)?.*(?::|\]).*user=.*@([a-z0-9\.\-]+),.*rcvd=(\d+), sent=(\d+),/i", $line, $matches)) {
// Courier IMAP & POP3
$this->_addDomainTraffic($matches[1], (int)$matches[2] + (int)$matches[3], $timestamp);
}
}
}
fclose($file_handle);
return true;
}
/**
* _addDomainTraffic
* adds the traffic to the domain array if we own the domain
* @param string domain
* @param int traffic
*/
private function _addDomainTraffic($domain, $traffic, $timestamp) {
$date = date("Y-m-d", $timestamp);
if (in_array($domain, $this->myDomains)) {
if (array_key_exists($domain, $this->domainTraffic) && array_key_exists($date, $this->domainTraffic[$domain])) {
$this->domainTraffic[$domain][$date] += (int)$traffic;
} else {
if (!array_key_exists($domain, $this->domainTraffic)) {
$this->domainTraffic[$domain] = array();
}
$this->domainTraffic[$domain][$date] = (int)$traffic;
}
}
}
/**
* getLogTimestamp
* @param string line
* return int
*/
private function _getLogTimestamp($line) {
if (preg_match("/((?:[A-Z]{3}\s{1,2}\d{1,2}|\d{4}-\d{2}-\d{2}) \d{2}:\d{2}:\d{2})/i", $line, $matches)) {
$timestamp = strtotime($matches[1]);
if ($timestamp > ($this->startTime + 60 * 60 * 24)) {
return strtotime($matches[1] . " -1 year");
} else {
return strtotime($matches[1]);
}
} else {
return 0;
}
}
/**
* getDomainTraffic
* returns the traffic of a given domain or 0 if the domain has no traffic
* @param string domain
* return array
*/
public function getDomainTraffic($domain) {
if (array_key_exists($domain, $this->domainTraffic)) {
return $this->domainTraffic[$domain];
} else {
return 0;
}
}
}