-
Notifications
You must be signed in to change notification settings - Fork 44
Clean re-implementation of PR #92: relative date filters, export improvements, and duplicate suppression fixes #121
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
c832e45
d0df95b
2213e14
7bb2a92
8001597
decae94
3d9b587
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,3 +8,4 @@ src/config.php | |
| /doc-site/docs/user-guide/chapters/ | ||
|
|
||
| src/index.html | ||
| .phpunit.result.cache | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -148,6 +148,11 @@ | |
| // No limit - export all matching records | ||
| $maxExportRecords = PHP_INT_MAX; | ||
| } | ||
|
|
||
| // --- Read export-specific config settings | ||
| $content['ExportAllMatchPages'] = GetConfigSetting("ExportAllMatchPages", 0, CFGLEVEL_USER) == 1; | ||
| $content['SuppressDuplicatedMessages'] = GetConfigSetting("ExportSuppressDuplicatedMessages", 0, CFGLEVEL_USER) == 1; | ||
| // --- | ||
|
|
||
| // Copy current used columns here! | ||
| $content['Columns'] = $content['Views'][$currentViewID]['Columns']; | ||
|
|
@@ -209,33 +214,55 @@ | |
| // We found matching records, so continue | ||
| if ( $ret == SUCCESS ) | ||
| { | ||
| // --- Init duplicate suppression state | ||
| $szLastMessage = ""; | ||
| $duplicateCount = 0; | ||
| // --- | ||
|
|
||
| //Loop through the messages! | ||
| do | ||
| { | ||
| // --- Extra stuff for suppressing messages | ||
| if ( | ||
| GetConfigSetting("SuppressDuplicatedMessages", 0, CFGLEVEL_USER) == 1 | ||
| && | ||
| isset($logArray[SYSLOG_MESSAGE]) | ||
| ) | ||
| if ( $content['SuppressDuplicatedMessages'] && isset($logArray[SYSLOG_MESSAGE]) ) | ||
| { | ||
|
|
||
| if ( !isset($szLastMessage) ) // Only set lastmgr | ||
| $szLastMessage = $logArray[SYSLOG_MESSAGE]; | ||
| if ( $szLastMessage !== "" && $szLastMessage == $logArray[SYSLOG_MESSAGE] ) | ||
| { | ||
| // It's a duplicate — count and skip | ||
| $duplicateCount++; | ||
|
|
||
| // Read next entry | ||
| do { | ||
| $ret = $stream->ReadNext($uID, $logArray); | ||
| } while ( $ret == ERROR_MSG_SKIPMESSAGE ); | ||
| continue; | ||
|
cubic-dev-ai[bot] marked this conversation as resolved.
|
||
| } | ||
| else | ||
| { | ||
| // Skip if same msg | ||
| if ( $szLastMessage == $logArray[SYSLOG_MESSAGE] ) | ||
| // Different message — flush any pending duplicate summary | ||
| if ( $duplicateCount > 0 ) | ||
| { | ||
| // Set last mgr | ||
| $szLastMessage = $logArray[SYSLOG_MESSAGE]; | ||
|
|
||
| // Skip entry | ||
| continue; | ||
| foreach ( $content['Columns'] as $mycolkey ) | ||
| { | ||
| $content['syslogmessages'][$counter][$mycolkey]['FieldColumn'] = $mycolkey; | ||
| $content['syslogmessages'][$counter][$mycolkey]['uid'] = ''; | ||
| $content['syslogmessages'][$counter][$mycolkey]['fieldvalue'] = ''; | ||
| } | ||
| if ( isset($content['fields'][SYSLOG_MESSAGE]) ) | ||
| $content['syslogmessages'][$counter][SYSLOG_MESSAGE]['fieldvalue'] = "... suppressed $duplicateCount duplicate(s)..."; | ||
| $counter++; | ||
| $duplicateCount = 0; | ||
| } | ||
| $szLastMessage = $logArray[SYSLOG_MESSAGE]; | ||
| } | ||
| } | ||
| // --- | ||
| // --- | ||
|
|
||
| // --- Track period timestamps for the export filename | ||
| if ( !isset($content['period_start_ts']) && isset($logArray['timereported']) ) | ||
| $content['period_start_ts'] = $logArray['timereported'][EVTIME_TIMESTAMP]; | ||
| if ( isset($logArray['timereported']) ) | ||
| $content['period_end_ts'] = $logArray['timereported'][EVTIME_TIMESTAMP]; | ||
|
cubic-dev-ai[bot] marked this conversation as resolved.
Outdated
Comment on lines
+265
to
+268
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar to the duplicate suppression logic, the timestamp tracking should explicitly verify that if ( !isset($content['period_start_ts']) && isset($logArray['timereported']) && is_array($logArray['timereported']) && isset($logArray['timereported'][EVTIME_TIMESTAMP]) )
$content['period_start_ts'] = $logArray['timereported'][EVTIME_TIMESTAMP];
if ( isset($logArray['timereported']) && is_array($logArray['timereported']) && isset($logArray['timereported'][EVTIME_TIMESTAMP]) )
$content['period_end_ts'] = $logArray['timereported'][EVTIME_TIMESTAMP]; |
||
| // --- | ||
|
|
||
| // --- Now we populate the values array! | ||
| foreach($content['Columns'] as $mycolkey) | ||
|
|
@@ -293,15 +320,41 @@ | |
|
|
||
| // Increment Counter | ||
| $counter++; | ||
| } while ($counter < $maxExportRecords && ($ret = $stream->ReadNext($uID, $logArray)) == SUCCESS); | ||
|
|
||
| // Safety limit — stop if we've hit the maximum export record count | ||
| if ( $counter >= $maxExportRecords ) | ||
| break; | ||
|
|
||
| // Read next entry, skipping filtered-out entries | ||
| do { | ||
| $ret = $stream->ReadNext($uID, $logArray); | ||
| } while ( $ret == ERROR_MSG_SKIPMESSAGE ); | ||
|
|
||
| // If not exporting all pages, stop after the current page size | ||
| if ( !$content['ExportAllMatchPages'] && $counter >= $content['CurrentViewEntriesPerPage'] ) | ||
| break; | ||
|
|
||
| } while ($ret == SUCCESS); | ||
|
|
||
| // Flush any trailing duplicate summary row | ||
| if ( $content['SuppressDuplicatedMessages'] && $duplicateCount > 0 ) | ||
| { | ||
| foreach ( $content['Columns'] as $mycolkey ) | ||
| { | ||
| $content['syslogmessages'][$counter][$mycolkey]['FieldColumn'] = $mycolkey; | ||
| $content['syslogmessages'][$counter][$mycolkey]['uid'] = ''; | ||
| $content['syslogmessages'][$counter][$mycolkey]['fieldvalue'] = ''; | ||
| } | ||
| if ( isset($content['fields'][SYSLOG_MESSAGE]) ) | ||
| $content['syslogmessages'][$counter][SYSLOG_MESSAGE]['fieldvalue'] = "... suppressed $duplicateCount duplicate(s)..."; | ||
| $counter++; | ||
| } | ||
|
|
||
| if ( $content['read_direction'] == EnumReadDirection::Forward ) | ||
| { | ||
| // Back Button was clicked, so we need to flip the array | ||
| $content['syslogmessages'] = array_reverse ( $content['syslogmessages'] ); | ||
| } | ||
| // DEBUG | ||
| //print_r ( $content['syslogmessages'] ); | ||
| } | ||
| } | ||
| else | ||
|
|
@@ -338,7 +391,9 @@ | |
| $szOutputMimeType = "text/plain"; | ||
| $szOutputCharset = ""; | ||
|
|
||
| $szOutputFileName = "ExportMessages"; | ||
| $szOutputFileName = isset($content['period_start_ts']) | ||
| ? "ExportMessages_" . date('Ymd\THis', $content['period_start_ts']) . "-" . date('Ymd\THis', $content['period_end_ts']) | ||
| : "ExportMessages"; | ||
| $szOutputFileExtension = ".txt"; | ||
| $szOPFieldSeparator = " "; | ||
| $szOPFirstLineFieldNames = true; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -333,39 +333,70 @@ | |
| $myMsgCharLimit = GetConfigSetting("ViewMessageCharacterLimit", 80, CFGLEVEL_USER); | ||
| $myStrCharLimit = GetConfigSetting("ViewStringCharacterLimit", 30, CFGLEVEL_USER); | ||
| $ViewColoredCells = GetConfigSetting("ViewColoredCells", 0, CFGLEVEL_USER); | ||
| $DuplicateRecordMaxTsDistance = GetConfigSetting("DuplicateRecordMaxTsDistance", PHP_INT_MAX, CFGLEVEL_USER); | ||
| // --- | ||
|
|
||
| // --- Init duplicate suppression state | ||
| $szLastMessage = ""; | ||
| $szLastMessageTimestamp = 0; | ||
| $duplicateCount = 0; | ||
| $duplicateCountTotal = 0; | ||
| // --- | ||
|
|
||
| //Loop through the messages! | ||
| do | ||
| { | ||
| // --- Extra stuff for suppressing messages | ||
| if ( | ||
| GetConfigSetting("SuppressDuplicatedMessages", 0, CFGLEVEL_USER) == 1 | ||
| && | ||
| isset($logArray[SYSLOG_MESSAGE]) | ||
| ) | ||
| if ( GetConfigSetting("SuppressDuplicatedMessages", 0, CFGLEVEL_USER) == 1 && isset($logArray[SYSLOG_MESSAGE]) ) | ||
|
Comment on lines
+336
to
+350
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The call to $DuplicateRecordMaxTsDistance = GetConfigSetting("DuplicateRecordMaxTsDistance", PHP_INT_MAX, CFGLEVEL_USER);
$SuppressDuplicatedMessages = GetConfigSetting("SuppressDuplicatedMessages", 0, CFGLEVEL_USER) == 1;
// ---
// --- Init duplicate suppression state
$szLastMessage = "";
$szLastMessageTimestamp = 0;
$duplicateCount = 0;
$duplicateCountTotal = 0;
// ---
//Loop through the messages!
do
{
// --- Extra stuff for suppressing messages
if ( $SuppressDuplicatedMessages && isset($logArray[SYSLOG_MESSAGE]) ) |
||
| { | ||
| $szCurrentMessage = $logArray[SYSLOG_MESSAGE]; | ||
| $szCurrentTs = isset($logArray['timereported']) ? $logArray['timereported'][EVTIME_TIMESTAMP] : 0; | ||
|
cubic-dev-ai[bot] marked this conversation as resolved.
Outdated
|
||
| $tsDiff = ($szLastMessageTimestamp > 0 && $szCurrentTs > 0) ? abs($szCurrentTs - $szLastMessageTimestamp) : 0; | ||
|
|
||
| if ( !isset($szLastMessage) ) // Only set lastmgr | ||
| $szLastMessage = $logArray[SYSLOG_MESSAGE]; | ||
| else | ||
| if ( $szLastMessage !== "" && $szLastMessage == $szCurrentMessage && $tsDiff < $DuplicateRecordMaxTsDistance ) | ||
|
cubic-dev-ai[bot] marked this conversation as resolved.
Outdated
|
||
| { | ||
| // Skip if same msg | ||
| if ( $szLastMessage == $logArray[SYSLOG_MESSAGE] ) | ||
| // It's a duplicate | ||
| $duplicateCount++; | ||
| $duplicateCountTotal++; | ||
| $szLastMessageTimestamp = $szCurrentTs; | ||
|
|
||
| // --- Extra Loop to get the next entry! | ||
| do | ||
| { | ||
| // Set last mgr | ||
| $szLastMessage = $logArray[SYSLOG_MESSAGE]; | ||
| $ret = $stream->ReadNext($uID, $logArray); | ||
| } while ( $ret == ERROR_MSG_SKIPMESSAGE ); | ||
| // --- | ||
|
|
||
| // --- Extra Loop to get the next entry! | ||
| do | ||
| // Skip entry | ||
| continue; | ||
| } | ||
| else | ||
| { | ||
| // Different message — flush any pending duplicate summary row | ||
| if ( $duplicateCount > 0 ) | ||
| { | ||
| $content['syslogmessages'][$counter]['cssclass'] = "line1"; | ||
| $content['syslogmessages'][$counter]['MiscShowDebugGridCounter'] = $content['MiscShowDebugGridCounter']; | ||
| foreach ( $content['Columns'] as $mycolkey ) | ||
| { | ||
| $ret = $stream->ReadNext($uID, $logArray); | ||
| } while ( $ret == ERROR_MSG_SKIPMESSAGE ); | ||
| // --- | ||
|
|
||
| // Skip entry | ||
| continue; | ||
| $content['syslogmessages'][$counter]['values'][$mycolkey]['FieldColumn'] = $mycolkey; | ||
| $content['syslogmessages'][$counter]['values'][$mycolkey]['uid'] = ''; | ||
| $content['syslogmessages'][$counter]['values'][$mycolkey]['FieldAlign'] = isset($fields[$mycolkey]) ? $fields[$mycolkey]['FieldAlign'] : 'left'; | ||
| $content['syslogmessages'][$counter]['values'][$mycolkey]['fieldcssclass'] = "line1"; | ||
| $content['syslogmessages'][$counter]['values'][$mycolkey]['fieldbgcolor'] = ""; | ||
| $content['syslogmessages'][$counter]['values'][$mycolkey]['isnowrap'] = "nowrap"; | ||
| $content['syslogmessages'][$counter]['values'][$mycolkey]['hasdetails'] = "false"; | ||
| $content['syslogmessages'][$counter]['values'][$mycolkey]['detailimagealign'] = "TOP"; | ||
| $content['syslogmessages'][$counter]['values'][$mycolkey]['detaillink'] = "#"; | ||
| $content['syslogmessages'][$counter]['values'][$mycolkey]['fieldvalue'] = ''; | ||
| } | ||
| if ( isset($content['syslogmessages'][$counter]['values'][SYSLOG_MESSAGE]) ) | ||
| $content['syslogmessages'][$counter]['values'][SYSLOG_MESSAGE]['fieldvalue'] = "... suppressed $duplicateCount duplicate(s)..."; | ||
| $counter++; | ||
| $duplicateCount = 0; | ||
| } | ||
| $szLastMessage = $szCurrentMessage; | ||
| $szLastMessageTimestamp = $szCurrentTs; | ||
| } | ||
| } | ||
| // --- | ||
|
|
@@ -689,7 +720,33 @@ | |
| } while ( $ret == ERROR_MSG_SKIPMESSAGE ); | ||
| // --- | ||
| } while ( $counter < $content['CurrentViewEntriesPerPage'] && ($ret == SUCCESS) ); | ||
| //print_r ( $content['syslogmessages'] ); | ||
|
|
||
| // Flush any trailing duplicate summary row that was pending when the loop ended | ||
| if ( GetConfigSetting("SuppressDuplicatedMessages", 0, CFGLEVEL_USER) == 1 && $duplicateCount > 0 ) | ||
| { | ||
| $content['syslogmessages'][$counter]['cssclass'] = "line1"; | ||
| $content['syslogmessages'][$counter]['MiscShowDebugGridCounter'] = $content['MiscShowDebugGridCounter']; | ||
| foreach ( $content['Columns'] as $mycolkey ) | ||
| { | ||
| $content['syslogmessages'][$counter]['values'][$mycolkey]['FieldColumn'] = $mycolkey; | ||
| $content['syslogmessages'][$counter]['values'][$mycolkey]['uid'] = ''; | ||
| $content['syslogmessages'][$counter]['values'][$mycolkey]['FieldAlign'] = isset($fields[$mycolkey]) ? $fields[$mycolkey]['FieldAlign'] : 'left'; | ||
| $content['syslogmessages'][$counter]['values'][$mycolkey]['fieldcssclass'] = "line1"; | ||
| $content['syslogmessages'][$counter]['values'][$mycolkey]['fieldbgcolor'] = ""; | ||
| $content['syslogmessages'][$counter]['values'][$mycolkey]['isnowrap'] = "nowrap"; | ||
| $content['syslogmessages'][$counter]['values'][$mycolkey]['hasdetails'] = "false"; | ||
| $content['syslogmessages'][$counter]['values'][$mycolkey]['detailimagealign'] = "TOP"; | ||
| $content['syslogmessages'][$counter]['values'][$mycolkey]['detaillink'] = "#"; | ||
| $content['syslogmessages'][$counter]['values'][$mycolkey]['fieldvalue'] = ''; | ||
| } | ||
| if ( isset($content['syslogmessages'][$counter]['values'][SYSLOG_MESSAGE]) ) | ||
| $content['syslogmessages'][$counter]['values'][SYSLOG_MESSAGE]['fieldvalue'] = "... suppressed $duplicateCount duplicate(s)..."; | ||
| $counter++; | ||
| } | ||
|
|
||
| // Expose suppressed record count and flag for the UI | ||
| $content['main_suppressed_recordcount'] = $duplicateCountTotal; | ||
| $content['SUPPRESS_ENABLED'] = GetConfigSetting("SuppressDuplicatedMessages", 0, CFGLEVEL_USER) == 1 ? "true" : "false"; | ||
|
|
||
| // Move below processing - Read First and LAST UID's before start reading the stream! | ||
| // $content['uid_last'] = $stream->GetLastPageUID(); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The duplicate suppression logic in the export loop is missing the timestamp distance check (
DuplicateRecordMaxTsDistance) that was implemented for the main view. To ensure consistency and adhere to the documentation inconfig.sample.php(line 108), the export suppression should also respect this distance. This requires reading theDuplicateRecordMaxTsDistancesetting outside the loop and tracking the timestamp of the last non-suppressed message (szLastMessageTimestamp) to calculate the difference.