├── modman
├── app
├── code
│ └── community
│ │ └── Aleron75
│ │ └── Magemonolog
│ │ ├── Model
│ │ ├── HandlerWrapper
│ │ │ ├── HandlerInterface.php
│ │ │ ├── NewRelicHandler.php
│ │ │ ├── NativeMailHandler.php
│ │ │ ├── StreamHandler.php
│ │ │ └── AbstractHandler.php
│ │ └── Logwriter.php
│ │ ├── Helper
│ │ └── Data.php
│ │ └── etc
│ │ └── config.xml
└── etc
│ └── modules
│ └── Aleron75_Magemonolog.xml
├── composer.json
└── README.md
/modman:
--------------------------------------------------------------------------------
1 | # Aleron75_Magemonolog definition
2 | app/etc/modules/*.xml app/etc/modules/
3 | app/code/community/Aleron75/* app/code/community/Aleron75/
4 |
--------------------------------------------------------------------------------
/app/code/community/Aleron75/Magemonolog/Model/HandlerWrapper/HandlerInterface.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | true
6 | community
7 |
8 |
9 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "aleron75/magemonolog",
3 | "description": "A Magento extension to transparently use Monolog as logging library.",
4 | "type": "magento-module",
5 | "license": "OSL-3.0",
6 | "authors": [
7 | {
8 | "name": "Alessandro Ronchi",
9 | "email": "aleron75@gmail.com"
10 | }
11 | ],
12 | "require": {
13 | "magento-hackathon/magento-composer-installer": "*",
14 | "firegento/psr0autoloader": "*",
15 | "monolog/monolog": "*"
16 | },
17 | "repositories": [
18 | {
19 | "type": "composer",
20 | "url": "http://packages.firegento.com"
21 | }
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/app/code/community/Aleron75/Magemonolog/Model/HandlerWrapper/NewRelicHandler.php:
--------------------------------------------------------------------------------
1 | _validateArgs($args);
11 | $this->_handler = new NewRelicHandler(
12 | $args['level'],
13 | $args['bubble'],
14 | $args['appname']
15 | );
16 | }
17 |
18 | protected function _validateArgs(array &$args)
19 | {
20 | parent::_validateArgs($args);
21 |
22 | // Appname
23 | $appname = '';
24 | if (isset($args['appname']))
25 | {
26 | $appname = trim($args['appname']);
27 | }
28 | $args['appname'] = $appname;
29 | }
30 | }
--------------------------------------------------------------------------------
/app/code/community/Aleron75/Magemonolog/Model/HandlerWrapper/NativeMailHandler.php:
--------------------------------------------------------------------------------
1 | _validateArgs($args);
11 | $this->_handler = new NativeMailerHandler(
12 | $args['to'],
13 | $args['subject'],
14 | $args['from'],
15 | $args['level'],
16 | $args['bubble'],
17 | $args['maxColumnWidth']
18 | );
19 | }
20 |
21 | protected function _validateArgs(array &$args)
22 | {
23 | parent::_validateArgs($args);
24 |
25 | // To
26 | $args['to'] = array_map('trim', explode(',', $args['to']));
27 |
28 | // Subject
29 | $args['subject'] = trim($args['subject']);
30 |
31 | // From
32 | $args['from'] = trim($args['from']);
33 |
34 | // Max Column Width
35 | $maxColumnWidth = null;
36 | if (isset($args['maxColumnWidth']) && is_numeric($args['maxColumnWidth']))
37 | {
38 | $maxColumnWidth = filter_var($args['maxColumnWidth'], FILTER_VALIDATE_INT);
39 | }
40 | $args['maxColumnWidth'] = $maxColumnWidth;
41 | }
42 | }
--------------------------------------------------------------------------------
/app/code/community/Aleron75/Magemonolog/Model/HandlerWrapper/StreamHandler.php:
--------------------------------------------------------------------------------
1 | _validateArgs($args);
11 | $this->_handler = new StreamHandler(
12 | $args['stream'],
13 | $args['level'],
14 | $args['bubble'],
15 | $args['filePermission'],
16 | $args['useLocking']
17 | );
18 | }
19 |
20 | protected function _validateArgs(array &$args)
21 | {
22 | parent::_validateArgs($args);
23 |
24 | // Stream
25 | $file = Mage::getStoreConfig('dev/log/file');
26 | if (isset($args['stream']))
27 | {
28 | $file = $args['stream'];
29 | }
30 | $logDir = Mage::getBaseDir('var') . DS . 'log';
31 | $logFile = $logDir . DS . $file;
32 | $args['stream'] = $logFile;
33 |
34 | // File Permission
35 | $filePermission = null;
36 | if (isset($args['filePermission']) && is_numeric($args['filePermission']))
37 | {
38 | $filePermission = filter_var($args['filePermission'], FILTER_VALIDATE_INT);
39 | }
40 | $args['filePermission'] = $filePermission;
41 |
42 | // Use Locking
43 | $useLocking = false;
44 | if (isset($args['useLocking']))
45 | {
46 | $useLocking = filter_var($args['useLocking'], FILTER_VALIDATE_BOOLEAN);
47 | }
48 | $args['useLocking'] = $useLocking;
49 | }
50 | }
--------------------------------------------------------------------------------
/app/code/community/Aleron75/Magemonolog/Model/HandlerWrapper/AbstractHandler.php:
--------------------------------------------------------------------------------
1 | _handler;
48 | }
49 |
50 | /**
51 | * @param \Monolog\Formatter\FormatterInterface $formatter
52 | */
53 | public function setFormatter(\Monolog\Formatter\FormatterInterface $formatter)
54 | {
55 | if ($this->_handler) {
56 | $this->_handler->setFormatter($formatter);
57 | }
58 | }
59 |
60 | }
--------------------------------------------------------------------------------
/app/code/community/Aleron75/Magemonolog/etc/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 0.3.0
6 |
7 |
8 |
9 |
10 |
11 | Aleron75_Magemonolog_Model
12 |
13 |
14 |
15 |
16 | Aleron75_Magemonolog_Helper
17 |
18 |
19 |
20 |
21 | Aleron75_Magemonolog_Model_Logwriter
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | 1
30 |
31 | magemonolog.log
32 | DEBUG
33 | true
34 | null
35 | false
36 |
37 |
38 | LogstashFormatter
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | 0
50 |
51 | dummy@example.com
52 | Log
53 | dummy@example.com
54 | ERROR
55 | true
56 | 70
57 |
58 |
59 |
60 | 0
61 |
62 | ERROR
63 | true
64 | ***your app name here***
65 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/app/code/community/Aleron75/Magemonolog/Model/Logwriter.php:
--------------------------------------------------------------------------------
1 | _logFile = $logFile;
27 |
28 | // Force autoloading
29 | Mage::dispatchEvent('add_spl_autoloader');
30 |
31 | // Initialize level mapping only after the Logger class is loaded
32 | $this->__initLevelMapping();
33 |
34 | $this->_logger = new Logger('monolog');
35 |
36 | $handlers = Mage::getStoreConfig('magemonolog/handlers');
37 |
38 | if (!is_null($handlers) && is_array($handlers))
39 | {
40 | foreach ($handlers as $handlerModel => $handlerValues)
41 | {
42 | $isActive = Mage::getStoreConfigFlag('magemonolog/handlers/'.$handlerModel.'/active');
43 | if (!$isActive)
44 | {
45 | continue;
46 | }
47 |
48 | $args = array();
49 | if (array_key_exists('params', $handlerValues))
50 | {
51 | $args = $handlerValues['params'];
52 | if (!empty($this->_logFile)){
53 | $logFileParts = explode(DS,$this->_logFile);
54 | $args['stream'] = array_pop($logFileParts);
55 | }
56 | }
57 |
58 | $handlerWrapper = Mage::getModel('aleron75_magemonolog/handlerWrapper_'.$handlerModel, $args);
59 |
60 | if (array_key_exists('formatter', $handlerValues)
61 | && array_key_exists('class', $handlerValues['formatter']))
62 | {
63 | $class = new ReflectionClass('\\Monolog\Formatter\\'.$handlerValues['formatter']['class']);
64 | $formatter = $class->newInstanceArgs($handlerValues['formatter']['args']);
65 | $handlerWrapper->setFormatter($formatter);
66 | }
67 |
68 | $this->_logger->pushHandler($handlerWrapper->getHandler());
69 | }
70 | }
71 | }
72 |
73 | /**
74 | * Initialize the array used to map Zend's log levels into Monolog's
75 | */
76 | private function __initLevelMapping()
77 | {
78 | $this->_levelMap = array(
79 | Zend_Log::EMERG => Logger::EMERGENCY,
80 | Zend_Log::ALERT => Logger::ALERT,
81 | Zend_Log::CRIT => Logger::CRITICAL,
82 | Zend_Log::ERR => Logger::ERROR,
83 | Zend_Log::WARN => Logger::WARNING,
84 | Zend_Log::NOTICE => Logger::NOTICE,
85 | Zend_Log::INFO => Logger::INFO,
86 | Zend_Log::DEBUG => Logger::DEBUG,
87 | );
88 | }
89 |
90 | /**
91 | * Write a message using Monolog.
92 | *
93 | * @param array $event event data
94 | * @return void
95 | */
96 | protected function _write($event)
97 | {
98 | $level = $this->_levelMap[$event['priority']];
99 | $message = $event['message'];
100 | $this->_logger->addRecord($level, $message);
101 | }
102 |
103 | /**
104 | * Create a new instance of Aleron75_Magemonolog_Model_Logwriter
105 | *
106 | * @param array|Zend_Config $config
107 | * @return Aleron75_Magemonolog_Model_Logwriter
108 | * @throws Zend_Log_Exception
109 | */
110 | static public function factory($config)
111 | {
112 | return new self(self::_parseConfig($config));
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | magemonolog
2 | ===========
3 |
4 | Facts
5 | -----
6 | Version: 0.2.2
7 | Developed (and tested) on Magento CE v 1.8.1.0
8 |
9 | Introduction
10 | ------------
11 |
12 | A Magento extension which provides a custom writer model to transparently use
13 | Monolog as logging library.
14 |
15 | The following Monolog's Handlers are supported at the moment:
16 |
17 | * `StreamHandler` - writes to file
18 | * `NativeMailHandler` - sends each log entry via email
19 | * `NewRelicHandler` - logs in NewRelic app
20 |
21 | Installation
22 | ------------
23 |
24 | You can install this extension in several ways:
25 |
26 | **Download**
27 |
28 | Download the full package, copy the content of the `app` directory
29 | in your Magento base directory; pay attention not to overwrite
30 | the `app` folder, only merge its contents into existing directory;
31 |
32 | **Modman**
33 |
34 | Install modman Module Manager: https://github.com/colinmollenhour/modman
35 |
36 | After having installed modman on your system, you can clone this module on your
37 | Magento base directory by typing the following command:
38 |
39 | $ modman init
40 | $ modman clone git@github.com:aleron75/magemonolog.git
41 |
42 | **Composer**
43 |
44 | Install composer: http://getcomposer.org/download/
45 |
46 | Install Magento Composer: https://github.com/magento-hackathon/magento-composer-installer
47 |
48 | Type the following command:
49 |
50 | $ php composer.phar require aleron75/magemonolog:dev-master
51 |
52 | or
53 |
54 | $ composer require aleron75/magemonolog:dev-master
55 |
56 | **Common tasks**
57 |
58 | After installation:
59 |
60 | * if you have cache enabled, disable or refresh it;
61 | * if you have compilation enabled, disable it or recompile the code base.
62 |
63 | Usage example
64 | -------------
65 | Once installed, the module automatically replaces the default Magento Log Writer
66 | with Monolog's StreamHandler.
67 |
68 | This is obtained through the following config node in `config.xml`:
69 |
70 |
71 |
72 |
73 |
74 | Aleron75_Magemonolog_Model_Logwriter
75 |
76 |
77 |
78 |
79 |
80 | which instructs Magento to use a custom log writer class when logging via the
81 | `Mage::log()` native static function.
82 |
83 | The configured `Aleron75_Magemonolog_Model_Logwriter` class is a wrapper for
84 | Monolog and allows to use Monolog's Handlers.
85 |
86 | Monolog's Handlers are configured in the `config.xml` through the following
87 | config node:
88 |
89 |
90 |
91 |
92 |
93 |
94 | 1
95 |
96 | magemonolog.log
97 | DEBUG
98 | true
99 | null
100 | false
101 |
102 |
103 |
104 | 0
105 |
106 | dummy@example.com
107 | Log
108 | dummy@example.com
109 | ERROR
110 | true
111 | 70
112 |
113 |
114 |
115 | 0
116 |
117 | ERROR
118 | true
119 | ***your app name here***
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 | It is assumed you know Monolog's Handlers to understand the meaning of `params`
128 | node.
129 |
130 | Multiple Log Handlers can be activated at the same time with different log
131 | filter level; this way, for example, it is possible to log any message into a
132 | file and only serious errors via e-mail.
133 |
134 | You can also use Monolog's Formatters like shown below:
135 |
136 |
137 |
138 |
139 |
140 |
141 | 1
142 |
143 | magemonolog.log
144 | DEBUG
145 | true
146 | null
147 | false
148 |
149 |
150 | LogstashFormatter
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 | The `` tag should contain proper Formatter's contructor arguments. Arguments' tag name is not important, values
166 | are passed to Formatter's constructor in the exact order the constructor requires them. You should consult Formatter's
167 | constructor signature to know which are its arguments, their meaning and their order.
168 |
169 | Closing words
170 | -------------
171 | Any feedback is appreciated.
172 |
173 | This extension is published under the [Open Software License (OSL 3.0)](http://opensource.org/licenses/OSL-3.0).
174 |
175 | Any contribution or feedback is extremely appreciated.
176 |
--------------------------------------------------------------------------------