From e9421f02bd450ec1ccbf20f777098d3ebc9b2d35 Mon Sep 17 00:00:00 2001 From: Samuel Vandamme Date: Wed, 2 Sep 2015 09:33:09 +0200 Subject: [PATCH] Magento version 0.6.0 --- .../community/CoScale/Monitor/Helper/Data.php | 7 +- .../CoScale/Monitor/Model/Cronjob.php | 23 + .../community/CoScale/Monitor/Model/Event.php | 484 +++++++++--------- .../CoScale/Monitor/Model/Event/Reindex.php | 57 ++- .../CoScale/Monitor/Model/Event/Store.php | 121 ++--- .../CoScale/Monitor/Model/Metric.php | 239 ++++----- .../CoScale/Monitor/Model/Metric/Abstract.php | 87 ++++ .../CoScale/Monitor/Model/Metric/Customer.php | 126 ++++- .../CoScale/Monitor/Model/Metric/File.php | 56 ++ .../CoScale/Monitor/Model/Metric/Order.php | 412 ++++++++++++--- .../CoScale/Monitor/Model/Metric/Product.php | 194 +++++++ .../CoScale/Monitor/Model/Metric/Rewrite.php | 37 ++ .../CoScale/Monitor/Model/Resource/Event.php | 60 +-- .../Model/Resource/Event/Collection.php | 9 +- .../CoScale/Monitor/Model/Resource/Metric.php | 61 +-- .../Model/Resource/Metric/Collection.php | 9 +- .../community/CoScale/Monitor/etc/config.xml | 47 +- .../coscale_monitor_setup/install-0.1.0.php | 300 +++++------ .../upgrade-0.1.0-0.2.0.php | 2 +- .../upgrade-0.2.0-0.3.0.php | 2 +- .../upgrade-0.3.0-0.4.0.php | 2 +- .../upgrade-0.4.0-0.5.0.php | 24 + shell/coscale.php | 127 +++-- 23 files changed, 1678 insertions(+), 808 deletions(-) create mode 100644 app/code/community/CoScale/Monitor/Model/Cronjob.php create mode 100644 app/code/community/CoScale/Monitor/Model/Metric/Abstract.php create mode 100644 app/code/community/CoScale/Monitor/Model/Metric/File.php create mode 100644 app/code/community/CoScale/Monitor/Model/Metric/Product.php create mode 100644 app/code/community/CoScale/Monitor/Model/Metric/Rewrite.php create mode 100644 app/code/community/CoScale/Monitor/sql/coscale_monitor_setup/upgrade-0.4.0-0.5.0.php diff --git a/app/code/community/CoScale/Monitor/Helper/Data.php b/app/code/community/CoScale/Monitor/Helper/Data.php index 43e2d36..26aa927 100644 --- a/app/code/community/CoScale/Monitor/Helper/Data.php +++ b/app/code/community/CoScale/Monitor/Helper/Data.php @@ -1,4 +1,5 @@ * @created 2015-07-03 * @version 1.0 - */ + */ class CoScale_Monitor_Helper_Data extends Mage_Core_Helper_Abstract -{} \ No newline at end of file +{ + +} \ No newline at end of file diff --git a/app/code/community/CoScale/Monitor/Model/Cronjob.php b/app/code/community/CoScale/Monitor/Model/Cronjob.php new file mode 100644 index 0000000..6779314 --- /dev/null +++ b/app/code/community/CoScale/Monitor/Model/Cronjob.php @@ -0,0 +1,23 @@ + + * @version 1.0 + * @created 2015-08-18 + */ + +class CoScale_Monitor_Model_Cronjob +{ + /** + * Daily cronjob to update daily values + */ + + public function dailyCron() + { + // Customer metric data + Mage::getSingleton('coscale_monitor/metric_customer')->dailyCron(); + Mage::getSingleton('coscale_monitor/metric_product')->dailyCron(); + } +} \ No newline at end of file diff --git a/app/code/community/CoScale/Monitor/Model/Event.php b/app/code/community/CoScale/Monitor/Model/Event.php index 901fb91..10a10e6 100644 --- a/app/code/community/CoScale/Monitor/Model/Event.php +++ b/app/code/community/CoScale/Monitor/Model/Event.php @@ -1,4 +1,5 @@ _init('coscale_monitor/event'); } - /** - * Make sure the version is always an integer, even when it's null - * - * @return int - */ - public function getVersion() - { - if (is_null($this->getData('version'))) { - return 0; - } - - return $this->getData('version'); - } - - /** - * Return the event data as an array, rather than the json string - * - * @return array - */ - public function getEventData() - { - return json_decode($this->getData('event_data'), true); - } - - /** - * Set the state for an event - * - * @param int $state Set the state to one of the predefined states in the system - * - * @return $this - * @throws Exception - */ - public function setState($state) - { - if ( ! in_array($state, array(self::STATE_DISABLED, self::STATE_ENABLED, self::STATE_INACTIVE))) { - throw new Exception('State must be one of the predefined state levels.'); - } - - return $this->setData('state', $state); - } - - /** - * Set the event type - * - * @param string $type Set the type of the event to one of the predefined types - * - * @return $this - * - * @throws Exception - */ - public function setType($type) - { - if ( ! in_array($type, $this->getTypes())) { - throw new Exception('Only predefined types can be used.'); - } - - return $this->setData('type', $type); - } - - /** - * Store the event data as a json string rather than a raw array - * - * @param array $data An array of data to expose to CoScale - * - * @return $this - */ - public function setEventData(array $data) - { - return $this->setData('event_data', json_encode($data)); - } - - /** - * Shorthand for adding new events - * - * @param string $type The event type as predefined in this model - * @param string $name Short name for the event - * @param string $description Description of the event - * @param array $data An array of data to expose to CoScale - * @param string $source The causer of the event, logged in user, etc - * @param int $state The state of the event - * - * @return $this - */ - public function addEvent($type, $name, $description, array $data, $source, $state = null) - { - $this->setType($type) - ->setName($name) - ->setDescription($description) - ->setEventData($data) - ->setDuration(0) - ->setTimestampStart(time()) - ->setSource($source) - ->setState($state); - - // By default we're assuming events don't do much and we're simply logging them - // if an event takes longer, the enabled state needs to be defined in the call - if (is_null($state)) { - $this->setState(self::STATE_INACTIVE) - ->setTimestampEnd(time()); - } - - $this->save(); - - return $this; - } - - /** - * Shorthand to update an event - * - * @param string $type The predefined type to load the event by - * @param int $state The state of the event - * @param string $source Source of the event, who triggered it - * @param array $data Event data to store - * - * @throws Exception - */ - public function updateEvent($type, $state, $source = null, array $data = array()) - { - $this->loadLastByType($type); - $this->setTimestampEnd(time()) - ->setState($state); - - if ( ! is_null($source)) { - $this->setSource($source); - } - - if ( ! is_null($data)) { - $this->setEventData($data); - } - - $this->save(); - } - - /** - * Load an event by it's type - * - * @param string $type The predefined type to load the event by - * - * @return $this - * - * @throws Exception - */ - public function loadLastByType($type) - { - if ( ! in_array($type, $this->getTypes())) { - throw new Exception('Type should be one of the predefined keys'); - } - - $this->_getResource()->loadByType($this, $type); - return $this; - } - - /** - * Type groups for the reporting and grouping of types - * - * @return string - */ - public function getTypeGroup() - { - switch($this->getType()) { - case self::TYPE_STORE_ADD: - case self::TYPE_FLUSH_PAGE_CACHE: - case self::TYPE_FLUSH_ASSET_CACHE: - case self::TYPE_FLUSH_IMAGE_CACHE: - case self::TYPE_REINDEX: - return self::GROUP_ADMIN; - } - } - - /** - * Set some defaults before saving an event to the database - * - * @return $this - */ - protected function _beforeSave() - { - $date = Mage::getModel('core/date'); - - $this->setUpdatedAt($date->date()) - ->setVersion($this->getVersion()+1); - - return $this; - } - - /** - * Retrieve the available types as an array - * - * @return array - */ - protected function getTypes() - { - return array(self::TYPE_REINDEX, self::TYPE_STORE_ADD, - self::TYPE_FLUSH_ASSET_CACHE, self::TYPE_FLUSH_IMAGE_CACHE, - self::TYPE_FLUSH_PAGE_CACHE); - } + /** + * Make sure the version is always an integer, even when it's null + * + * @return int + */ + public function getVersion() + { + if (is_null($this->getData('version'))) { + return 0; + } + + return $this->getData('version'); + } + + /** + * Return the event data as an array, rather than the json string + * + * @return array + */ + public function getEventData() + { + return json_decode($this->getData('event_data'), true); + } + + /** + * Set the state for an event + * + * @param int $state Set the state to one of the predefined states in the system + * + * @return $this + * @throws Exception + */ + public function setState($state) + { + if (!in_array($state, array(self::STATE_DISABLED, self::STATE_ENABLED, self::STATE_INACTIVE))) { + throw new Exception('State must be one of the predefined state levels.'); + } + + return $this->setData('state', $state); + } + + /** + * Set the event type + * + * @param string $type Set the type of the event to one of the predefined types + * + * @return $this + * + * @throws Exception + */ + public function setType($type) + { + if (!in_array($type, $this->getTypes())) { + throw new Exception('Only predefined types can be used.'); + } + + return $this->setData('type', $type); + } + + /** + * Store the event data as a json string rather than a raw array + * + * @param array $data An array of data to expose to CoScale + * + * @return $this + */ + public function setEventData(array $data) + { + return $this->setData('event_data', json_encode($data)); + } + + /** + * Shorthand for adding new events + * + * @param string $type The event type as predefined in this model + * @param string $name Short name for the event + * @param string $description Description of the event + * @param array $data An array of data to expose to CoScale + * @param string $source The causer of the event, logged in user, etc + * @param int $state The state of the event + * + * @return $this + */ + public function addEvent($type, $name, $description, array $data, $source, $state = null) + { + $this->setType($type) + ->setName($name) + ->setDescription($description) + ->setEventData($data) + ->setDuration(0) + ->setTimestampStart(time()) + ->setSource($source) + ->setState($state); + + // By default we're assuming events don't do much and we're simply logging them + // if an event takes longer, the enabled state needs to be defined in the call + if (is_null($state)) { + $this->setState(self::STATE_INACTIVE) + ->setTimestampEnd(time()); + } + + $this->save(); + + return $this; + } + + /** + * Shorthand to update an event + * + * @param string $type The predefined type to load the event by + * @param int $state The state of the event + * @param string $source Source of the event, who triggered it + * @param array $data Event data to store + * + * @throws Exception + */ + public function updateEvent($type, $state, $source = null, array $data = array()) + { + $this->loadLastByType($type); + $this->setTimestampEnd(time()) + ->setState($state); + + if (!is_null($source)) { + $this->setSource($source); + } + + if (!is_null($data)) { + $this->setEventData($data); + } + + $this->save(); + } + + /** + * Load an event by it's type + * + * @param string $type The predefined type to load the event by + * + * @return $this + * + * @throws Exception + */ + public function loadLastByType($type) + { + if (!in_array($type, $this->getTypes())) { + throw new Exception('Type should be one of the predefined keys'); + } + + $this->_getResource()->loadByType($this, $type); + return $this; + } + + /** + * Type groups for the reporting and grouping of types + * + * @return string + */ + public function getTypeGroup() + { + switch ($this->getType()) { + case self::TYPE_STORE_ADD: + case self::TYPE_FLUSH_PAGE_CACHE: + case self::TYPE_FLUSH_ASSET_CACHE: + case self::TYPE_FLUSH_IMAGE_CACHE: + case self::TYPE_REINDEX: + return self::GROUP_ADMIN; + } + } + + /** + * Set some defaults before saving an event to the database + * + * @return $this + */ + protected function _beforeSave() + { + $date = Mage::getModel('core/date'); + + $this->setUpdatedAt($date->date()) + ->setVersion($this->getVersion() + 1); + + return $this; + } + + /** + * Retrieve the available types as an array + * + * @return array + */ + protected function getTypes() + { + return array(self::TYPE_REINDEX, self::TYPE_STORE_ADD, + self::TYPE_FLUSH_ASSET_CACHE, self::TYPE_FLUSH_IMAGE_CACHE, + self::TYPE_FLUSH_PAGE_CACHE); + } } \ No newline at end of file diff --git a/app/code/community/CoScale/Monitor/Model/Event/Reindex.php b/app/code/community/CoScale/Monitor/Model/Event/Reindex.php index b8b7169..84c202b 100644 --- a/app/code/community/CoScale/Monitor/Model/Event/Reindex.php +++ b/app/code/community/CoScale/Monitor/Model/Event/Reindex.php @@ -1,4 +1,5 @@ addEvent($coscale::TYPE_REINDEX, - 'Reindexing', - 'Reindexing the indexes!', - array(), - Mage::getSingleton('admin/session')->getUser()->getUsername(), - $coscale::STATE_ENABLED); - } + /** + * Trigger adding an event at the start of the reindexing process + * + * @param Varien_Event_Observer $event + */ + public function startIndex(Varien_Event_Observer $event) + { + /** @var CoScale_Monitor_Model_Event $coscale */ + $coscale = Mage::getModel('coscale_monitor/event'); + $coscale->addEvent( + $coscale::TYPE_REINDEX, + 'Reindexing', + 'Reindexing the indexes!', + array(), + Mage::getSingleton('admin/session')->getUser()->getUsername(), + $coscale::STATE_ENABLED + ); + } - /** - * Trigger ending an event at the end of the reindexing process - * - * @param Varien_Event_Observer $event - */ - public function endIndex(Varien_Event_Observer $event) - { - /** @var CoScale_Monitor_Model_Event $coscale */ - $coscale = Mage::getModel('coscale_monitor/event'); - $coscale->updateEvent($coscale::TYPE_REINDEX, $coscale::STATE_INACTIVE); - } + /** + * Trigger ending an event at the end of the reindexing process + * + * @param Varien_Event_Observer $event + */ + public function endIndex(Varien_Event_Observer $event) + { + /** @var CoScale_Monitor_Model_Event $coscale */ + $coscale = Mage::getModel('coscale_monitor/event'); + $coscale->updateEvent($coscale::TYPE_REINDEX, $coscale::STATE_INACTIVE); + } } \ No newline at end of file diff --git a/app/code/community/CoScale/Monitor/Model/Event/Store.php b/app/code/community/CoScale/Monitor/Model/Event/Store.php index ba53d08..5fe62b6 100644 --- a/app/code/community/CoScale/Monitor/Model/Event/Store.php +++ b/app/code/community/CoScale/Monitor/Model/Event/Store.php @@ -1,4 +1,5 @@ getStore(); + /** + * Track the adding of a new store + * + * @param Varien_Event_Observer $event + */ + public function addNew(Varien_Event_Observer $event) + { + /** @var Mage_Core_Model_Store $store */ + $store = $event->getStore(); - $event = Mage::getModel('coscale_monitor/event'); - $event->addEvent($event::TYPE_STORE_ADD, - 'Store added', - 'A new store was added', - array('id' => $store->getId(), - 'name' => $store->getName(), - 'code' => $store->getCode(), - 'website' => $store->getWebsiteId() - ), - Mage::getSingleton('admin/session')->getUser()->getUsername() - ); + $event = Mage::getModel('coscale_monitor/event'); + $event->addEvent( + $event::TYPE_STORE_ADD, + 'Store added', + 'A new store was added', + array( + 'id' => $store->getId(), + 'name' => $store->getName(), + 'code' => $store->getCode(), + 'website' => $store->getWebsiteId() + ), + Mage::getSingleton('admin/session')->getUser()->getUsername() + ); - $customertotal = Mage::getModel('coscale_monitor/metric'); - $customertotal->incrementMetric( - $customertotal::KEY_CUSTOMER_TOTAL, - $store->getId(), - $customertotal::TYPE_APPLICATION, - 'Total customers', - 'The total number of customers in the system', - 0, - 'customers'); + $customertotal = Mage::getModel('coscale_monitor/metric'); + $customertotal->incrementMetric( + $customertotal::KEY_CUSTOMER_TOTAL, + $store->getId(), + $customertotal::TYPE_APPLICATION, + 'Total customers', + 'The total number of customers in the system', + 0, + 'customers' + ); - $orderAverageSize = Mage::getModel('coscale_monitor/metric'); - $orderAverageSize->incrementMetric( - $orderAverageSize::KEY_ORDER_SIZE_AVERAGE, - $store->getId(), - $orderAverageSize::TYPE_APPLICATION, - 'Order size average', - 'The average size of an order in the system for this store', - 0, - 'orders'); + $orderAverageSize = Mage::getModel('coscale_monitor/metric'); + $orderAverageSize->incrementMetric( + $orderAverageSize::KEY_ORDER_SIZE_AVERAGE, + $store->getId(), + $orderAverageSize::TYPE_APPLICATION, + 'Order size average', + 'The average size of an order in the system for this store', + 0, + 'orders' + ); - $orderAverageAmount = Mage::getModel('coscale_monitor/metric'); - $orderAverageAmount->incrementMetric( - $orderAverageAmount::KEY_ORDER_AMOUNT_AVERAGE, - $store->getId(), - $orderAverageAmount::TYPE_APPLICATION, - 'Order amount average', - 'The average amount of an order in the system for this store', - 0, - '$'); + $orderAverageAmount = Mage::getModel('coscale_monitor/metric'); + $orderAverageAmount->incrementMetric( + $orderAverageAmount::KEY_ORDER_AMOUNT_AVERAGE, + $store->getId(), + $orderAverageAmount::TYPE_APPLICATION, + 'Order amount average', + 'The average amount of an order in the system for this store', + 0, + '€' + ); - $orderTotal = Mage::getModel('coscale_monitor/metric'); - $orderTotal->incrementMetric( - $orderTotal::KEY_ORDER_TOTAL, - $store->getId(), - $orderTotal::TYPE_APPLICATION, - 'Total orders', - 'The total number of orders in the system for this store', - 0, - 'orders'); - } + $orderTotal = Mage::getModel('coscale_monitor/metric'); + $orderTotal->incrementMetric( + $orderTotal::KEY_ORDER_TOTAL, + $store->getId(), + $orderTotal::TYPE_APPLICATION, + 'Total orders', + 'The total number of orders in the system for this store', + 0, + 'orders' + ); + } } diff --git a/app/code/community/CoScale/Monitor/Model/Metric.php b/app/code/community/CoScale/Monitor/Model/Metric.php index d52d8f3..5d0cefe 100644 --- a/app/code/community/CoScale/Monitor/Model/Metric.php +++ b/app/code/community/CoScale/Monitor/Model/Metric.php @@ -1,4 +1,5 @@ _init('coscale_monitor/metric'); } - /** - * Shorthand to add or update a metric to the system - * - * @param int $key A key as predefined in this model - * @param int $store The store id - * @param int $type A predefined type for the metric - * @param string $name The name of the metric - * @param string $description A longer description of the metric - * @param mixed $value The value to set - * @param string $unit The unit the value is saved in - * - * @throws Exception - */ - public function updateMetric($key, $store, $type, $name, $description, $value, $unit) - { - $this->loadByKey($key, $store); - - $this->setKey($key) - ->setStoreId($store) - ->setType($type) - ->setName($name) - ->setDescription($description) - ->setValue($value) - ->setUnit($unit); - - $this->save(); - } - - /** - * Shorthand to add or increment a numerical metric in the system - * - * @param int $key A key as predefined in this model - * @param int $store The store the metric belongs to - * @param string $type A predefined type for the metric - * @param string $name The name of the metric - * @param string $description A longer description of the metric - * @param mixed $value The value to set - * @param string $unit The unit the value is saved in - */ - public function incrementMetric($key, $store, $type, $name, $description, $value, $unit) - { - $this->loadByKey($key, $store); + /** + * Shorthand to add or update a metric to the system + * + * @param int $key A key as predefined in this model + * @param int $store The store id + * @param int $type A predefined type for the metric + * @param string $name The name of the metric + * @param string $description A longer description of the metric + * @param mixed $value The value to set + * @param string $unit The unit the value is saved in + * + * @throws Exception + */ + public function updateMetric($key, $store, $type, $name, $description, $value, $unit) + { + $this->loadByKey($key, $store); - $this->updateMetric($key, $store, $type, $name, $description, ($this->getValue()+$value), $unit); - } + $this->setKey($key) + ->setStoreId($store) + ->setType($type) + ->setName($name) + ->setDescription($description) + ->setValue($value) + ->setUnit($unit); - /** - * Return the textual version of the metric type - * - * @return string - */ - public function getTypeText() - { - switch($this->getType()) { - case self::TYPE_SERVER: - return 'S'; - break; - case self::TYPE_APPLICATION: - return 'A'; - break; + $this->save(); + } - } - } + /** + * Shorthand to add or increment a numerical metric in the system + * + * @param int $key A key as predefined in this model + * @param int $store The store the metric belongs to + * @param string $type A predefined type for the metric + * @param string $name The name of the metric + * @param string $description A longer description of the metric + * @param mixed $value The value to set + * @param string $unit The unit the value is saved in + */ + public function incrementMetric($key, $store, $type, $name, $description, $value, $unit) + { + $this->loadByKey($key, $store); - /** - * Load a metric by it's key - * - * @param int $key The predefined key to load the metric from - * @param int $store The store to load the metric for - * - * @return $this - * - * @throws Exception - */ - public function loadByKey($key, $store) - { - if ( ! in_array($key, $this->getMetrics())) { - throw new Exception('Key should be one of the predefined keys'); - } + $this->updateMetric($key, $store, $type, $name, $description, ($this->getValue() + $value), $unit); + } - $this->_getResource()->loadByKey($this, $key, $store); - return $this; - } + /** + * Return the textual version of the metric type + * + * @return string + */ + public function getTypeText() + { + switch ($this->getType()) { + case self::TYPE_SERVER: + return 'S'; + break; + case self::TYPE_APPLICATION: + return 'A'; + break; + + } + } - /** - * Return an array of the available metrics - * - * @return array - */ - protected function getMetrics() - { - return array(self::KEY_ORDER_TOTAL, - self::KEY_ORDER_AMOUNT_AVERAGE, - self::KEY_ORDER_SIZE_AVERAGE, - self::KEY_CUSTOMER_TOTAL); - } + /** + * Load a metric by it's key + * + * @param int $key The predefined key to load the metric from + * @param int $store The store to load the metric for + * + * @return $this + * + * @throws Exception + */ + public function loadByKey($key, $store) + { + $this->_getResource()->loadByKey($this, $key, $store); + return $this; + } - /** - * Set some defaults before saving an event to the database - * - * @return $this - */ - protected function _beforeSave() - { - $date = Mage::getModel('core/date'); + /** + * Set some defaults before saving an event to the database + * + * @return $this + */ + protected function _beforeSave() + { + $date = Mage::getModel('core/date'); - $this->setTimestamp($date->timestamp()) - ->setUpdatedAt($date->date()); + $this->setTimestamp($date->timestamp()) + ->setUpdatedAt($date->date()); - return $this; - } + return $this; + } } \ No newline at end of file diff --git a/app/code/community/CoScale/Monitor/Model/Metric/Abstract.php b/app/code/community/CoScale/Monitor/Model/Metric/Abstract.php new file mode 100644 index 0000000..bd3a840 --- /dev/null +++ b/app/code/community/CoScale/Monitor/Model/Metric/Abstract.php @@ -0,0 +1,87 @@ + + * @version 1.0 + * @created 2015-08-18 + */ +class CoScale_Monitor_Model_Metric_Abstract +{ + protected $_metric = false; + protected $_metricData = array(); + + protected $_metricType = CoScale_Monitor_Model_Metric::TYPE_APPLICATION; + + const ACTION_UPDATE = 1; + const ACTION_INCREMENT=2; + + public function __construct() + { + $this->_metric = Mage::getModel('coscale_monitor/metric'); + $this->_contruct(); + } + + /** + * Public contructor + */ + public function _contruct() + { + + } + + /** + * Shorthand to add/update or increment a metric to the system + * + * @param int $action Specify action + * @param int $key A key as predefined in this model + * @param int $store The store id + * @param int|bool $type A predefined type for the metric + * @param string|bool $name The name of the metric + * @param string|bool $descr A longer description of the metric + * @param mixed $value The value to set + * @param string|bool $unit The unit the value is saved in + * + * @throws Exception + */ + protected function setMetric($action, $key, $store, $value, $type = false, $name = false, $descr = false, $unit = false) + { + if (!$type) { + $type = $this->_metricType; + } + + if (!$name && isset($this->_metricData[$key]['name'])) { + $name = $this->_metricData[$key]['name']; + } + + if (!$descr && isset($this->_metricData[$key]['description'])) { + $descr = $this->_metricData[$key]['description']; + } + + if (!$unit && isset($this->_metricData[$key]['unit'])) { + $unit = $this->_metricData[$key]['unit']; + } + + if (!$name || !$descr || !$unit) { + throw new Exception('Invalid metric data supplied'); + } + + if ($action == self::ACTION_UPDATE) { + $this->_metric->updateMetric($key, $store, $type, $name, $descr, $value, $unit); + } else { + $this->_metric->incrementMetric($key, $store, $type, $name, $descr, $value, $unit); + } + } + + protected function getMetric($key, $store) + { + $data = $this->_metric->loadByKey($key, $store); + + if (!$data->getId()) { + return 0; + } + return $data->getValue(); + } + +} \ No newline at end of file diff --git a/app/code/community/CoScale/Monitor/Model/Metric/Customer.php b/app/code/community/CoScale/Monitor/Model/Metric/Customer.php index ab876a4..0c7599c 100644 --- a/app/code/community/CoScale/Monitor/Model/Metric/Customer.php +++ b/app/code/community/CoScale/Monitor/Model/Metric/Customer.php @@ -8,26 +8,110 @@ * @version 1.0 * @created 2015-07-03 */ -class CoScale_Monitor_Model_Metric_Customer +class CoScale_Monitor_Model_Metric_Customer extends CoScale_Monitor_Model_Metric_Abstract { - /** - * Observe the adding of new customers to the system - * - * @param Varien_Event_Observer $observer - */ - public function addNew(Varien_Event_Observer $observer) - { - /** @var Mage_Customer_Model_Customer $customer */ - $customer = $observer->getEvent()->getCustomer(); - - $metric = Mage::getModel('coscale_monitor/metric'); - $metric->incrementMetric( - $metric::KEY_CUSTOMER_TOTAL, - $customer->getStore()->getId(), - $metric::TYPE_APPLICATION, - 'Total customers', - 'The total number of customers in the system', - 1, - 'customers'); - } + /** + * Identifier for the total number of customers in the system + */ + const KEY_CUSTOMER_TOTAL = 1000; + /** + * Identifier for the total number of customers in the system + */ + const KEY_CUSTOMER_TODAY = 1001; + + /** + * Public contructor function + */ + public function _contruct() + { + $this->_metricData[self::KEY_CUSTOMER_TOTAL] = array( + 'name' => 'Total customers', + 'description' => 'The total number of customers in the system', + 'unit' => 'customers' + ); + + $this->_metricData[self::KEY_CUSTOMER_TODAY] = array( + 'name' => 'New customers today', + 'description' => 'The total number of customers created today', + 'unit' => 'customers' + ); + } + + /** + * Observe the adding of new customers to the system + * + * @param Varien_Event_Observer $observer + */ + public function addNew(Varien_Event_Observer $observer) + { + /** @var Mage_Customer_Model_Customer $customer */ + $customer = $observer->getEvent()->getCustomer(); + + if ($customer->getOrigData('entity_id') == $customer->getId()) { + return; + } + + $this->setMetric( + self::ACTION_INCREMENT, + self::KEY_CUSTOMER_TOTAL, + $customer->getStore()->getId(), + 1 + ); + + $this->setMetric( + self::ACTION_INCREMENT, + self::KEY_CUSTOMER_TODAY, + $customer->getStore()->getId(), + 1 + ); + } + + /** + * Cronjob to update the total number of customers + */ + public function dailyCron() + { + $this->resetDayCounter(); + $this->updateTotalCount(); + } + + /** + * Reset daily new created customer accounts counter per store + */ + protected function resetDayCounter() + { + foreach (Mage::app()->getStores(true) as $storeId => $store) { + $this->setMetric( + self::ACTION_UPDATE, + self::KEY_CUSTOMER_TODAY, + $storeId, + 0 + ); + } + } + + /** + * Daily update full numbers of customers + */ + public function updateTotalCount() + { + $collection = Mage::getResourceModel('customer/customer_collection'); + $collection->getSelect() + ->reset('columns') + ->columns(array('website_id' => 'e.website_id', + 'customer_count' => 'COUNT(*)')) + ->group('e.website_id'); + + foreach ($collection as $customer) { + $storeIds = Mage::app()->getWebsite($customer->getWebsiteId())->getStoreIds(); + foreach ($storeIds as $storeId) { + $this->setMetric( + self::ACTION_UPDATE, + self::KEY_CUSTOMER_TOTAL, + $storeId, + $customer->getCustomerCount() + ); + } + } + } } \ No newline at end of file diff --git a/app/code/community/CoScale/Monitor/Model/Metric/File.php b/app/code/community/CoScale/Monitor/Model/Metric/File.php new file mode 100644 index 0000000..ed66e30 --- /dev/null +++ b/app/code/community/CoScale/Monitor/Model/Metric/File.php @@ -0,0 +1,56 @@ + + * @version 1.0 + * @created 2015-08-18 + */ +class CoScale_Monitor_Model_Metric_File extends CoScale_Monitor_Model_Metric_Abstract +{ + + /** + * Get amount of reports in var/report + * @return array + */ + public function getErrorReports() + { + $dir = Mage::getBaseDir('var') . DS . 'report'; + + $contents = scandir($dir); + + return array( + 'name' => 'Files in var/report/', + 'unit' => 'files', + 'value' => (count($contents)-2), + 'store_id' => 0, + 'type' => 'S' + ); + } + + /** + * Get details of logfiles in var/log + * @return array + */ + public function getLogFiles() + { + $dir = Mage::getBaseDir('var') . DS . 'log'; + + $contents = scandir($dir); + $output = array(); + foreach ($contents as $logfile) { + if ($logfile == '.' || $logfile=='..') { + continue; + } + $output[] = array( + 'name' => 'Logfile var/log/' . $logfile, + 'unit' => 'bytes', + 'value' => filesize($dir . DS . $logfile), + 'store_id' => 0, + 'type' => 'S' + ); + } + return $output; + } +} \ No newline at end of file diff --git a/app/code/community/CoScale/Monitor/Model/Metric/Order.php b/app/code/community/CoScale/Monitor/Model/Metric/Order.php index 3cc8c22..630346e 100644 --- a/app/code/community/CoScale/Monitor/Model/Metric/Order.php +++ b/app/code/community/CoScale/Monitor/Model/Metric/Order.php @@ -8,65 +8,357 @@ * @version 1.0 * @created 2015-07-07 */ -class CoScale_Monitor_Model_Metric_Order +class CoScale_Monitor_Model_Metric_Order extends CoScale_Monitor_Model_Metric_Abstract { - /** - * Observe the adding of new orders to the system - * - * @param Varien_Event_Observer $observer - */ - public function addNew(Varien_Event_Observer $observer) - { - /** @var Mage_Sales_Model_Order $order */ - $order = $observer->getEvent()->getOrder(); - - // not too please about this bit, I'd rather we store the totals in the metric - // table as well and retrieve them if we need them, it's much cheaper to do it - // that way but I ran into an issue with the metrics table being a MEMORY table - // and not being able to depend on it for persistent storage and updates. - $orders = Mage::getResourceModel('sales/order_collection')->addAttributeToFilter('store_id', $order->getStoreId()); - - // adjust the collection query a bit, removing the existing columns from the select and adding our - // aggregate's in its place. - $orders->getSelect() - ->reset('columns') - ->columns(array('total' => 'SUM(main_table.base_grand_total)', - 'items' => 'SUM(main_table.total_item_count)', - 'orders' => 'COUNT(*)')); - - // make sure we got data back to work with and then update the metrics - $data = $orders->getData(); - if (is_array($data) && isset($data[0]) && isset($data[0]['total'])) { - - $orderAverageSize = Mage::getModel('coscale_monitor/metric'); - $orderAverageSize->updateMetric( - $orderAverageSize::KEY_ORDER_SIZE_AVERAGE, - $order->getStoreId(), - $orderAverageSize::TYPE_APPLICATION, - 'Order size average', - 'The average size of an order in the system for this store', - $data[0]['items'], - 'orders'); - - $orderAverageAmount = Mage::getModel('coscale_monitor/metric'); - $orderAverageAmount->updateMetric( - $orderAverageAmount::KEY_ORDER_AMOUNT_AVERAGE, - $order->getStoreId(), - $orderAverageAmount::TYPE_APPLICATION, - 'Order amount average', - 'The average amount of an order in the system for this store', - $data[0]['total'], - '€'); - - $orderTotal = Mage::getModel('coscale_monitor/metric'); - $orderTotal->updateMetric( - $orderTotal::KEY_ORDER_TOTAL, - $order->getStoreId(), - $orderTotal::TYPE_APPLICATION, - 'Total orders', - 'The total number of orders in the system for this store', - $data[0]['orders'], - 'orders'); - } - } + + /** + * Identifier for total orders + */ + const KEY_ORDER_TOTAL = 2000; + const KEY_ORDER_TOTAL_TODAY = 2001; + + /** + * Identifier for order amount average and total + */ + const KEY_ORDER_AMOUNT_AVERAGE = 2010; + const KEY_ORDER_SIZE_TOTAL = 2011; + + /** + * Identifier for order size average and total + */ + const KEY_ORDER_SIZE_AVERAGE = 2020; + const KEY_ORDER_AMOUNT_TOTAL = 2021; + + /** + * Identifier for order state processing/completed + */ + const KEY_ORDER_STATE_NEW = 2030; + const KEY_ORDER_STATE_PROCESSING = 2031; + const KEY_ORDER_STATE_COMPLETED = 2032; + + /** + * Public contructor function + */ + public function _contruct() + { + $this->_metricData[self::KEY_ORDER_SIZE_TOTAL] = array( + 'name' => 'Order size total', + 'description' => 'The total size of all order in the system for this store', + 'unit' => 'items' + ); + + $this->_metricData[self::KEY_ORDER_SIZE_AVERAGE] = array( + 'name' => 'Order size average', + 'description' => 'The average size of an order in the system for this store', + 'unit' => 'items' + ); + + $this->_metricData[self::KEY_ORDER_AMOUNT_TOTAL] = array( + 'name' => 'Order amount total', + 'description' => 'The total amount of an order in the system for this store', + 'unit' => 'Amount' + ); + + $this->_metricData[self::KEY_ORDER_AMOUNT_AVERAGE] = array( + 'name' => 'Order amount average', + 'description' => 'The average amount of an order in the system for this store', + 'unit' => 'Amount' + ); + + $this->_metricData[self::KEY_ORDER_TOTAL] = array( + 'name' => 'Total orders', + 'description' => 'The total number of orders in the system for this store', + 'unit' => 'orders' + ); + + $this->_metricData[self::KEY_ORDER_TOTAL_TODAY] = array( + 'name' => 'Total orders today', + 'description' => 'The total number of orders in the system for this store placed today', + 'unit' => 'orders' + ); + + $this->_metricData[self::KEY_ORDER_STATE_NEW] = array( + 'name' => 'Total orders new ', + 'description' => 'The total number of orders in new state', + 'unit' => 'orders' + ); + + $this->_metricData[self::KEY_ORDER_STATE_PROCESSING] = array( + 'name' => 'Total orders processing ', + 'description' => 'The total number of orders in processing state', + 'unit' => 'orders' + ); + + $this->_metricData[self::KEY_ORDER_STATE_COMPLETED] = array( + 'name' => 'Total orders completed', + 'description' => 'The total number of orders in completed state', + 'unit' => 'orders' + ); + + } + + /** + * Observe the adding of new orders to the system + * + * @param Varien_Event_Observer $observer + */ + public function addNew(Varien_Event_Observer $observer) + { + /** @var Mage_Sales_Model_Order $order */ + $order = $observer->getEvent()->getOrder(); + + $this->setMetric( + self::ACTION_INCREMENT, + self::KEY_ORDER_SIZE_TOTAL, + $order->getStoreId(), + $order->getTotalItemCount() + ); + + $this->setMetric( + self::ACTION_INCREMENT, + self::KEY_ORDER_AMOUNT_TOTAL, + $order->getStoreId(), + $order->getBaseGrandTotal() + ); + + $this->setMetric( + self::ACTION_INCREMENT, + self::KEY_ORDER_TOTAL, + $order->getStoreId(), + 1 + ); + + $this->setMetric( + self::ACTION_INCREMENT, + self::KEY_ORDER_TOTAL_TODAY, + $order->getStoreId(), + 1 + ); + + // Update state statistics (only is changed) + if ($order->getState() != $order->getOrigData('state')) { + // Decrease order processing when previous state was processing + if ($order->getOrigData('state') == 'new') { + $this->setMetric( + self::ACTION_INCREMENT, + self::KEY_ORDER_STATE_NEW, + $order->getStoreId(), + -1 + ); + } + // Decrease order processing when previous state was processing + if ($order->getOrigData('state') == 'processing') { + $this->setMetric( + self::ACTION_INCREMENT, + self::KEY_ORDER_STATE_PROCESSING, + $order->getStoreId(), + -1 + ); + } + + // Increase orders with the state new + if ($order->getState() == 'new') { + $this->setMetric( + self::ACTION_INCREMENT, + self::KEY_ORDER_STATE_NEW, + $order->getStoreId(), + 1 + ); + } + // Increase orders with the state processing + if ($order->getState() == 'processing') { + $this->setMetric( + self::ACTION_INCREMENT, + self::KEY_ORDER_STATE_PROCESSING, + $order->getStoreId(), + 1 + ); + } + // Increase orders with the state complete + if ($order->getState() == 'complete') { + $this->setMetric( + self::ACTION_INCREMENT, + self::KEY_ORDER_STATE_COMPLETED, + $order->getStoreId(), + 1 + ); + } + } + + $this->updateAvgOrderValues($order->getStoreId()); + } + + /** + * Update Avarage values for order details + * + * @param $storeId + */ + public function updateAvgOrderValues($storeId) + { + $orderTotal = $this->getMetric(self::KEY_ORDER_TOTAL, $storeId); + $orderItems = $this->getMetric(self::KEY_ORDER_SIZE_TOTAL, $storeId); + $orderAmount = $this->getMetric(self::KEY_ORDER_AMOUNT_TOTAL, $storeId); + + + $this->setMetric( + self::ACTION_UPDATE, + self::KEY_ORDER_SIZE_AVERAGE, + $storeId, + ($orderItems/$orderTotal) + ); + + $this->setMetric( + self::ACTION_UPDATE, + self::KEY_ORDER_AMOUNT_AVERAGE, + $storeId, + ($orderAmount/$orderTotal) + ); + } + + + public function initOrderData() + { + $collection = Mage::getResourceModel('sales/order_collection'); + $collection->getSelect() + ->reset('columns') + ->columns(array('amount' => 'SUM(main_table.base_grand_total)', + 'items' => 'SUM(main_table.total_item_count)', + 'store_id' => 'main_table.store_id', + 'state' => 'main_table.state', + 'count' => 'COUNT(*)')) + ->group(array('main_table.store_id','main_table.state')); + + $data = array(); + foreach ($collection as $order) { + if (!$order->getStoreId()) { + continue; + } + if (!isset($data[$order->getStoreId()])) { + $data[$order->getStoreId()] = array( + 'items' => 0, + 'amount' => 0, + 'count' => 0, + 'new' => 0, + 'processing' => 0, + 'complete' => 0 + ); + } + $data[$order->getStoreId()]['items'] += $order->getItems(); + $data[$order->getStoreId()]['amount'] += $order->getAmount(); + $data[$order->getStoreId()]['count'] += $order->getCount(); + if ($order->getState() == 'new') { + $data[$order->getStoreId()]['new'] += $order->getCount(); + } + + if ($order->getState() == 'processing') { + $data[$order->getStoreId()]['processing'] += $order->getCount(); + } + + if ($order->getState() == 'complete') { + $data[$order->getStoreId()]['complete'] += $order->getCount(); + } + } + + foreach ($data as $storeId => $details) { + $this->setMetric( + self::ACTION_UPDATE, + self::KEY_ORDER_SIZE_TOTAL, + $storeId, + $details['items'] + ); + + $this->setMetric( + self::ACTION_UPDATE, + self::KEY_ORDER_AMOUNT_TOTAL, + $storeId, + $details['amount'] + ); + + $this->setMetric( + self::ACTION_UPDATE, + self::KEY_ORDER_TOTAL, + $storeId, + $details['count'] + ); + + $this->setMetric( + self::ACTION_UPDATE, + self::KEY_ORDER_STATE_NEW, + $storeId, + $details['new'] + ); + + $this->setMetric( + self::ACTION_UPDATE, + self::KEY_ORDER_STATE_PROCESSING, + $storeId, + $details['processing'] + ); + + $this->setMetric( + self::ACTION_UPDATE, + self::KEY_ORDER_STATE_COMPLETED, + $storeId, + $details['complete'] + ); + + $this->updateAvgOrderValues($storeId); + } + } + + /** + * Get Abandonned cart amounts + * @return array + */ + public function getAbandonnedCarts() + { + /** @var $collection Mage_Reports_Model_Resource_Quote_Collection */ + $collection = Mage::getResourceModel('reports/quote_collection'); + $collection->prepareForAbandonedReport(array()); + $collection->getSelect() + ->columns(array('store_id' => 'main_table.store_id', + 'count' => 'COUNT(*)')) + ->group('main_table.store_id'); + $output = array(); + foreach ($collection as $order) { + $output[] = array( + 'name' => 'Abandonned carts', + 'unit' => 'orders', + 'value' => (float)$order->getCount(), + 'store_id' => (int)$order->getStoreId(), + 'type' => 'A' + ); + } + return $output; + } + + public function getEmailQueueSize() + { + $edition = method_exists('Mage', 'getEdition') ? Mage::getEdition():false; + + // Pre CE1.7 version => No e-mail queue available + if (!$edition) { + return array(); + } + + // Pre CE 1.9 version => No e-mail queue available + if ($edition == 'Community' && version_compare(Mage::getVersion(), '1.9', '<')) { + return array(); + } + + // Pre EE 1.14 version => No e-mail queue available + if ($edition == 'Enterprise' && version_compare(Mage::getVersion(), '1.14', '<')) { + return array(); + } + $collection = Mage::getResourceModel('core/email_queue_collection'); + + return array( + 'name' => 'Amount of messages in the e-mail queue', + 'unit' => 'messages', + 'value' => $collection->getSize(), + 'store_id' => 0, + 'type' => 'A' + ); + } + } \ No newline at end of file diff --git a/app/code/community/CoScale/Monitor/Model/Metric/Product.php b/app/code/community/CoScale/Monitor/Model/Metric/Product.php new file mode 100644 index 0000000..2a2a6dd --- /dev/null +++ b/app/code/community/CoScale/Monitor/Model/Metric/Product.php @@ -0,0 +1,194 @@ + + * @version 1.0 + * @created 2015-08-18 + */ +class CoScale_Monitor_Model_Metric_Product extends CoScale_Monitor_Model_Metric_Abstract +{ + /** + * Identifier for the total number of products in the system + */ + const KEY_PRODUCT_TOTAL = 3000; + const KEY_PRODUCT_TODAY = 3001; + /** + * Identifier for the total number of categories in the system + */ + const KEY_CATEGORIES_TOTAL = 3010; + const KEY_CATEGORIES_TODAY = 3011; + + /** + * Public contructor function + */ + public function _contruct() + { + $this->_metricData[self::KEY_PRODUCT_TOTAL] = array( + 'name' => 'Total products', + 'description' => 'The total number of products in the system', + 'unit' => 'products' + ); + + $this->_metricData[self::KEY_PRODUCT_TODAY] = array( + 'name' => 'New products today', + 'description' => 'The total number of products created today', + 'unit' => 'products' + ); + + $this->_metricData[self::KEY_CATEGORIES_TOTAL] = array( + 'name' => 'Total categories', + 'description' => 'The total number of categories in the system', + 'unit' => 'categories' + ); + + $this->_metricData[self::KEY_CATEGORIES_TODAY] = array( + 'name' => 'New categories today', + 'description' => 'The total number of categories created today', + 'unit' => 'categories' + ); + } + + /** + * Observe the adding of new product to the system + * + * @param Varien_Event_Observer $observer + */ + public function addNewProduct(Varien_Event_Observer $observer) + { + /** @var Mage_Catalog_Model_Product $product */ + $product = $observer->getEvent()->getProduct(); + + if ($product->getOrigData('entity_id') == $product->getId()) { + return; + } + + $this->setMetric( + self::ACTION_INCREMENT, + self::KEY_PRODUCT_TOTAL, + 0, + 1 + ); + + $this->setMetric( + self::ACTION_INCREMENT, + self::KEY_PRODUCT_TODAY, + 0, + 1 + ); + } + + /** + * Observe the remove of product + * + * @param Varien_Event_Observer $observer + */ + public function removeProduct(Varien_Event_Observer $observer) + { + $this->setMetric( + self::ACTION_INCREMENT, + self::KEY_PRODUCT_TOTAL, + 0, + -1 + ); + } + + /** + * Observe the adding of new category to the system + * + * @param Varien_Event_Observer $observer + */ + public function addNewCategory(Varien_Event_Observer $observer) + { + /** @var Mage_Catalog_Model_Category $category */ + $category = $observer->getEvent()->getCategory(); + + if ($category->getOrigData('entity_id') == $category->getId()) { + return; + } + + $this->setMetric( + self::ACTION_INCREMENT, + self::KEY_CATEGORIES_TOTAL, + 0, + 1 + ); + + $this->setMetric( + self::ACTION_INCREMENT, + self::KEY_CATEGORIES_TODAY, + 0, + 1 + ); + } + + /** + * Observe the remove of category + * + * @param Varien_Event_Observer $observer + */ + public function removeCategory(Varien_Event_Observer $observer) + { + $this->setMetric( + self::ACTION_INCREMENT, + self::KEY_CATEGORIES_TOTAL, + 0, + -1 + ); + } + + /** + * Cronjob to update the total number of customers + */ + public function dailyCron() + { + $this->resetDayCounter(); + $this->updateTotalCount(); + } + + /** + * Reset daily new created products counter + */ + protected function resetDayCounter() + { + $this->setMetric( + self::ACTION_UPDATE, + self::KEY_PRODUCT_TODAY, + 0, + 0 + ); + + $this->setMetric( + self::ACTION_UPDATE, + self::KEY_CATEGORIES_TODAY, + 0, + 0 + ); + } + + /** + * Daily update full numbers of products + */ + public function updateTotalCount() + { + $collection = Mage::getResourceModel('catalog/product_collection'); + + $this->setMetric( + self::ACTION_UPDATE, + self::KEY_PRODUCT_TOTAL, + 0, + $collection->getSize() + ); + + $collection = Mage::getResourceModel('catalog/category_collection'); + + $this->setMetric( + self::ACTION_UPDATE, + self::KEY_CATEGORIES_TOTAL, + 0, + $collection->getSize() + ); + } +} \ No newline at end of file diff --git a/app/code/community/CoScale/Monitor/Model/Metric/Rewrite.php b/app/code/community/CoScale/Monitor/Model/Metric/Rewrite.php new file mode 100644 index 0000000..c7f3cfb --- /dev/null +++ b/app/code/community/CoScale/Monitor/Model/Metric/Rewrite.php @@ -0,0 +1,37 @@ + + * @version 1.0 + * @created 2015-08-18 + */ +class CoScale_Monitor_Model_Metric_Rewrite extends CoScale_Monitor_Model_Metric_Abstract +{ + + /** + * Get amount of rewrites + * @return array + */ + public function getUrlRewrites() + { + $collection = Mage::getResourceModel('core/url_rewrite_collection'); + $collection->getSelect() + ->reset('columns') + ->columns(array('store_id' => 'main_table.store_id', + 'count' => 'COUNT(*)')) + ->group('main_table.store_id'); + + foreach ($collection as $rewrite) { + $output[] = array( + 'name' => 'URL Rewrites', + 'unit' => 'rewrites', + 'value' => $rewrite->getCount(), + 'store_id' => $rewrite->getStoreId(), + 'type' => 'A' + ); + } + return $output; + } +} \ No newline at end of file diff --git a/app/code/community/CoScale/Monitor/Model/Resource/Event.php b/app/code/community/CoScale/Monitor/Model/Resource/Event.php index ed85d39..6a341c1 100644 --- a/app/code/community/CoScale/Monitor/Model/Resource/Event.php +++ b/app/code/community/CoScale/Monitor/Model/Resource/Event.php @@ -1,4 +1,5 @@ * @created 2015-07-03 * @version 1.0 - */ + */ class CoScale_Monitor_Model_Resource_Event extends Mage_Core_Model_Resource_Db_Abstract { - /** - * Construct the resource model - */ + /** + * Construct the resource model + */ protected function _construct() { $this->_init('coscale_monitor/event', 'id'); } - /** - * Load event by type - * - * @throws Exception - * - * @param CoScale_Monitor_Model_Event $event - * @param string $type The type identifier to load the event by - - * @return $this - */ - public function loadByType(CoScale_Monitor_Model_Event $event, $type) - { - $adapter = $this->_getReadAdapter(); - $bind = array('type' => $type); - $select = $adapter->select() - ->from($this->getTable('coscale_monitor/event'), array('id')) - ->where('`type` = :type') - ->order('id DESC'); + /** + * Load event by type + * + * @throws Exception + * + * @param CoScale_Monitor_Model_Event $event + * @param string $type The type identifier to load the event by + * @return $this + */ + public function loadByType(CoScale_Monitor_Model_Event $event, $type) + { + $adapter = $this->_getReadAdapter(); + $bind = array('type' => $type); + $select = $adapter->select() + ->from($this->getTable('coscale_monitor/event'), array('id')) + ->where('`type` = :type') + ->order('id DESC'); - $eventId = $adapter->fetchOne($select, $bind); - if ($eventId) { - $this->load($event, $eventId); - } else { - $event->setData(array()); - } + $eventId = $adapter->fetchOne($select, $bind); + if ($eventId) { + $this->load($event, $eventId); + } else { + $event->setData(array()); + } - return $this; - } + return $this; + } } \ No newline at end of file diff --git a/app/code/community/CoScale/Monitor/Model/Resource/Event/Collection.php b/app/code/community/CoScale/Monitor/Model/Resource/Event/Collection.php index 4c593a0..e2ef55b 100644 --- a/app/code/community/CoScale/Monitor/Model/Resource/Event/Collection.php +++ b/app/code/community/CoScale/Monitor/Model/Resource/Event/Collection.php @@ -1,4 +1,5 @@ * @created 2015-07-03 * @version 1.0 - */ + */ class CoScale_Monitor_Model_Resource_Event_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract { - /** - * Construct the event collection - */ + /** + * Construct the event collection + */ protected function _construct() { $this->_init('coscale_monitor/event'); diff --git a/app/code/community/CoScale/Monitor/Model/Resource/Metric.php b/app/code/community/CoScale/Monitor/Model/Resource/Metric.php index 74479b7..250d830 100644 --- a/app/code/community/CoScale/Monitor/Model/Resource/Metric.php +++ b/app/code/community/CoScale/Monitor/Model/Resource/Metric.php @@ -1,4 +1,5 @@ * @created 2015-07-03 * @version 1.0 - */ + */ class CoScale_Monitor_Model_Resource_Metric extends Mage_Core_Model_Resource_Db_Abstract { - /** - * Construct the resource model - */ + /** + * Construct the resource model + */ protected function _construct() { $this->_init('coscale_monitor/metric', 'id'); } - /** - * Load metric by key - * - * @param CoScale_Monitor_Model_Metric $metric - * @param int $key The identifier to load the metric by - * @param int $store The store to load the metric belongs to - * - * @return $this - * - * @throws Exception - */ - public function loadByKey(CoScale_Monitor_Model_Metric $metric, $key, $store) - { - $adapter = $this->_getReadAdapter(); - $bind = array('key' => $key, 'store' => $store); - $select = $adapter->select() - ->from($this->getTable('coscale_monitor/metric'), array('id')) - ->where('`key` = :key AND `store_id` = :store'); + /** + * Load metric by key + * + * @param CoScale_Monitor_Model_Metric $metric + * @param int $key The identifier to load the metric by + * @param int $store The store to load the metric belongs to + * + * @return $this + * + * @throws Exception + */ + public function loadByKey(CoScale_Monitor_Model_Metric $metric, $key, $store) + { + $adapter = $this->_getReadAdapter(); + $bind = array('key' => $key, 'store' => $store); + $select = $adapter->select() + ->from($this->getTable('coscale_monitor/metric'), array('id')) + ->where('`key` = :key AND `store_id` = :store'); - $metricId = $adapter->fetchOne($select, $bind); - if ($metricId) { - $this->load($metric, $metricId); - } else { - $metric->setData(array()); - } + $metricId = $adapter->fetchOne($select, $bind); + if ($metricId) { + $this->load($metric, $metricId); + } else { + $metric->setData(array()); + } - return $this; - } + return $this; + } } \ No newline at end of file diff --git a/app/code/community/CoScale/Monitor/Model/Resource/Metric/Collection.php b/app/code/community/CoScale/Monitor/Model/Resource/Metric/Collection.php index c3722bd..40037d6 100644 --- a/app/code/community/CoScale/Monitor/Model/Resource/Metric/Collection.php +++ b/app/code/community/CoScale/Monitor/Model/Resource/Metric/Collection.php @@ -1,4 +1,5 @@ * @created 2015-07-03 * @version 1.0 - */ + */ class CoScale_Monitor_Model_Resource_Metric_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract { - /** - * Construct the data collection - */ + /** + * Construct the data collection + */ protected function _construct() { $this->_init('coscale_monitor/metric'); diff --git a/app/code/community/CoScale/Monitor/etc/config.xml b/app/code/community/CoScale/Monitor/etc/config.xml index 2d1f12b..94567fe 100644 --- a/app/code/community/CoScale/Monitor/etc/config.xml +++ b/app/code/community/CoScale/Monitor/etc/config.xml @@ -2,7 +2,7 @@ - 0.4.0 + 0.6.0 @@ -57,6 +57,38 @@ + + + + coscale_monitor/metric_product + addNewCategory + + + + + + + coscale_monitor/metric_product + removeCategory + + + + + + + coscale_monitor/metric_product + addNewProduct + + + + + + + coscale_monitor/metric_product + removeProduct + + + @@ -91,4 +123,17 @@ + + + + + + 0 0 * * * + + + coscale_monitor/cronjobs::dailyCron + + + + \ No newline at end of file diff --git a/app/code/community/CoScale/Monitor/sql/coscale_monitor_setup/install-0.1.0.php b/app/code/community/CoScale/Monitor/sql/coscale_monitor_setup/install-0.1.0.php index 0042540..63f359d 100644 --- a/app/code/community/CoScale/Monitor/sql/coscale_monitor_setup/install-0.1.0.php +++ b/app/code/community/CoScale/Monitor/sql/coscale_monitor_setup/install-0.1.0.php @@ -6,166 +6,166 @@ * @author Rian Orie * @created 2015-07-03 * @version 1.0 - */ + */ /* @var $installer Mage_Core_Model_Resource_Setup */ $installer = $this; $installer->startSetup(); $event = $installer->getConnection() - ->newTable($installer->getTable('coscale_monitor/event')) - ->addColumn('id', Varien_Db_Ddl_Table::TYPE_INTEGER, - 10, - array( - 'nullable' => false, - 'primary' => true, - 'identity' => true - ), - 'Identifier') - ->addColumn('name', Varien_Db_Ddl_Table::TYPE_VARCHAR, - 255, - array( - 'nullable' => false, - 'primary' => false, - ), - 'Event name') - ->addColumn('description', Varien_Db_Ddl_Table::TYPE_VARCHAR, - 255, - array( - 'nullable' => false, - 'primary' => false, - ), - 'Event description') - ->addColumn('event_data', Varien_Db_Ddl_Table::TYPE_VARCHAR, - 255, - array( - 'nullable' => true, - 'primary' => false, - ), - 'Event data (json)') - ->addColumn('type', Varien_Db_Ddl_Table::TYPE_VARCHAR, - 50, - array( - 'nullable' => false, - 'primary' => false, - ), - 'Event type') - ->addColumn('source', Varien_Db_Ddl_Table::TYPE_VARCHAR, - 50, - array( - 'nullable' => false, - 'primary' => false, - ), - 'Event source') - ->addColumn('state', Varien_Db_Ddl_Table::TYPE_INTEGER, - 1, - array( - 'nullable' => false, - 'primary' => false, - ), - 'Event state (-1 = disabled, 0 = inactive, 1 = on)') - ->addColumn('version', Varien_Db_Ddl_Table::TYPE_VARCHAR, - 10, - array( - 'nullable' => false, - 'primary' => false, - ), - 'Event version (incremented on every update)') - ->addColumn('timestamp', Varien_Db_Ddl_Table::TYPE_INTEGER, - 15, - array(), - 'Update timestamp') - ->addColumn('updated_at', Varien_Db_Ddl_Table::TYPE_TIMESTAMP, - null, - array(), - 'Update Timestamp readable') - ->setComment('CoScale event data'); + ->newTable($installer->getTable('coscale_monitor/event')) + ->addColumn('id', Varien_Db_Ddl_Table::TYPE_INTEGER, + 10, + array( + 'nullable' => false, + 'primary' => true, + 'identity' => true + ), + 'Identifier') + ->addColumn('name', Varien_Db_Ddl_Table::TYPE_VARCHAR, + 255, + array( + 'nullable' => false, + 'primary' => false, + ), + 'Event name') + ->addColumn('description', Varien_Db_Ddl_Table::TYPE_VARCHAR, + 255, + array( + 'nullable' => false, + 'primary' => false, + ), + 'Event description') + ->addColumn('event_data', Varien_Db_Ddl_Table::TYPE_VARCHAR, + 255, + array( + 'nullable' => true, + 'primary' => false, + ), + 'Event data (json)') + ->addColumn('type', Varien_Db_Ddl_Table::TYPE_VARCHAR, + 50, + array( + 'nullable' => false, + 'primary' => false, + ), + 'Event type') + ->addColumn('source', Varien_Db_Ddl_Table::TYPE_VARCHAR, + 50, + array( + 'nullable' => false, + 'primary' => false, + ), + 'Event source') + ->addColumn('state', Varien_Db_Ddl_Table::TYPE_INTEGER, + 1, + array( + 'nullable' => false, + 'primary' => false, + ), + 'Event state (-1 = disabled, 0 = inactive, 1 = on)') + ->addColumn('version', Varien_Db_Ddl_Table::TYPE_VARCHAR, + 10, + array( + 'nullable' => false, + 'primary' => false, + ), + 'Event version (incremented on every update)') + ->addColumn('timestamp', Varien_Db_Ddl_Table::TYPE_INTEGER, + 15, + array(), + 'Update timestamp') + ->addColumn('updated_at', Varien_Db_Ddl_Table::TYPE_TIMESTAMP, + null, + array(), + 'Update Timestamp readable') + ->setComment('CoScale event data'); $event->setOption('type', Varien_Db_Adapter_Pdo_Mysql::ENGINE_MEMORY); $metric = $installer->getConnection() - ->newTable($installer->getTable('coscale_monitor/metric')) - ->addColumn('id', Varien_Db_Ddl_Table::TYPE_INTEGER, - 5, - array( - 'nullable' => false, - 'primary' => true, - 'identity' => true - ), - 'Identifier') - ->addColumn('key', Varien_Db_Ddl_Table::TYPE_INTEGER, - 5, - array( - 'nullable' => false, - 'primary' => false, - ), - 'Fixed identifier for the metric') - ->addColumn('datatype', Varien_Db_Ddl_Table::TYPE_VARCHAR, - 32, - array( - 'nullable' => false, - 'primary' => false, - ), - 'Metric datatype') - ->addColumn('name', Varien_Db_Ddl_Table::TYPE_VARCHAR, - 255, - array( - 'nullable' => false, - 'primary' => false, - ), - 'Metric name') - ->addColumn('description', Varien_Db_Ddl_Table::TYPE_VARCHAR, - 255, - array( - 'nullable' => false, - 'primary' => false, - ), - 'Metric description') - ->addColumn('value', Varien_Db_Ddl_Table::TYPE_VARCHAR, - 255, - array( - 'nullable' => true, - 'primary' => false, - ), - 'Metric value (mixed content)') - ->addColumn('unit', Varien_Db_Ddl_Table::TYPE_VARCHAR, - 10, - array( - 'nullable' => false, - 'primary' => false, - ), - 'Metric unit') - ->addColumn('groups', Varien_Db_Ddl_Table::TYPE_VARCHAR, - 255, - array( - 'nullable' => true, - 'primary' => false, - ), - 'Metric groups') - ->addColumn('tags', Varien_Db_Ddl_Table::TYPE_VARCHAR, - 255, - array( - 'nullable' => true, - 'primary' => false, - ), - 'Metric tags') - ->addColumn('calctype', Varien_Db_Ddl_Table::TYPE_INTEGER, - 2, - array( - 'nullable' => false, - 'primary' => false, - ), - 'Metric calculation type') - ->addColumn('timestamp', Varien_Db_Ddl_Table::TYPE_INTEGER, - 15, - array(), - 'Update timestamp') - ->addColumn('updated_at', Varien_Db_Ddl_Table::TYPE_TIMESTAMP, - null, - array(), - 'Update Timestamp') - ->addIndex('COSCALE_METRIC_UNIQUE_IDX', 'key', array('type' => 'UNIQUE')) - ->setComment('CoScale metric data'); + ->newTable($installer->getTable('coscale_monitor/metric')) + ->addColumn('id', Varien_Db_Ddl_Table::TYPE_INTEGER, + 5, + array( + 'nullable' => false, + 'primary' => true, + 'identity' => true + ), + 'Identifier') + ->addColumn('key', Varien_Db_Ddl_Table::TYPE_INTEGER, + 5, + array( + 'nullable' => false, + 'primary' => false, + ), + 'Fixed identifier for the metric') + ->addColumn('datatype', Varien_Db_Ddl_Table::TYPE_VARCHAR, + 32, + array( + 'nullable' => false, + 'primary' => false, + ), + 'Metric datatype') + ->addColumn('name', Varien_Db_Ddl_Table::TYPE_VARCHAR, + 255, + array( + 'nullable' => false, + 'primary' => false, + ), + 'Metric name') + ->addColumn('description', Varien_Db_Ddl_Table::TYPE_VARCHAR, + 255, + array( + 'nullable' => false, + 'primary' => false, + ), + 'Metric description') + ->addColumn('value', Varien_Db_Ddl_Table::TYPE_VARCHAR, + 255, + array( + 'nullable' => true, + 'primary' => false, + ), + 'Metric value (mixed content)') + ->addColumn('unit', Varien_Db_Ddl_Table::TYPE_VARCHAR, + 10, + array( + 'nullable' => false, + 'primary' => false, + ), + 'Metric unit') + ->addColumn('groups', Varien_Db_Ddl_Table::TYPE_VARCHAR, + 255, + array( + 'nullable' => true, + 'primary' => false, + ), + 'Metric groups') + ->addColumn('tags', Varien_Db_Ddl_Table::TYPE_VARCHAR, + 255, + array( + 'nullable' => true, + 'primary' => false, + ), + 'Metric tags') + ->addColumn('calctype', Varien_Db_Ddl_Table::TYPE_INTEGER, + 2, + array( + 'nullable' => false, + 'primary' => false, + ), + 'Metric calculation type') + ->addColumn('timestamp', Varien_Db_Ddl_Table::TYPE_INTEGER, + 15, + array(), + 'Update timestamp') + ->addColumn('updated_at', Varien_Db_Ddl_Table::TYPE_TIMESTAMP, + null, + array(), + 'Update Timestamp') + ->addIndex('COSCALE_METRIC_UNIQUE_IDX', 'key', array('type' => 'UNIQUE')) + ->setComment('CoScale metric data'); $metric->setOption('type', Varien_Db_Adapter_Pdo_Mysql::ENGINE_MEMORY); diff --git a/app/code/community/CoScale/Monitor/sql/coscale_monitor_setup/upgrade-0.1.0-0.2.0.php b/app/code/community/CoScale/Monitor/sql/coscale_monitor_setup/upgrade-0.1.0-0.2.0.php index 4c7da13..3299237 100644 --- a/app/code/community/CoScale/Monitor/sql/coscale_monitor_setup/upgrade-0.1.0-0.2.0.php +++ b/app/code/community/CoScale/Monitor/sql/coscale_monitor_setup/upgrade-0.1.0-0.2.0.php @@ -6,7 +6,7 @@ * @author Rian Orie * @created 2015-07-03 * @version 1.0 - */ + */ /* @var $installer Mage_Core_Model_Resource_Setup */ $installer = $this; diff --git a/app/code/community/CoScale/Monitor/sql/coscale_monitor_setup/upgrade-0.2.0-0.3.0.php b/app/code/community/CoScale/Monitor/sql/coscale_monitor_setup/upgrade-0.2.0-0.3.0.php index beacb14..f49ea75 100644 --- a/app/code/community/CoScale/Monitor/sql/coscale_monitor_setup/upgrade-0.2.0-0.3.0.php +++ b/app/code/community/CoScale/Monitor/sql/coscale_monitor_setup/upgrade-0.2.0-0.3.0.php @@ -6,7 +6,7 @@ * @author Rian Orie * @created 2015-07-03 * @version 1.0 - */ + */ /* @var $installer Mage_Core_Model_Resource_Setup */ $installer = $this; diff --git a/app/code/community/CoScale/Monitor/sql/coscale_monitor_setup/upgrade-0.3.0-0.4.0.php b/app/code/community/CoScale/Monitor/sql/coscale_monitor_setup/upgrade-0.3.0-0.4.0.php index 98e6bc4..3a442a2 100644 --- a/app/code/community/CoScale/Monitor/sql/coscale_monitor_setup/upgrade-0.3.0-0.4.0.php +++ b/app/code/community/CoScale/Monitor/sql/coscale_monitor_setup/upgrade-0.3.0-0.4.0.php @@ -6,7 +6,7 @@ * @author Rian Orie * @created 2015-07-03 * @version 1.0 - */ + */ /* @var $installer Mage_Core_Model_Resource_Setup */ $installer = $this; diff --git a/app/code/community/CoScale/Monitor/sql/coscale_monitor_setup/upgrade-0.4.0-0.5.0.php b/app/code/community/CoScale/Monitor/sql/coscale_monitor_setup/upgrade-0.4.0-0.5.0.php new file mode 100644 index 0000000..aeab973 --- /dev/null +++ b/app/code/community/CoScale/Monitor/sql/coscale_monitor_setup/upgrade-0.4.0-0.5.0.php @@ -0,0 +1,24 @@ + + * @created 2015-08-18 + * @version 0.5 + */ +/* @var $installer Mage_Core_Model_Resource_Setup */ +$installer = $this; + +$installer->startSetup(); + +$metric = $installer->getConnection(); +$metric->changeTableEngine($installer->getTable('coscale_monitor/metric'), 'InnoDB'); + + +/** + * Initialize order data for further delta processing + */ +Mage::getSingleton('coscale_monitor/metric_order')->initOrderData(); + +$installer->endSetup(); \ No newline at end of file diff --git a/shell/coscale.php b/shell/coscale.php index 8ecf0ef..337aeff 100644 --- a/shell/coscale.php +++ b/shell/coscale.php @@ -12,52 +12,101 @@ */ class CoScale_Shell extends Mage_Shell_Abstract { - /** - * Execute the script - */ - public function run() - { - $output['metrics'] = array(); + /** + * Execute the script + */ + public function run() + { + $output['metrics'] = array(); - $collection = Mage::getModel('coscale_monitor/metric')->getCollection(); - /** @var CoScale_Monitor_Model_Metric $metric */ - foreach($collection as $metric) { - $output['metrics'][] = array('name' => $metric->getName(), - 'unit' => $metric->getUnit(), - 'value' => (float)$metric->getValue(), - 'store_id' => (int)$metric->getStoreId(), - 'type' => $metric->getTypeText()); - } + $collection = Mage::getModel('coscale_monitor/metric')->getCollection(); + /** @var CoScale_Monitor_Model_Metric $metric */ + foreach ($collection as $metric) { + $output['metrics'][] = array( + 'name' => $metric->getName(), + 'unit' => $metric->getUnit(), + 'value' => (float)$metric->getValue(), + 'store_id' => (int)$metric->getStoreId(), + 'type' => $metric->getTypeText()); + } - $output['events'] = array(); + // Abandonned carts + $carts = Mage::getSingleton('coscale_monitor/metric_order')->getAbandonnedCarts(); + foreach ($carts as $data) { + $output['metrics'][] =$data; + } - $collection = Mage::getModel('coscale_monitor/event')->getCollection(); - /** @var CoScale_Monitor_Model_Event $event */ - foreach($collection as $event) { + // Amount of files in var/log + $output['metrics'][] = Mage::getSingleton('coscale_monitor/metric_file')->getErrorReports(); - $output['events'][] = array('type' => $event->getTypeGroup(), - 'message' => $event->getName(), - 'start_time' => (int)(time()-$event->getTimestampStart()), - 'stop_time' => (int)($event->getTimestampEnd() != 0 ? (time()-$event->getTimestampEnd()) : 0), - ); - $event->delete(); - if ($event->getState() != $event::STATE_ENABLED) { - //$event->delete(); - } - } + // Log file details + $logFiles = Mage::getSingleton('coscale_monitor/metric_file')->getLogFiles(); + foreach ($logFiles as $data) { + $output['metrics'][] = $data; + } - $output['modules'] = array(); - foreach(Mage::getConfig()->getNode('modules')->children() as $module) { - $output['modules'][] = array('name' => $module->getName(), 'version' => (string)$module->version); - } + // URL Rewrite details + $urlRewrites = Mage::getSingleton('coscale_monitor/metric_rewrite')->getUrlRewrites(); + foreach ($urlRewrites as $data) { + $output['metrics'][] = $data; + } - $output['stores'] = array(); - foreach(Mage::app()->getStores() as $store) { - $output['stores'][] = array('name' => $store->getName(), 'id' => (int)$store->getId()); - } + // Email queue size + $output['metrics'][] = Mage::getSingleton('coscale_monitor/metric_order')->getEmailQueueSize(); - echo Zend_Json::encode($output); - } + $output['events'] = array(); + + if (file_exists(Mage::getBaseDir('base') . DS . 'maintenance.flag')) { + $output['events'][] = array( + 'type' => 'maintenance mode', + 'message' => 'Maintenance mode enabled', + 'start_time' => 0, + 'stop_time' => 0, + ); + } + + $collection = Mage::getModel('coscale_monitor/event')->getCollection(); + /** @var CoScale_Monitor_Model_Event $event */ + foreach ($collection as $event) { + $output['events'][] = array( + 'type' => $event->getTypeGroup(), + 'message' => $event->getName(), + 'start_time' => (int)(time() - $event->getTimestampStart()), + 'stop_time' => (int)($event->getTimestampEnd() != 0 ? (time() - $event->getTimestampEnd()) : 0), + ); + $event->delete(); + if ($event->getState() != $event::STATE_ENABLED) { + //$event->delete(); + } + } + + $endDateTime = date('U');//Mage::getModel('core/date')->timestamp(time()); // Current timestamp - 65 seconds + $collection = Mage::getModel('cron/schedule')->getCollection() + ->addFieldToFilter('finished_at', array('from' => date('Y-m-d H:i:s', $endDateTime-65))) + ->setOrder('finished_at', 'DESC'); + /** @var Mage_Cron_Model_Schedule $event */ + foreach ($collection as $cron) { + $output['events'][] = array( + 'type' => CoScale_Monitor_Model_Event::GROUP_CRON, + 'message' => $cron->getJobCode(), + 'status' => $cron->getStatus(), + 'start_time' => (int)strtotime($cron->getExecutedAt()), + 'stop_time' => (int)strtotime($cron->getFinishedAt()), + ); + } + $output['modules'] = array(); + $output['modules'][] = array('name' => 'core', 'version' => (string)Mage::getVersion()); + foreach (Mage::getConfig()->getNode('modules')->children() as $module) { + $output['modules'][] = array('name' => $module->getName(), 'version' => (string)$module->version); + } + + $output['stores'] = array(); + foreach (Mage::app()->getStores() as $store) { + $output['stores'][] = array('name' => $store->getName(), 'id' => (int)$store->getId()); + } + + echo Zend_Json::encode($output); + } } $shell = new CoScale_Shell();