Yireo_NewRelic - Version 1.1.0

Version Notes

No notes

Download this release

Release Info

Developer Yireo
Extension Yireo_NewRelic
Version 1.1.0
Comparing to
See all releases


Code changes from version 1.0.5 to 1.1.0

app/code/community/Varien/Profiler.php DELETED
@@ -1,13 +0,0 @@
1
- <?php
2
- /**
3
- * NewRelic plugin for Magento
4
- *
5
- * @package Yireo_NewRelic
6
- * @author Yireo
7
- * @copyright Copyright (c) 2011 Yireo (http://www.yireo.com/)
8
- * @license Open Software License
9
- */
10
-
11
- class Varien_Profiler extends Yireo_NewRelic_Model_Profiler
12
- {
13
- }
app/code/community/Yireo/NewRelic/Helper/Data.php CHANGED
@@ -3,9 +3,9 @@
3
* NewRelic plugin for Magento
4
*
5
* @package Yireo_NewRelic
6
- * @author Yireo
7
- * @copyright Copyright (c) 2011 Yireo (http://www.yireo.com/)
8
- * @license Open Software License
9
*/
10
11
class Yireo_NewRelic_Helper_Data extends Mage_Core_Helper_Abstract
3
* NewRelic plugin for Magento
4
*
5
* @package Yireo_NewRelic
6
+ * @author Yireo (http://www.yireo.com/)
7
+ * @copyright Copyright (c) 2013 Yireo (http://www.yireo.com/)
8
+ * @license Open Source License
9
*/
10
11
class Yireo_NewRelic_Helper_Data extends Mage_Core_Helper_Abstract
app/code/community/Yireo/NewRelic/Model/Observer.php CHANGED
@@ -2,15 +2,39 @@
2
/**
3
* NewRelic plugin for Magento
4
*
5
- * @category design_default
6
* @package Yireo_NewRelic
7
* @author Yireo (http://www.yireo.com/)
8
- * @copyright Copyright (c) 2010 Yireo (http://www.yireo.com/)
9
- * @license Open Software License
10
*/
11
12
class Yireo_NewRelic_Model_Observer
13
{
14
/*
15
* Listen to the event core_block_abstract_to_html_after
16
*
@@ -20,6 +44,11 @@ class Yireo_NewRelic_Model_Observer
20
*/
21
public function coreBlockAbstractToHtmlAfter($observer)
22
{
23
// Check whether NewRelic can be used
24
if(Mage::helper('newrelic')->isEnabled() == false) {
25
return $this;
@@ -30,6 +59,34 @@ class Yireo_NewRelic_Model_Observer
30
return $this;
31
}
32
33
// Fetch objects from this event
34
$transport = $observer->getEvent()->getTransport();
35
$block = $observer->getEvent()->getBlock();
@@ -66,7 +123,27 @@ class Yireo_NewRelic_Model_Observer
66
}
67
68
$object = $observer->getEvent()->getObject();
69
- newrelic_custom_metric('Saving '.get_class($object), 1);
70
71
return $this;
72
}
2
/**
3
* NewRelic plugin for Magento
4
*
5
* @package Yireo_NewRelic
6
* @author Yireo (http://www.yireo.com/)
7
+ * @copyright Copyright (c) 2013 Yireo (http://www.yireo.com/)
8
+ * @license Open Source License
9
*/
10
11
class Yireo_NewRelic_Model_Observer
12
{
13
+ /*
14
+ * Listen to the event controller_action_predispatch
15
+ *
16
+ * @access public
17
+ * @parameter Varien_Event_Observer $observer
18
+ * @return $this
19
+ */
20
+ public function controllerActionPredispatch($observer)
21
+ {
22
+ // Check whether NewRelic can be used
23
+ if(Mage::helper('newrelic')->isEnabled() == true) {
24
+
25
+ // Set the app-name
26
+ $appname = trim(Mage::helper('newrelic')->getConfigValue('appname'));
27
+ $license = trim(Mage::helper('newrelic')->getConfigValue('license'));
28
+ $xmit = true; // @warning: This gives a slight performance overhead - check the NewRelic docs for details
29
+ if(!empty($appname)) newrelic_set_appname($appname, $license, $xmit);
30
+
31
+ // Common settings
32
+ newrelic_capture_params(true);
33
+ }
34
+
35
+ return $this;
36
+ }
37
+
38
/*
39
* Listen to the event core_block_abstract_to_html_after
40
*
44
*/
45
public function coreBlockAbstractToHtmlAfter($observer)
46
{
47
+ // Only for the frontend
48
+ if(Mage::app()->getStore()->isAdmin() == true) {
49
+ return $this;
50
+ }
51
+
52
// Check whether NewRelic can be used
53
if(Mage::helper('newrelic')->isEnabled() == false) {
54
return $this;
59
return $this;
60
}
61
62
+ // Set generic data
63
+ newrelic_add_custom_parameter('magento_controller', Mage::getModel('core/url')->getRequest()->getControllerModule());
64
+ newrelic_add_custom_parameter('magento_request', Mage::getModel('core/url')->getRequest()->getRequestUri());
65
+ newrelic_add_custom_parameter('magento_store_id', Mage::app()->getStore()->getId());
66
+
67
+ // Get and set customer-data
68
+ $customer = Mage::getSingleton('customer/session')->getCustomer();
69
+ $customerName = trim($customer->getName());
70
+ if(empty($customerName)) $customerName = 'guest';
71
+ $customerEmail = trim($customer->getEmail());
72
+ if(empty($customerEmail)) $customerEmail = 'guest';
73
+ newrelic_add_custom_parameter('magento_customer_email', $customerEmail);
74
+ newrelic_add_custom_parameter('magento_customer_name', $customerName);
75
+
76
+ // Get and set product-data
77
+ $product = Mage::registry('current_product');
78
+ if(!empty($product)) {
79
+ $productSku = $product->getSku();
80
+ newrelic_add_custom_parameter('magento_product_name', $product->getName());
81
+ newrelic_add_custom_parameter('magento_product_sku', $product->getSku());
82
+ newrelic_add_custom_parameter('magento_product_id', $product->getId());
83
+ } else {
84
+ $productSku = null;
85
+ }
86
+
87
+ // Set user attributes
88
+ newrelic_set_user_attributes($customerEmail, $customerName, $productSku);
89
+
90
// Fetch objects from this event
91
$transport = $observer->getEvent()->getTransport();
92
$block = $observer->getEvent()->getBlock();
123
}
124
125
$object = $observer->getEvent()->getObject();
126
+ newrelic_custom_metric('Magento/'.get_class($object).'_Save', 1);
127
+
128
+ return $this;
129
+ }
130
+
131
+ /*
132
+ * Listen to the event model_delete_after
133
+ *
134
+ * @access public
135
+ * @parameter Varien_Event_Observer $observer
136
+ * @return $this
137
+ */
138
+ public function modelDeleteAfter($observer)
139
+ {
140
+ // Check whether NewRelic can be used
141
+ if(Mage::helper('newrelic')->isEnabled() == false) {
142
+ return $this;
143
+ }
144
+
145
+ $object = $observer->getEvent()->getObject();
146
+ newrelic_custom_metric('Magento/'.get_class($object).'_Delete', 1);
147
148
return $this;
149
}
app/code/community/Yireo/NewRelic/Model/Profiler.php CHANGED
@@ -5,8 +5,8 @@
5
* @category design_default
6
* @package Yireo_NewRelic
7
* @author Yireo (http://www.yireo.com/)
8
- * @copyright Copyright (c) 2010 Yireo (http://www.yireo.com/)
9
- * @license Open Software License
10
*/
11
12
class Yireo_NewRelic_Model_Profiler
@@ -19,12 +19,12 @@ class Yireo_NewRelic_Model_Profiler
19
}
20
21
// Add generic NewRelic calls that don't have dependancies on Magento
22
- // @all users: More suggestions are welcome
23
static $initialized = false;
24
if($initialized == false) {
25
newrelic_add_custom_tracer('Mage::getModel');
26
newrelic_add_custom_tracer('Mage::getSingleton');
27
newrelic_add_custom_tracer('Mage::helper');
28
newrelic_add_custom_tracer('Mage_Core_Model_App::_initCache');
29
newrelic_add_custom_tracer('Mage_Core_Model_Config::loadDb');
30
newrelic_add_custom_tracer('Mage_Core_Model_Config::loadModules');
@@ -38,69 +38,172 @@ class Yireo_NewRelic_Model_Profiler
38
// Register the Magento request (once it is loaded in Magento) with NewRelic
39
static $request_logged = false;
40
if($request_logged == false) {
41
$request = Mage::app()->getRequest();
42
- if(!empty($request)) {
43
newrelic_name_transaction($request->getRequestUri());
44
}
45
- $request_logged = true;
46
}
47
-
48
- // Register the Magento customers name with NewRelic
49
- // @todo: Load this through an event
50
- /*static $customer_logged = false;
51
- if($customer_logged == false) {
52
- if(Mage::app()->getStore()->isAdmin() == false) {
53
- $session = Mage::getModel('customer/session');
54
- if($session->isLoggedIn()) {
55
- $customer = $session->getCustomer();
56
- if($customer->getId() > 0) {
57
- newrelic_add_custom_parameter('customer', $customer->getName());
58
- }
59
- }
60
- }
61
- $customer_logged = true;
62
- }*/
63
}
64
65
public static function enable()
66
{
67
self::init();
68
- return;
69
}
70
71
public static function disable()
72
{
73
- self::init();
74
- return;
75
}
76
77
public static function reset($timerName)
78
{
79
- self::init();
80
- return;
81
}
82
83
public static function resume($timerName)
84
{
85
- self::init();
86
- return;
87
}
88
89
public static function start($timerName)
90
{
91
- self::init();
92
- return;
93
}
94
95
public static function pause($timerName)
96
{
97
- self::init();
98
- return;
99
}
100
101
public static function stop($timerName)
102
{
103
- self::init();
104
- return;
105
}
106
}
5
* @category design_default
6
* @package Yireo_NewRelic
7
* @author Yireo (http://www.yireo.com/)
8
+ * @copyright Copyright (c) 2013 Yireo (http://www.yireo.com/)
9
+ * @license Open Source License
10
*/
11
12
class Yireo_NewRelic_Model_Profiler
19
}
20
21
// Add generic NewRelic calls that don't have dependancies on Magento
22
static $initialized = false;
23
if($initialized == false) {
24
newrelic_add_custom_tracer('Mage::getModel');
25
newrelic_add_custom_tracer('Mage::getSingleton');
26
newrelic_add_custom_tracer('Mage::helper');
27
+ newrelic_add_custom_tracer('Mage::log');
28
newrelic_add_custom_tracer('Mage_Core_Model_App::_initCache');
29
newrelic_add_custom_tracer('Mage_Core_Model_Config::loadDb');
30
newrelic_add_custom_tracer('Mage_Core_Model_Config::loadModules');
38
// Register the Magento request (once it is loaded in Magento) with NewRelic
39
static $request_logged = false;
40
if($request_logged == false) {
41
+ $request_logged = true;
42
$request = Mage::app()->getRequest();
43
+ if(!empty($request) && function_exists('newrelic_name_transaction')) {
44
newrelic_name_transaction($request->getRequestUri());
45
}
46
}
47
}
48
49
+ /*
50
+ * Below is a copy of the original Varien_Profiler class
51
+ * with one exception: the init() method is called from within enable()
52
+ */
53
+
54
+ /**
55
+ * Timers for code profiling
56
+ *
57
+ * @var array
58
+ */
59
+ static private $_timers = array();
60
+ static private $_enabled = false;
61
+ static private $_memory_get_usage = false;
62
+
63
public static function enable()
64
{
65
+ self::$_enabled = true;
66
+ self::$_memory_get_usage = function_exists('memory_get_usage');
67
self::init();
68
}
69
70
public static function disable()
71
{
72
+ self::$_enabled = false;
73
}
74
75
public static function reset($timerName)
76
{
77
+ self::$_timers[$timerName] = array(
78
+ 'start'=>false,
79
+ 'count'=>0,
80
+ 'sum'=>0,
81
+ 'realmem'=>0,
82
+ 'emalloc'=>0,
83
+ );
84
}
85
86
public static function resume($timerName)
87
{
88
+ if (!self::$_enabled) {
89
+ return;
90
+ }
91
+
92
+ if (empty(self::$_timers[$timerName])) {
93
+ self::reset($timerName);
94
+ }
95
+ if (self::$_memory_get_usage) {
96
+ self::$_timers[$timerName]['realmem_start'] = memory_get_usage(true);
97
+ self::$_timers[$timerName]['emalloc_start'] = memory_get_usage();
98
+ }
99
+ self::$_timers[$timerName]['start'] = microtime(true);
100
+ self::$_timers[$timerName]['count'] ++;
101
}
102
103
public static function start($timerName)
104
{
105
+ self::resume($timerName);
106
}
107
108
public static function pause($timerName)
109
{
110
+ if (!self::$_enabled) {
111
+ return;
112
+ }
113
+
114
+ $time = microtime(true); // Get current time as quick as possible to make more accurate calculations
115
+
116
+ if (empty(self::$_timers[$timerName])) {
117
+ self::reset($timerName);
118
+ }
119
+ if (false!==self::$_timers[$timerName]['start']) {
120
+ self::$_timers[$timerName]['sum'] += $time-self::$_timers[$timerName]['start'];
121
+ self::$_timers[$timerName]['start'] = false;
122
+ if (self::$_memory_get_usage) {
123
+ self::$_timers[$timerName]['realmem'] += memory_get_usage(true)-self::$_timers[$timerName]['realmem_start'];
124
+ self::$_timers[$timerName]['emalloc'] += memory_get_usage()-self::$_timers[$timerName]['emalloc_start'];
125
+ }
126
+ }
127
}
128
129
public static function stop($timerName)
130
{
131
+ self::pause($timerName);
132
+ }
133
+
134
+ public static function fetch($timerName, $key='sum')
135
+ {
136
+ if (empty(self::$_timers[$timerName])) {
137
+ return false;
138
+ } elseif (empty($key)) {
139
+ return self::$_timers[$timerName];
140
+ }
141
+ switch ($key) {
142
+ case 'sum':
143
+ $sum = self::$_timers[$timerName]['sum'];
144
+ if (self::$_timers[$timerName]['start']!==false) {
145
+ $sum += microtime(true)-self::$_timers[$timerName]['start'];
146
+ }
147
+ return $sum;
148
+
149
+ case 'count':
150
+ $count = self::$_timers[$timerName]['count'];
151
+ return $count;
152
+
153
+ case 'realmem':
154
+ if (!isset(self::$_timers[$timerName]['realmem'])) {
155
+ self::$_timers[$timerName]['realmem'] = -1;
156
+ }
157
+ return self::$_timers[$timerName]['realmem'];
158
+
159
+ case 'emalloc':
160
+ if (!isset(self::$_timers[$timerName]['emalloc'])) {
161
+ self::$_timers[$timerName]['emalloc'] = -1;
162
+ }
163
+ return self::$_timers[$timerName]['emalloc'];
164
+
165
+ default:
166
+ if (!empty(self::$_timers[$timerName][$key])) {
167
+ return self::$_timers[$timerName][$key];
168
+ }
169
+ }
170
+ return false;
171
+ }
172
+
173
+ public static function getTimers()
174
+ {
175
+ return self::$_timers;
176
+ }
177
+
178
+ /**
179
+ * Output SQl Zend_Db_Profiler
180
+ *
181
+ */
182
+ public static function getSqlProfiler($res) {
183
+ if(!$res){
184
+ return '';
185
+ }
186
+ $out = '';
187
+ $profiler = $res->getProfiler();
188
+ if($profiler->getEnabled()) {
189
+ $totalTime = $profiler->getTotalElapsedSecs();
190
+ $queryCount = $profiler->getTotalNumQueries();
191
+ $longestTime = 0;
192
+ $longestQuery = null;
193
+
194
+ foreach ($profiler->getQueryProfiles() as $query) {
195
+ if ($query->getElapsedSecs() > $longestTime) {
196
+ $longestTime = $query->getElapsedSecs();
197
+ $longestQuery = $query->getQuery();
198
+ }
199
+ }
200
+
201
+ $out .= 'Executed ' . $queryCount . ' queries in ' . $totalTime . ' seconds' . "<br>";
202
+ $out .= 'Average query length: ' . $totalTime / $queryCount . ' seconds' . "<br>";
203
+ $out .= 'Queries per second: ' . $queryCount / $totalTime . "<br>";
204
+ $out .= 'Longest query length: ' . $longestTime . "<br>";
205
+ $out .= 'Longest query: <br>' . $longestQuery . "<hr>";
206
+ }
207
+ return $out;
208
}
209
}
app/code/community/Yireo/NewRelic/etc/config.xml CHANGED
@@ -3,17 +3,16 @@
3
/**
4
* NewRelic plugin for Magento
5
*
6
- * @category design_default
7
* @package Yireo_NewRelic
8
* @author Yireo
9
- * @copyright Copyright (c) 2011 Yireo (http://www.yireo.com/)
10
* @license Open Software License
11
*/
12
-->
13
<config>
14
<modules>
15
<Yireo_NewRelic>
16
- <version>1.0.5</version>
17
</Yireo_NewRelic>
18
</modules>
19
@@ -34,6 +33,15 @@
34
</newrelic>
35
</models>
36
<events>
37
<core_block_abstract_to_html_after>
38
<observers>
39
<newrelic_core_block_abstract_to_html_after>
@@ -52,6 +60,15 @@
52
</newrelic_model_save_after>
53
</observers>
54
</model_save_after>
55
</events>
56
</global>
57
3
/**
4
* NewRelic plugin for Magento
5
*
6
* @package Yireo_NewRelic
7
* @author Yireo
8
+ * @copyright Copyright (c) 2013 Yireo (http://www.yireo.com/)
9
* @license Open Software License
10
*/
11
-->
12
<config>
13
<modules>
14
<Yireo_NewRelic>
15
+ <version>1.1.0</version>
16
</Yireo_NewRelic>
17
</modules>
18
33
</newrelic>
34
</models>
35
<events>
36
+ <controller_action_predispatch>
37
+ <observers>
38
+ <magebridge_controller_action_predispatch>
39
+ <type>singleton</type>
40
+ <class>Yireo_NewRelic_Model_Observer</class>
41
+ <method>controllerActionPredispatch</method>
42
+ </magebridge_controller_action_predispatch>
43
+ </observers>
44
+ </controller_action_predispatch>
45
<core_block_abstract_to_html_after>
46
<observers>
47
<newrelic_core_block_abstract_to_html_after>
60
</newrelic_model_save_after>
61
</observers>
62
</model_save_after>
63
+ <model_delete_after>
64
+ <observers>
65
+ <newrelic_model_delete_after>
66
+ <type>singleton</type>
67
+ <class>Yireo_NewRelic_Model_Observer</class>
68
+ <method>modelDeleteAfter</method>
69
+ </newrelic_model_delete_after>
70
+ </observers>
71
+ </model_delete_after>
72
</events>
73
</global>
74
app/code/community/Yireo/NewRelic/etc/system.xml CHANGED
@@ -3,17 +3,16 @@
3
/**
4
* NewRelic plugin for Magento
5
*
6
- * @category design_default
7
* @package Yireo_NewRelic
8
* @author Yireo
9
- * @copyright Copyright (c) 2011 Yireo (http://www.yireo.com/)
10
* @license Open Software License
11
*/
12
-->
13
<config>
14
<sections>
15
<newrelic translate="label" module="newrelic">
16
- <label>NewRelic</label>
17
<tab>advanced</tab>
18
<frontend_type>text</frontend_type>
19
<sort_order>342</sort_order>
@@ -29,12 +28,30 @@
29
<show_in_website>1</show_in_website>
30
<show_in_store>1</show_in_store>
31
<fields>
32
<real_user_monitoring translate="label">
33
<label>Real User Monitoring</label>
34
- <comment><![CDATA[Enable when your NewRelic subscription includes this feature]]></comment>
35
<frontend_type>select</frontend_type>
36
<source_model>adminhtml/system_config_source_yesno</source_model>
37
- <sort_order>1</sort_order>
38
<show_in_default>1</show_in_default>
39
<show_in_website>1</show_in_website>
40
<show_in_store>1</show_in_store>
3
/**
4
* NewRelic plugin for Magento
5
*
6
* @package Yireo_NewRelic
7
* @author Yireo
8
+ * @copyright Copyright (c) 2013 Yireo (http://www.yireo.com/)
9
* @license Open Software License
10
*/
11
-->
12
<config>
13
<sections>
14
<newrelic translate="label" module="newrelic">
15
+ <label>New Relic</label>
16
<tab>advanced</tab>
17
<frontend_type>text</frontend_type>
18
<sort_order>342</sort_order>
28
<show_in_website>1</show_in_website>
29
<show_in_store>1</show_in_store>
30
<fields>
31
+ <appname translate="label">
32
+ <label>Application Name</label>
33
+ <comment><![CDATA[Appears in New Relic application-overview]]></comment>
34
+ <frontend_type>text</frontend_type>
35
+ <sort_order>1</sort_order>
36
+ <show_in_default>1</show_in_default>
37
+ <show_in_website>1</show_in_website>
38
+ <show_in_store>1</show_in_store>
39
+ </appname>
40
+ <license translate="label">
41
+ <label>License Key</label>
42
+ <comment><![CDATA[Override of New Relic license-key]]></comment>
43
+ <frontend_type>text</frontend_type>
44
+ <sort_order>2</sort_order>
45
+ <show_in_default>1</show_in_default>
46
+ <show_in_website>1</show_in_website>
47
+ <show_in_store>1</show_in_store>
48
+ </license>
49
<real_user_monitoring translate="label">
50
<label>Real User Monitoring</label>
51
+ <comment><![CDATA[Enable when your New Relic subscription includes this feature]]></comment>
52
<frontend_type>select</frontend_type>
53
<source_model>adminhtml/system_config_source_yesno</source_model>
54
+ <sort_order>99</sort_order>
55
<show_in_default>1</show_in_default>
56
<show_in_website>1</show_in_website>
57
<show_in_store>1</show_in_store>
package.xml CHANGED
@@ -1,18 +1,2 @@
1
<?xml version="1.0"?>
2
- <package>
3
- <name>Yireo_NewRelic</name>
4
- <version>1.0.5</version>
5
- <stability>stable</stability>
6
- <license uri="http://www.opensource.org/licenses/osl-3.0.php/">Open Software License</license>
7
- <channel>community</channel>
8
- <extends/>
9
- <summary>This module adds NewRelic to Magento</summary>
10
- <description>This module adds NewRelic to Magento</description>
11
- <notes>This module adds NewRelic to Magento</notes>
12
- <authors><author><name>Yireo</name><user>auto-converted</user><email>info@yireo.com</email></author></authors>
13
- <date>2011-09-13</date>
14
- <time>15:38:57</time>
15
- <contents><target name="magecommunity"><dir name="Varien"><file name="Profiler.php" hash="296d3f7a5a0686ce8db7cda71639e8eb"/></dir><dir name="Yireo"><dir name="NewRelic"><dir name="Model"><file name="Observer.php" hash="22b013daa3c0214dbfbcf8790e93d62d"/><file name="Profiler.php" hash="f892b59b0ab51f19ef4494d42d7130d3"/></dir><dir name="Helper"><file name="Data.php" hash="7661aee7c080d2af887e934cc9b12f71"/></dir><dir name="etc"><file name="config.xml" hash="4a808fa37260ef41b5f885e50579da61"/><file name="system.xml" hash="2dab0268fd0c5d36b0e7efcc6ffc4cbc"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Yireo_NewRelic.xml" hash="ca797759fe9ecc807f986141989cee17"/></dir></target></contents>
16
- <compatible/>
17
- <dependencies/>
18
- </package>
1
<?xml version="1.0"?>
2
+ <package><name>Yireo_NewRelic</name><version>1.1.0</version><stability>stable</stability><license>Open Source License</license><channel>community</channel><extends></extends><summary>No summary</summary><description>No description</description><notes>No notes</notes><authors><author><name>Yireo</name><user>yireo</user><email>info@yireo.com</email></author></authors><date>2013-05-13</date><time>23:00:54</time><compatible></compatible><dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies><contents><target name="mage"><dir name="app"><dir name="etc"><dir name="modules"><file name="Yireo_NewRelic.xml" hash="ca797759fe9ecc807f986141989cee17"/></dir></dir><dir name="code"><dir name="community"><dir name="Yireo"><dir name="NewRelic"><dir name="etc"><file name="config.xml" hash="73d0df648e9baee26efabaa6cea4440a"/><file name="system.xml" hash="091a15b1f949db3213a72479e1ed5f79"/></dir><dir name="Helper"><file name="Data.php" hash="afb3f139ea7dc1cd90f11151947bd38c"/></dir><dir name="Model"><file name="Observer.php" hash="317204b51a372f050b8678866f2ec0b3"/><file name="Profiler.php" hash="86dfde082f5f0d5cf345205799ed301d"/></dir></dir></dir></dir></dir></dir></target></contents></package>