Page MenuHomeIn-Portal Phabricator

D442.id1148.diff
No OneTemporary

File Metadata

Created
Tue, Feb 11, 7:52 PM

D442.id1148.diff

Index: core/admin_templates/logs/system_logs/system_log_edit.tpl
===================================================================
--- core/admin_templates/logs/system_logs/system_log_edit.tpl
+++ core/admin_templates/logs/system_logs/system_log_edit.tpl
@@ -56,12 +56,13 @@
font-size: 12px;
}
- .highlight-area {
+ div.highlight-area {
border: 1px solid black;
padding: 8px;
font-family: serif;
background-color: #F6F6F6;
overflow: auto;
+ margin-top: 4px;
}
.log_backtrace {
@@ -69,8 +70,12 @@
padding-left: 25px;
}
- .log_backtrace div {
- margin: 4px 0;
+ div.expandable-area {
+ margin: 4px 0 4px 0;
+ }
+
+ div.expandable-area div.highlight-area:first-child {
+ margin-bottom: 4px;
}
</style>
@@ -84,13 +89,27 @@
</inp2:m_RenderElement>
</inp2:m_DefineElement>
-<inp2:m_DefineElement name="backtrace_element">
+<inp2:m_DefineElement name="backtrace_element" expandable="">
<li>
<inp2:m_if check="m_Param" name="has_args">
- <a href="#" title="<inp2:m_Phrase name='hint:la_LogBacktraceFunction' html_escape='1'/>" trace_index="<inp2:m_Param name='index'/>"><inp2:m_Phrase name="la_LogBacktraceFunction"/>:</a> <inp2:m_Param name="file_info"/>
+ <inp2:m_SetParam expandable="1"/>
+ <inp2:m_elseif check="m_Param" name="has_code_fragment"/>
+ <inp2:m_SetParam expandable="1"/>
+ </inp2:m_if>
- <div class="highlight-area" style="display: none;" id="trace_args_<inp2:m_Param name='index'/>">
- <inp2:m_Param name="args"/>
+ <inp2:m_if check="m_Param" name="expandable">
+ <a href="#" class="expandable" title="<inp2:m_Phrase name='hint:la_LogBacktraceFunction' html_escape='1'/>" trace_index="<inp2:m_Param name='index'/>"><inp2:m_Phrase name="la_LogBacktraceFunction"/>:</a> <inp2:m_Param name="file_info"/>
+
+ <div style="display: none;" class="expandable-area">
+ <inp2:m_if check="m_Param" name="has_args">
+ <inp2:m_Phrase name="la_text_Arguments"/>:
+ <div class="highlight-area"><inp2:m_Param name="args"/></div>
+ </inp2:m_if>
+
+ <inp2:m_if check="m_Param" name="has_code_fragment">
+ <a href="#" class="expandable"><inp2:m_Phrase name="la_btn_ToggleCode"/></a>
+ <div class="highlight-area expandable-area" style="display: none;"><inp2:m_Param name="code_fragment"/></div>
+ </inp2:m_if>
</div>
<inp2:m_else/>
<inp2:m_Phrase name="la_LogBacktraceFunction"/>: <inp2:m_Param name="file_info"/>
@@ -144,6 +163,11 @@
<inp2:m_RenderElement design="form_row" prefix="system-log" field="LogSourceFilename">
<td class="control-cell" valign="top">
<strong><inp2:$prefix_Filename/></strong> <inp2:m_Phrase name="la_OnLine"/> <strong><inp2:$prefix_Field field="LogSourceFileLine"/></strong>
+
+ <inp2:m_if check="{$prefix}_Field" name="LogCodeFragment" db="db">
+ <a href="#" class="expandable"><inp2:m_Phrase name="la_btn_ToggleCode"/></a>
+ <div class="highlight-area expandable-area" style="display: none;"><inp2:$prefix_PrintCodeFragment/></div>
+ </inp2:m_if>
</td>
</inp2:m_RenderElement>
@@ -155,7 +179,7 @@
<inp2:m_RenderElement design="form_row" prefix="system-log" field="LogBacktrace">
<td class="control-cell" valign="top">
<ol class="log_backtrace">
- <inp2:$prefix_PrintBacktrace render_as="backtrace_element" include_args="1"/>
+ <inp2:$prefix_PrintBacktrace render_as="backtrace_element" include_args="1" include_code_fragment="1"/>
</ol>
</td>
</inp2:m_RenderElement>
@@ -183,10 +207,10 @@
<script type="text/javascript">
$(document).ready(function () {
- $('a', '.log_backtrace').click(function () {
- $('#trace_args_' + $(this).attr('trace_index')).toggle();
+ $(document).on('click', 'a.expandable', function ($e) {
+ $(this).siblings('.expandable-area:first').toggle();
- return false;
+ $e.preventDefault();
});
});
</script>
Index: core/install/english.lang
===================================================================
--- core/install/english.lang
+++ core/install/english.lang
@@ -60,6 +60,7 @@
<PHRASE Label="la_btn_SetValue" Module="Core" Type="1">U2V0IFZhbHVl</PHRASE>
<PHRASE Label="la_btn_ShowStructure" Module="Core" Type="1">U2hvdyBTdHJ1Y3R1cmU=</PHRASE>
<PHRASE Label="la_btn_Synchronize" Module="Core" Type="1">U3luY2hyb25pemU=</PHRASE>
+ <PHRASE Label="la_btn_ToggleCode" Module="Core" Type="1">VG9nZ2xlIENvZGUuLi4=</PHRASE>
<PHRASE Label="la_btn_Unselect" Module="Core" Type="1">VW5zZWxlY3Q=</PHRASE>
<PHRASE Label="la_btn_Up" Module="Core" Type="1">VXA=</PHRASE>
<PHRASE Label="la_btn_UseDraft" Module="Core" Type="1">VXNl</PHRASE>
@@ -211,6 +212,7 @@
<PHRASE Label="la_config_SoftMaintenanceTemplate" Module="Core" Type="1" Hint="VGhpcyB0ZW1wbGF0ZSB3aWxsIGJlIHNob3duIHRvIHRoZSBGcm9udCBFbmQgdXNlcnMgd2hlbiBTb2Z0IE1haW50ZW5hbmNlIG1vZGUgaXMgYWN0aXZlLg==">VGVtcGxhdGUgZm9yIFNvZnQgTWFpbnRlbmFuY2U=</PHRASE>
<PHRASE Label="la_config_ssl_url" Module="Core" Type="1">U1NMIEZ1bGwgVVJMIChodHRwczovL3d3dy5kb21haW4uY29tL3BhdGgp</PHRASE>
<PHRASE Label="la_config_StickyGridSelection" Module="Core" Type="1">VXNlIFN0aWNreSBHcmlkIFNlbGVjdGlvbg==</PHRASE>
+ <PHRASE Label="la_config_SystemLogCodeFragmentPathFilterRegExp" Module="Core" Type="1">UmVjb3JkIGNvZGUgZnJhZ21lbnRzIGluICJTeXN0ZW0gTG9nIiBmb3IgdGhlc2UgcGF0aHMgKHJlZ2V4cCk=</PHRASE>
<PHRASE Label="la_config_SystemLogNotificationEmail" Module="Core" Type="1" Hint="RW1haWwgYWRkcmVzcyB3aGVyZSBVc2VyLWRlZmluZWQgbWVzc2FnZXMgKG1hbnVhbGx5IHNldHVwIGluIHRoZSBjb2RlKSB3aWxsIGJlIGVtYWlsZWQgdG8uIE5vdGUgdGhhdCBhbGwgZGVmYXVsdCAiU3lzdGVtIExvZyIgbWVzc2FnZXMgKG5vbmUgdXNlci1kZWZpbmVkKSBhcmUgTk9UIGVtYWlsZWQgYnkgZGVmYXVsdC4=">U2VuZCBVc2VyLWRlZmluZWQgIlN5c3RlbSBMb2ciIG1lc3NhZ2VzIHRv</PHRASE>
<PHRASE Label="la_config_SystemLogRotationInterval" Module="Core" Type="1" Hint="VGhpcyBzZXR0aW5nIGFsbG93cyB5b3UgdG8gY29udHJvbCBmb3IgaG93IGxvbmcgIlN5c3RlbSBMb2ciIG1lc3NhZ2VzIHdpbGwgYmUgc3RvcmVkIGluIHRoZSBsb2cgYW5kIHRoZW4gYXV0b21hdGljYWxseSBkZWxldGVkLiBVc2Ugb3B0aW9uICJGb3JldmVyIiB3aXRoIGNhdXRpb24gc2luY2UgaXQgd2lsbCBjb21wbGV0ZWx5IGRpc2FibGUgYXV0b21hdGljIGxvZyBjbGVhbnVwIGFuZCBjYW4gbGVhZCB0byBsYXJnZSBzaXplIG9mIGRhdGFiYXNlIHRhYmxlIHRoYXQgc3RvcmVzIGxvZyBtZXNzYWdlcy4=">S2VlcCAiU3lzdGVtIExvZyIgZm9y</PHRASE>
<PHRASE Label="la_config_ThumbnailImageHeight" Module="Core" Type="1">VGh1bWJuYWlsIEhlaWdodA==</PHRASE>
@@ -1327,6 +1329,7 @@
<PHRASE Label="la_Text_Admin" Module="Core" Type="1">QWRtaW4=</PHRASE>
<PHRASE Label="la_text_advanced" Module="Core" Type="1">QWR2YW5jZWQ=</PHRASE>
<PHRASE Label="la_Text_All" Module="Core" Type="1">QWxs</PHRASE>
+ <PHRASE Label="la_text_Arguments" Module="Core" Type="1">QXJndW1lbnRz</PHRASE>
<PHRASE Label="la_text_AutoRefresh" Module="Core" Type="1">QXV0by1SZWZyZXNo</PHRASE>
<PHRASE Label="la_Text_BackupComplete" Module="Core" Type="1">QmFjayB1cCBoYXMgYmVlbiBjb21wbGV0ZWQuIFRoZSBiYWNrdXAgZmlsZSBpczo=</PHRASE>
<PHRASE Label="la_Text_backup_access" Module="Core" Type="1">SW4tUG9ydGFsIGRvZXMgbm90IGhhdmUgYWNjZXNzIHRvIHdyaXRlIHRvIHRoaXMgZGlyZWN0b3J5</PHRASE>
Index: core/install/install_data.sql
===================================================================
--- core/install/install_data.sql
+++ core/install/install_data.sql
@@ -104,6 +104,7 @@
INSERT INTO SystemSettings VALUES(DEFAULT, 'EmailLogRotationInterval', '2419200', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsLogs', 'la_config_EmailLogRotationInterval', 'select', NULL, '86400=la_opt_OneDay||604800=la_opt_OneWeek||1209600=la_opt_TwoWeeks||2419200=la_opt_OneMonth||7257600=la_opt_ThreeMonths||29030400=la_opt_OneYear||-1=la_opt_EmailLogKeepForever', 65.02, 0, 0, 'hint:la_config_EmailLogRotationInterval');
INSERT INTO SystemSettings VALUES(DEFAULT, 'SystemLogRotationInterval', '2419200', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsLogs', 'la_config_SystemLogRotationInterval', 'select', NULL, '86400=la_opt_OneDay||604800=la_opt_OneWeek||1209600=la_opt_TwoWeeks||2419200=la_opt_OneMonth||7257600=la_opt_ThreeMonths||29030400=la_opt_OneYear||-1=la_opt_SystemLogKeepForever', 65.03, 0, 1, 'hint:la_config_SystemLogRotationInterval');
INSERT INTO SystemSettings VALUES(DEFAULT, 'SystemLogNotificationEmail', '', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsLogs', 'la_config_SystemLogNotificationEmail', 'text', 'a:5:{s:4:"type";s:6:"string";s:9:"formatter";s:10:"kFormatter";s:6:"regexp";s:85:"/^([-a-zA-Z0-9!\\#$%&*+\\/=?^_`{|}~.]+@[a-zA-Z0-9]{1}[-.a-zA-Z0-9_]*\\.[a-zA-Z]{2,6})$/i";s:10:"error_msgs";a:1:{s:14:"invalid_format";s:18:"!la_invalid_email!";}s:7:"default";s:0:"";}', NULL, 65.04, 0, 1, 'hint:la_config_SystemLogNotificationEmail');
+INSERT INTO SystemSettings VALUES(DEFAULT, 'SystemLogCodeFragmentPathFilterRegExp', '#(modules/custom|system/cache/modules/custom)/.*#', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsLogs', 'la_config_SystemLogCodeFragmentPathFilterRegExp', 'text', NULL, NULL, 65.05, 0, 1, NULL);
INSERT INTO SystemSettings VALUES(DEFAULT, 'CSVExportDelimiter', '1', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsCSVExport', 'la_config_CSVExportDelimiter', 'select', NULL, '0=la_opt_Tab||1=la_opt_Comma||2=la_opt_Semicolon||3=la_opt_Space||4=la_opt_Colon', 70.01, 0, 1, NULL);
INSERT INTO SystemSettings VALUES(DEFAULT, 'CSVExportEnclosure', '0', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsCSVExport', 'la_config_CSVExportEnclosure', 'radio', NULL, '0=la_Doublequotes||1=la_Quotes', 70.02, 0, 1, NULL);
INSERT INTO SystemSettings VALUES(DEFAULT, 'CSVExportSeparator', '0', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsCSVExport', 'la_config_CSVExportSeparator', 'radio', NULL, '0=la_Linux||1=la_Windows', 70.03, 0, 1, NULL);
Index: core/install/install_schema.sql
===================================================================
--- core/install/install_schema.sql
+++ core/install/install_schema.sql
@@ -447,6 +447,8 @@
LogBacktrace longtext,
LogSourceFilename varchar(255) NOT NULL DEFAULT '',
LogSourceFileLine int(11) DEFAULT NULL,
+ LogCodeFragment longtext,
+ LogCodeFragmentsRotated tinyint(4) NOT NULL DEFAULT '0',
LogProcessId bigint(20) unsigned DEFAULT NULL,
LogMemoryUsed bigint(20) unsigned NOT NULL,
LogUserData longtext NOT NULL,
@@ -454,7 +456,8 @@
PRIMARY KEY (LogId),
KEY LogLevel (LogLevel),
KEY LogType (LogType),
- KEY LogNotificationStatus (LogNotificationStatus)
+ KEY LogNotificationStatus (LogNotificationStatus),
+ KEY `TIMESTAMP_CODE_FRAGMENTS_ROTATED` (`LogTimestamp`,`LogCodeFragmentsRotated`) USING BTREE
);
CREATE TABLE SystemCache (
Index: core/install/upgrades.sql
===================================================================
--- core/install/upgrades.sql
+++ core/install/upgrades.sql
@@ -2958,3 +2958,9 @@
ALTER TABLE Semaphores CHANGE MainIDs MainIDs TEXT NULL;
ALTER TABLE Users ADD KEY Email (Email);
+
+INSERT INTO SystemSettings VALUES(DEFAULT, 'SystemLogCodeFragmentPathFilterRegExp', '#(modules/custom|system/cache/modules/custom)/.*#', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsLogs', 'la_config_SystemLogCodeFragmentPathFilterRegExp', 'text', NULL, NULL, 65.05, 0, 1, NULL);
+ALTER TABLE SystemLog
+ ADD COLUMN `LogCodeFragment` longtext NULL AFTER `LogSourceFileLine`,
+ ADD COLUMN `LogCodeFragmentsRotated` tinyint(4) NOT NULL DEFAULT '0' AFTER `LogCodeFragment`;
+ALTER TABLE SystemLog ADD INDEX `TIMESTAMP_CODE_FRAGMENTS_ROTATED` (`LogTimestamp`,`LogCodeFragmentsRotated`) USING BTREE;
Index: core/kernel/utility/logger.php
===================================================================
--- core/kernel/utility/logger.php
+++ core/kernel/utility/logger.php
@@ -458,6 +458,15 @@
$this->_logRecord['LogSourceFileLine'] = $line;
}
+ $code_fragment = $this->getCodeFragment(
+ $this->_logRecord['LogSourceFilename'],
+ $this->_logRecord['LogSourceFileLine']
+ );
+
+ if ( $code_fragment !== null ) {
+ $this->_logRecord['LogCodeFragment'] = $code_fragment;
+ }
+
return $this;
}
@@ -521,6 +530,14 @@
if ( isset($trace_info['args']) ) {
$trace[$trace_index]['args'] = $this->_implodeObjects($trace_info['args']);
}
+
+ if ( isset($trace_info['file'], $trace_info['line']) ) {
+ $code_fragment = $this->getCodeFragment($trace_info['file'], $trace_info['line']);
+
+ if ( $code_fragment !== null ) {
+ $trace[$trace_index]['code_fragment'] = $code_fragment;
+ }
+ }
}
$this->_logRecord['LogBacktrace'] = serialize($this->_removeObjectsFromTrace($trace));
@@ -529,6 +546,57 @@
}
/**
+ * Returns a code fragment.
+ *
+ * @param string $file Filename.
+ * @param integer $line Line.
+ *
+ * @return string|null
+ */
+ protected function getCodeFragment($file, $line)
+ {
+ static $path_filter_regexp;
+
+ // Lazy detect path filter regexp, because it's not available at construction time.
+ if ( $path_filter_regexp === null ) {
+ $application =& kApplication::Instance();
+ $path_filter_regexp = $application->ConfigValue('SystemLogCodeFragmentPathFilterRegExp');
+ }
+
+ if ( strpos($file, 'eval()\'d code') !== false
+ || ($path_filter_regexp && !preg_match($path_filter_regexp, $file))
+ ) {
+ return null;
+ }
+
+ $from_line = max(1, $line - 10);
+ $to_line = $line + 10;
+
+ // Prefix example: ">>> 5. " or " 5. ".
+ $prefix_length = 4 + strlen($to_line) + 2;
+
+ $cmd_parts = array(
+ 'sed',
+ '-n',
+ escapeshellarg($from_line . ',' . $to_line . 'p'),
+ escapeshellarg($file),
+ );
+ $command = implode(' ', $cmd_parts);
+
+ $ret = array();
+ $code_fragment = preg_replace('/(\r\n|\n|\r)$/', '', shell_exec($command), 1);
+
+ foreach ( explode("\n", $code_fragment) as $line_offset => $code_fragment_part ) {
+ $line_number = $from_line + $line_offset;
+ $line_indicator = $line_number == $line ? '>>> ' : ' ';
+
+ $ret[] = str_pad($line_indicator . $line_number . '.', $prefix_length) . $code_fragment_part;
+ }
+
+ return implode("\n", $ret);
+ }
+
+ /**
* Remove objects from trace, since before PHP 5.2.5 there wasn't possible to remove them initially
*
* @param Array $trace
Index: core/units/logs/system_logs/system_log_eh.php
===================================================================
--- core/units/logs/system_logs/system_log_eh.php
+++ core/units/logs/system_logs/system_log_eh.php
@@ -117,4 +117,48 @@
$temp_handler->DeleteItems($event->Prefix, $event->Special, $ids);
}
}
+
+ /**
+ * Removes old code fragments.
+ *
+ * @param kEvent $event Event.
+ *
+ * @return void
+ */
+ protected function OnRotateCodeFragmentsScheduledTask(kEvent $event)
+ {
+ $id_field = $this->Application->getUnitOption($event->Prefix, 'IDField');
+ $table_name = $this->Application->getUnitOption($event->Prefix, 'TableName');
+
+ $sql = 'SELECT LogBacktrace, ' . $id_field . '
+ FROM ' . $table_name . '
+ WHERE LogTimestamp < ' . strtotime('-1 month') . ' AND LogCodeFragmentsRotated = 0
+ LIMIT 0,500';
+ $records = $this->Conn->GetColIterator($sql, $id_field);
+
+ foreach ( $records as $system_log_id => $trace ) {
+ if ( $trace ) {
+ $trace = unserialize($trace);
+
+ foreach ( $trace as $index => $trace_info ) {
+ if ( array_key_exists('code_fragment', $trace_info) ) {
+ unset($trace[$index]['code_fragment']);
+ }
+ }
+
+ $trace = serialize($trace);
+ }
+
+ $this->Conn->doUpdate(
+ array(
+ 'LogBacktrace' => $trace,
+ 'LogCodeFragment' => null,
+ 'LogCodeFragmentsRotated' => 1,
+ ),
+ $table_name,
+ $id_field . ' = ' . $system_log_id
+ );
+ }
+ }
+
}
Index: core/units/logs/system_logs/system_log_tp.php
===================================================================
--- core/units/logs/system_logs/system_log_tp.php
+++ core/units/logs/system_logs/system_log_tp.php
@@ -118,6 +118,7 @@
$ret = '';
$trace = unserialize($value);
$include_args = isset($params['include_args']) ? $params['include_args'] : false;
+ $include_code_fragment = isset($params['include_code_fragment']) ? $params['include_code_fragment'] : false;
$strip_tags = isset($params['strip_tags']) ? $params['strip_tags'] : false;
$block_params = $this->prepareTagParams($params);
@@ -139,11 +140,21 @@
}
$block_params['has_args'] = isset($trace_info['args']);
+ $block_params['has_code_fragment'] = isset($trace_info['code_fragment']);
if ( $include_args ) {
$block_params['args'] = $block_params['has_args'] ? $this->highlightString(print_r($trace_info['args'], true)) : '';
}
+ if ( $include_code_fragment ) {
+ if ( $block_params['has_code_fragment'] ) {
+ $block_params['code_fragment'] = $this->highlightString($trace_info['code_fragment']);
+ }
+ else {
+ $block_params['code_fragment'] = '';
+ }
+ }
+
$ret .= $this->Application->ParseBlock($block_params);
}
@@ -151,6 +162,27 @@
}
/**
+ * Prints a code fragment.
+ *
+ * @param array $params Tag params.
+ *
+ * @return string
+ */
+ protected function PrintCodeFragment(array $params)
+ {
+ /** @var kDBItem $object */
+ $object = $this->getObject($params);
+
+ $code_fragment = $object->GetDBField('LogCodeFragment');
+
+ if ( $code_fragment ) {
+ return $this->highlightString($code_fragment);
+ }
+
+ return '';
+ }
+
+ /**
* Prints backtrace record index
*
* @param Array $params
Index: core/units/logs/system_logs/system_logs_config.php
===================================================================
--- core/units/logs/system_logs/system_logs_config.php
+++ core/units/logs/system_logs/system_logs_config.php
@@ -34,6 +34,7 @@
'ScheduledTasks' => Array (
'system_log_notifications' => Array ('EventName' => 'OnSendNotifications', 'RunSchedule' => '0 * * * *'),
'rotate_system_logs' => Array ('EventName' => 'OnRotate', 'RunSchedule' => '0 0 * * *'),
+ 'rotate_system_log_code_fragments' => Array ('EventName' => 'OnRotateCodeFragmentsScheduledTask', 'RunSchedule' => '0 0 * * 0'),
),
'IDField' => 'LogId',
@@ -156,6 +157,13 @@
'LogBacktrace' => Array ('type' => 'string', 'default' => NULL),
'LogSourceFilename' => Array ('type' => 'string', 'max_len' => 255, 'not_null' => 1, 'default' => ''),
'LogSourceFileLine' => Array ('type' => 'int', 'default' => NULL),
+ 'LogCodeFragment' => Array ('type' => 'string', 'default' => NULL),
+ 'LogCodeFragmentsRotated' => Array (
+ 'type' => 'int',
+ 'formatter' => 'kOptionsFormatter',
+ 'options' => Array (1 => 'la_Yes', 0 => 'la_No'), 'use_phrases' => 1,
+ 'not_null' => 1, 'default' => 0,
+ ),
'LogProcessId' => Array ('type' => 'int', 'default' => NULL),
'LogMemoryUsed' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0),
'LogUserData' => Array ('type' => 'string', 'not_null' => 1, 'default' => ''),

Event Timeline