From ec2f05ab1f1448007fc20d86f7ca8893b125cd4f Mon Sep 17 00:00:00 2001 From: Vitaly X Date: Wed, 28 Dec 2022 23:43:47 +0200 Subject: [PATCH 01/18] support TRACE syslog level; add loglevel style colors and change color for full line; limit empty search to 6h; change datelastx behaviour - use number as hours indicator; --- src/index.html | 375 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 375 insertions(+) create mode 100644 src/index.html diff --git a/src/index.html b/src/index.html new file mode 100644 index 0000000..96ed444 --- /dev/null +++ b/src/index.html @@ -0,0 +1,375 @@ + + + + + + + Apache2 Ubuntu Default Page: It works + + + +
+ + +
+ + +
+
+ It works! +
+
+

+ This is the default welcome page used to test the correct + operation of the Apache2 server after installation on Ubuntu systems. + It is based on the equivalent page on Debian, from which the Ubuntu Apache + packaging is derived. + If you can read this page, it means that the Apache HTTP server installed at + this site is working properly. You should replace this file (located at + /var/www/html/index.html) before continuing to operate your HTTP server. +

+ + +

+ If you are a normal user of this web site and don't know what this page is + about, this probably means that the site is currently unavailable due to + maintenance. + If the problem persists, please contact the site's administrator. +

+ +
+
+
+ Configuration Overview +
+
+

+ Ubuntu's Apache2 default configuration is different from the + upstream default configuration, and split into several files optimized for + interaction with Ubuntu tools. The configuration system is + fully documented in + /usr/share/doc/apache2/README.Debian.gz. Refer to this for the full + documentation. Documentation for the web server itself can be + found by accessing the manual if the apache2-doc + package was installed on this server. + +

+

+ The configuration layout for an Apache2 web server installation on Ubuntu systems is as follows: +

+
+/etc/apache2/
+|-- apache2.conf
+|       `--  ports.conf
+|-- mods-enabled
+|       |-- *.load
+|       `-- *.conf
+|-- conf-enabled
+|       `-- *.conf
+|-- sites-enabled
+|       `-- *.conf
+          
+
    +
  • + apache2.conf is the main configuration + file. It puts the pieces together by including all remaining configuration + files when starting up the web server. +
  • + +
  • + ports.conf is always included from the + main configuration file. It is used to determine the listening ports for + incoming connections, and this file can be customized anytime. +
  • + +
  • + Configuration files in the mods-enabled/, + conf-enabled/ and sites-enabled/ directories contain + particular configuration snippets which manage modules, global configuration + fragments, or virtual host configurations, respectively. +
  • + +
  • + They are activated by symlinking available + configuration files from their respective + *-available/ counterparts. These should be managed + by using our helpers + + a2enmod, + a2dismod, + + + a2ensite, + a2dissite, + + and + + a2enconf, + a2disconf + . See their respective man pages for detailed information. +
  • + +
  • + The binary is called apache2. Due to the use of + environment variables, in the default configuration, apache2 needs to be + started/stopped with /etc/init.d/apache2 or apache2ctl. + Calling /usr/bin/apache2 directly will not work with the + default configuration. +
  • +
+
+ +
+
+ Document Roots +
+ +
+

+ By default, Ubuntu does not allow access through the web browser to + any file apart of those located in /var/www, + public_html + directories (when enabled) and /usr/share (for web + applications). If your site is using a web document root + located elsewhere (such as in /srv) you may need to whitelist your + document root directory in /etc/apache2/apache2.conf. +

+

+ The default Ubuntu document root is /var/www/html. You + can make your own virtual hosts under /var/www. This is different + to previous releases which provides better security out of the box. +

+
+ +
+
+ Reporting Problems +
+
+

+ Please use the ubuntu-bug tool to report bugs in the + Apache2 package with Ubuntu. However, check existing bug reports before reporting a new bug. +

+

+ Please report bugs specific to modules (such as PHP and others) + to respective packages, not to the web server itself. +

+
+ + + + +
+
+
+
+ + + From 41d274399c0adfda01e95d040549d7566ec39d29 Mon Sep 17 00:00:00 2001 From: Vitaly Date: Wed, 28 Dec 2022 23:48:20 +0200 Subject: [PATCH 02/18] Create README.md --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..02c90be --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +# loganalyzer +Adiscon LogAnalyzer, a web frontend to log data from the same folks the created rsyslog + +# changes + - support TRACE syslog level; + - add loglevel style colors and change color for full line; + - limit empty search to 6h; + - change datelastx behaviour - use number as hours indicator, i.e. datelastx:3 is 3 hours limit From 1e6befa4b5f679daed2f5555f5816610a061deb5 Mon Sep 17 00:00:00 2001 From: Vitaly Date: Wed, 28 Dec 2022 23:52:42 +0200 Subject: [PATCH 03/18] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 02c90be..b4364bc 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +![loganalizer_example](https://user-images.githubusercontent.com/8426197/209875963-b7438f3b-9052-4e8f-9f22-05794e1e54a5.png) # loganalyzer Adiscon LogAnalyzer, a web frontend to log data from the same folks the created rsyslog From f1985040a5ef8a3ae22acef695b89edb1253b86a Mon Sep 17 00:00:00 2001 From: Vitaly X Date: Wed, 28 Dec 2022 23:59:28 +0200 Subject: [PATCH 04/18] support TRACE syslog level; add loglevel style colors and change color for full line; limit empty search to 6h; change datelastx behaviour - use number as hours indicator; --- src/classes/logstreamdb.class.php | 7 +- src/include/constants_filters.php | 4 +- src/include/constants_general.php | 4 + src/include/functions_filters.php | 4 +- src/index.html | 375 ------------------------------ src/index.php | 11 +- src/themes/default/main.css | 48 +++- 7 files changed, 67 insertions(+), 386 deletions(-) delete mode 100644 src/index.html diff --git a/src/classes/logstreamdb.class.php b/src/classes/logstreamdb.class.php index 92aba6f..ab3fc8c 100644 --- a/src/classes/logstreamdb.class.php +++ b/src/classes/logstreamdb.class.php @@ -1496,9 +1496,10 @@ class LogStreamDB extends LogStream { if ( $myfilter[FILTER_DATEMODE] == DATEMODE_LASTX ) { // Get current timestamp - $nNowTimeStamp = time(); + + $nNowTimeStamp = time() - (60 * 60 * intval($myfilter[FILTER_VALUE])); - if ( $myfilter[FILTER_VALUE] == DATE_LASTX_HOUR ) + /*if ( $myfilter[FILTER_VALUE] == DATE_LASTX_HOUR ) $nNowTimeStamp -= 60 * 60; // One Hour! else if ( $myfilter[FILTER_VALUE] == DATE_LASTX_12HOURS ) $nNowTimeStamp -= 60 * 60 * 12; // 12 Hours! @@ -1513,7 +1514,7 @@ class LogStreamDB extends LogStream { // Set filter to unknown and Abort in this case! $tmpfilters[$propertyname][FILTER_TYPE] = FILTER_TYPE_UNKNOWN; break; - } + }*/ // Append filter $tmpfilters[$propertyname][FILTER_VALUE] .= $dbmapping[$szTableType]['DBMAPPINGS'][$propertyname] . " > '" . date("Y-m-d H:i:s", $nNowTimeStamp) . "'"; diff --git a/src/include/constants_filters.php b/src/include/constants_filters.php index 4bb1e3b..11b74de 100644 --- a/src/include/constants_filters.php +++ b/src/include/constants_filters.php @@ -109,6 +109,8 @@ $content['filter_severity_list'][] = array( "ID" => SYSLOG_WARNING, "DisplayName $content['filter_severity_list'][] = array( "ID" => SYSLOG_NOTICE, "DisplayName" => "NOTICE", "selected" => "" ); $content['filter_severity_list'][] = array( "ID" => SYSLOG_INFO, "DisplayName" => "INFO", "selected" => "" ); $content['filter_severity_list'][] = array( "ID" => SYSLOG_DEBUG, "DisplayName" => "DEBUG", "selected" => "" ); +$content['filter_severity_list'][] = array( "ID" => SYSLOG_TRACE, "DisplayName" => "TRACE", "selected" => "" ); + // --- // Init MessageType LIST @@ -118,4 +120,4 @@ $content['filter_messagetype_list'][] = array( "ID" => IUT_NT_EventReport, "Disp $content['filter_messagetype_list'][] = array( "ID" => IUT_File_Monitor, "DisplayName" => "File Monitor", "selected" => "" ); $content['filter_messagetype_list'][] = array( "ID" => IUT_WEBSERVERLOG, "DisplayName" => "Webserver Logfile", "selected" => "" ); -?> \ No newline at end of file +?> diff --git a/src/include/constants_general.php b/src/include/constants_general.php index 76194d0..993432c 100644 --- a/src/include/constants_general.php +++ b/src/include/constants_general.php @@ -169,6 +169,8 @@ define('SYSLOG_WARNING', 4); define('SYSLOG_NOTICE', 5); define('SYSLOG_INFO', 6); define('SYSLOG_DEBUG', 7); +define('SYSLOG_TRACE', 8); + $severity_colors[SYSLOG_EMERG] = "#840A15"; $severity_colors[SYSLOG_ALERT] = "#BA0716"; $severity_colors[SYSLOG_CRIT] = "#CE0819"; @@ -177,6 +179,8 @@ $severity_colors[SYSLOG_WARNING] = "#EF8200"; $severity_colors[SYSLOG_NOTICE] = "#14AD42"; $severity_colors[SYSLOG_INFO] = "#0C9C91"; $severity_colors[SYSLOG_DEBUG] = "#119BDE"; +$severity_colors[SYSLOG_TRACE] = "#C0C381"; + // --- // --- MonitorWare InfoUnit Defines | Messagetypes diff --git a/src/include/functions_filters.php b/src/include/functions_filters.php index 748186a..bb239e5 100644 --- a/src/include/functions_filters.php +++ b/src/include/functions_filters.php @@ -237,7 +237,7 @@ function InitFilterHelpers() if ( isset($_SESSION['filter_severity']) ) $filters['filter_severity'] = intval($_SESSION['filter_severity']); else - $filters['filter_severity'] = array ( SYSLOG_EMERG, SYSLOG_ALERT, SYSLOG_CRIT, SYSLOG_ERR, SYSLOG_WARNING, SYSLOG_NOTICE, SYSLOG_INFO, SYSLOG_DEBUG ); + $filters['filter_severity'] = array ( SYSLOG_EMERG, SYSLOG_ALERT, SYSLOG_CRIT, SYSLOG_ERR, SYSLOG_WARNING, SYSLOG_NOTICE, SYSLOG_INFO, SYSLOG_DEBUG, SYSLOG_TRACE ); $iCount = count($content['filter_severity_list']); for ( $i = 0; $i < $iCount; $i++ ) @@ -363,4 +363,4 @@ function GetDateTimeDetailsFromTimeString($szTimeString, &$second, &$minute, &$h return false; } -?> \ No newline at end of file +?> diff --git a/src/index.html b/src/index.html deleted file mode 100644 index 96ed444..0000000 --- a/src/index.html +++ /dev/null @@ -1,375 +0,0 @@ - - - - - - - Apache2 Ubuntu Default Page: It works - - - -
- - -
- - -
-
- It works! -
-
-

- This is the default welcome page used to test the correct - operation of the Apache2 server after installation on Ubuntu systems. - It is based on the equivalent page on Debian, from which the Ubuntu Apache - packaging is derived. - If you can read this page, it means that the Apache HTTP server installed at - this site is working properly. You should replace this file (located at - /var/www/html/index.html) before continuing to operate your HTTP server. -

- - -

- If you are a normal user of this web site and don't know what this page is - about, this probably means that the site is currently unavailable due to - maintenance. - If the problem persists, please contact the site's administrator. -

- -
-
-
- Configuration Overview -
-
-

- Ubuntu's Apache2 default configuration is different from the - upstream default configuration, and split into several files optimized for - interaction with Ubuntu tools. The configuration system is - fully documented in - /usr/share/doc/apache2/README.Debian.gz. Refer to this for the full - documentation. Documentation for the web server itself can be - found by accessing the manual if the apache2-doc - package was installed on this server. - -

-

- The configuration layout for an Apache2 web server installation on Ubuntu systems is as follows: -

-
-/etc/apache2/
-|-- apache2.conf
-|       `--  ports.conf
-|-- mods-enabled
-|       |-- *.load
-|       `-- *.conf
-|-- conf-enabled
-|       `-- *.conf
-|-- sites-enabled
-|       `-- *.conf
-          
-
    -
  • - apache2.conf is the main configuration - file. It puts the pieces together by including all remaining configuration - files when starting up the web server. -
  • - -
  • - ports.conf is always included from the - main configuration file. It is used to determine the listening ports for - incoming connections, and this file can be customized anytime. -
  • - -
  • - Configuration files in the mods-enabled/, - conf-enabled/ and sites-enabled/ directories contain - particular configuration snippets which manage modules, global configuration - fragments, or virtual host configurations, respectively. -
  • - -
  • - They are activated by symlinking available - configuration files from their respective - *-available/ counterparts. These should be managed - by using our helpers - - a2enmod, - a2dismod, - - - a2ensite, - a2dissite, - - and - - a2enconf, - a2disconf - . See their respective man pages for detailed information. -
  • - -
  • - The binary is called apache2. Due to the use of - environment variables, in the default configuration, apache2 needs to be - started/stopped with /etc/init.d/apache2 or apache2ctl. - Calling /usr/bin/apache2 directly will not work with the - default configuration. -
  • -
-
- -
-
- Document Roots -
- -
-

- By default, Ubuntu does not allow access through the web browser to - any file apart of those located in /var/www, - public_html - directories (when enabled) and /usr/share (for web - applications). If your site is using a web document root - located elsewhere (such as in /srv) you may need to whitelist your - document root directory in /etc/apache2/apache2.conf. -

-

- The default Ubuntu document root is /var/www/html. You - can make your own virtual hosts under /var/www. This is different - to previous releases which provides better security out of the box. -

-
- -
-
- Reporting Problems -
-
-

- Please use the ubuntu-bug tool to report bugs in the - Apache2 package with Ubuntu. However, check existing bug reports before reporting a new bug. -

-

- Please report bugs specific to modules (such as PHP and others) - to respective packages, not to the web server itself. -

-
- - - - -
-
-
-
- - - diff --git a/src/index.php b/src/index.php index 396b4b1..bcc18a2 100644 --- a/src/index.php +++ b/src/index.php @@ -122,7 +122,7 @@ $content['main_pager_last_found'] = false; // Init Sorting variables $content['sorting'] = ""; $content['searchstr'] = ""; -$content['searchstr_htmlform'] = ""; +$content['searchstr_htmlform'] = "datelastx:6"; $content['highlightstr'] = ""; $content['highlightstr_htmlform'] = ""; $content['EXPAND_HIGHLIGHT'] = "false"; @@ -202,7 +202,6 @@ if ( (isset($_POST['search']) || isset($_GET['search'])) || (isset($_POST['filte } } // --- - // --- BEGIN CREATE TITLE $content['TITLE'] = InitPageTitle(); @@ -215,6 +214,10 @@ else // --- BEGIN Custom Code +//by default limit search to some sane range +if (empty($content['searchstr'])){ + $content['searchstr'] = $content['searchstr_htmlform']; +} // Do not BLOCK other Site Calls WriteClosePHPSession(); @@ -365,9 +368,9 @@ if ( isset($content['Sources'][$currentSourceID]) ) // --- Set CSS Class if ( $counter % 2 == 0 ) - $content['syslogmessages'][$counter]['cssclass'] = "line1"; + $content['syslogmessages'][$counter]['cssclass'] = "line1_".$logArray[SYSLOG_SEVERITY]; else - $content['syslogmessages'][$counter]['cssclass'] = "line2"; + $content['syslogmessages'][$counter]['cssclass'] = "line2_".$logArray[SYSLOG_SEVERITY]; // --- // --- Copy other needed properties diff --git a/src/themes/default/main.css b/src/themes/default/main.css index 0b305f7..a9cb627 100644 --- a/src/themes/default/main.css +++ b/src/themes/default/main.css @@ -25,7 +25,7 @@ a:link,a:active,a:visited,a.postlink text-decoration:none; background-color: transparent; - color:#005989; + color:#ffffff; } a:hover { @@ -157,6 +157,52 @@ font } /* Cells for listening */ +/*emergency*/ +.line1_0 { color: #ffffff; background-color: #840A15;} +.line1_0:hover { background-color:#ed1224;} +.line2_0{ color: #ffffff; background-color: #be0e1d;} +.line2_0:hover {background-color:#f8a0a7; } +/*alert*/ +.line1_1 { color: #ffffff; background-color: #BA0716;} +.line1_1:hover { background-color:#f6091d;} +.line2_1{ color: #ffffff; background-color: #dd081a;} +.line2_1:hover {background-color:#fa6b77; } +/*critical*/ +.line1_2 { color: #ffffff; background-color: #CE0819;} +.line1_2:hover { background-color:#fa6b77;} +.line2_2{ color: #ffffff; background-color: #f83a4a;} +.line2_2:hover {background-color:#fcb5bb; } +/*error*/ +.line1_3 { color: #ffffff; background-color: #BB0A1F;} +.line1_3:hover { background-color:#fa9ea9;} +.line2_3{ color: #ffffff; background-color: #f20d28;} +.line2_3:hover {background-color:#fa9ea9; } +/*warning*/ +.line1_4 { color: #000000; background-color: #EF8200;} +.line1_4:hover { background-color:#ffa333;} +.line2_4{ color: #000000; background-color: #ff8c00;} +.line2_4:hover {background-color:#ffc680; } +/*notice*/ +.line1_5 { color: #000000; background-color: #14AD42;} +.line1_5:hover { background-color:#32e768;} +.line2_5{ color: #000000; background-color: #18cd4e;} +.line2_5:hover {background-color:#76ef9a; } +/*info*/ +.line1_6 { color: #000000; background-color: #0C9C91;} +.line1_6:hover { background-color:#2aefde;} +.line2_6{ color: #000000; background-color: #0ebeaf;} +.line2_6:hover {background-color:#2aefde; } +/*debug*/ +.line1_7 { color: #000000; background-color: #666699;} +.line1_7:hover { background-color:#a3a3c2;} +.line2_7{ color: #000000; background-color: #8585ad;} +.line2_7:hover {background-color:#a3a3c2; } +/*trace*/ +.line1_8 { color: #000000; background-color: #c2c2c0;} +.line1_8:hover { background-color:#dadad8;} +.line2_8{ color: #000000; background-color: #cdcdcb;} +.line2_8:hover {background-color:#f3f3f2; } + .line0 { color: #000000; From 09646a4f8cd04fff4d1ad2f0ff1ee19ccda66e11 Mon Sep 17 00:00:00 2001 From: Vitaly Date: Thu, 29 Dec 2022 12:25:56 +0200 Subject: [PATCH 05/18] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index b4364bc..37dc5a2 100644 --- a/README.md +++ b/README.md @@ -7,3 +7,6 @@ Adiscon LogAnalyzer, a web frontend to log data from the same folks the created - add loglevel style colors and change color for full line; - limit empty search to 6h; - change datelastx behaviour - use number as hours indicator, i.e. datelastx:3 is 3 hours limit + +# todo + - "Maximize view" - reloads page, hide toolbars with js instead From 5e9fd89a29b329765b2a8958997cee8d60b9b3f9 Mon Sep 17 00:00:00 2001 From: Vitaly Date: Thu, 29 Dec 2022 12:26:28 +0200 Subject: [PATCH 06/18] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 37dc5a2..b3253ed 100644 --- a/README.md +++ b/README.md @@ -9,4 +9,4 @@ Adiscon LogAnalyzer, a web frontend to log data from the same folks the created - change datelastx behaviour - use number as hours indicator, i.e. datelastx:3 is 3 hours limit # todo - - "Maximize view" - reloads page, hide toolbars with js instead + - "Maximize view" - reloads page and resets search filter, hide toolbars with js instead From b46e135d245b5272ed2e0e85ae44e19142a904d5 Mon Sep 17 00:00:00 2001 From: Vitaly Date: Thu, 29 Dec 2022 12:27:24 +0200 Subject: [PATCH 07/18] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b3253ed..7b8239a 100644 --- a/README.md +++ b/README.md @@ -10,3 +10,4 @@ Adiscon LogAnalyzer, a web frontend to log data from the same folks the created # todo - "Maximize view" - reloads page and resets search filter, hide toolbars with js instead + - changing "Autoreload" does the same as "Max. view" From 678f984eebc53e261282fa65f614afa119121e7c Mon Sep 17 00:00:00 2001 From: Vitaly Date: Thu, 29 Dec 2022 12:30:17 +0200 Subject: [PATCH 08/18] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 7b8239a..ced17c1 100644 --- a/README.md +++ b/README.md @@ -11,3 +11,4 @@ Adiscon LogAnalyzer, a web frontend to log data from the same folks the created # todo - "Maximize view" - reloads page and resets search filter, hide toolbars with js instead - changing "Autoreload" does the same as "Max. view" + - allow to manually configure log levels (severity) instead of using constants From fe720c48bc1537576011db3b2fc44719136a514c Mon Sep 17 00:00:00 2001 From: Vitaly X Date: Tue, 3 Jan 2023 14:55:40 +0200 Subject: [PATCH 09/18] Support quoted filters <- use text inside without parsing; support number ranges --- src/classes/logstream.class.php | 93 ++++++++++++++++++++++++++------- 1 file changed, 75 insertions(+), 18 deletions(-) diff --git a/src/classes/logstream.class.php b/src/classes/logstream.class.php index d57e0dc..27f30b7 100644 --- a/src/classes/logstream.class.php +++ b/src/classes/logstream.class.php @@ -752,7 +752,7 @@ abstract class LogStream { // Use RegEx for intelligent splitting $szFilterRgx = '/[\s]++(?=(?:(?:[^"]*+"){2})*+[^"]*+$)(?=(?:(?:[^\']*+\'){2})*+[^\']*+$)(?=(?:[^()]*+\([^()]*+\))*+[^()]*+$)/x'; $tmpEntries = preg_split($szFilterRgx, $szFilters, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); -//DEBUG print_r ( $tmpEntries ); + //echo "DEBUG:
"; print_r ($tmpEntries ); echo "
"; foreach($tmpEntries as $myEntry) { @@ -761,10 +761,10 @@ abstract class LogStream { continue; if ( - ($pos = strpos($myEntry, ":")) !== false + ($pos = strpos($myEntry, ":")) !== false && - ($pos > 0 && substr($myEntry, $pos-1,1) != '\\') /* Only if character before is no backslash! */ - ) + ($pos > 0 && substr($myEntry, $pos-1,1) != '\\') /* Only if character before is no backslash! */ + ) { // Split key and value $tmpArray = explode(":", $myEntry, 2); @@ -777,12 +777,76 @@ abstract class LogStream { // Check for multiple values! if ( strpos($tmpArray[FILTER_TMP_VALUE], ",") ) { - // Split by comma and fill tmp Value array - $tmpValueArray = explode(",", $tmpArray[FILTER_TMP_VALUE]); - foreach($tmpValueArray as $myValueEntry) - { - // Append to temp array - $tmpValues[] = array( FILTER_TMP_MODE => $this->SetFilterIncludeMode($myValueEntry), FILTER_TMP_VALUE => $myValueEntry ); + //echo $tmpArray[FILTER_TMP_VALUE]."
"; + $tmpArrayFilt = $tmpArray[FILTER_TMP_VALUE]; + //don't parse quoted filter part - use it as a whole, i.e. param:"t1.1,t1.2",k2,k3 - search for (param like "%t1.1,t1.2%" or param like "%k2% or param like "%k3%") + //replace number range, i.e. 1-8, to 1,2,...,8 + $myValueEntry = ""; + $prevChar = ""; + $quoteStart = false; + $numberRange = false; + $rangeStart = 0; + for ($i = 0; $i < strlen($tmpArrayFilt); $i++){ + $strChar = $tmpArrayFilt[$i]; + //echo $strChar."
"; + + if($numberRange){ + //echo "#range#end#"; + $range = $rangeStart; + for($j = $rangeStart; $j < intval($strChar); $j++){ + $range .= ($j == $rangeStart)?(""):(",").$j; + } + $tmpValues[] = array( FILTER_TMP_MODE => $this->SetFilterIncludeMode($range), FILTER_TMP_VALUE => $range); + + $myValueEntry = ''; + $rangeStart = 0; + $numberRange = false; + + }//not filter start, not quoted, and is not negation, then it's a range + // TODO handle partial range, i.e. property:3-,-1,-4 = ignore 1,4 and find range from 3 to max_syslog_severity + else if($strChar === '-' && !$quoteStart && $prevChar !== ',' && $i !== 0 /*!filter start':'*/){ + //echo "#range#start#".$prevChar; + $nextChar = $tmpArrayFilt[$i+1]; + if(!is_numeric($nextChar)){//handle incomplete range as a singleton + $tmpValues[] = array( FILTER_TMP_MODE => $this->SetFilterIncludeMode($prevChar), FILTER_TMP_VALUE => $prevChar); + }else{ + $numberRange = true; + $rangeStart = intval($prevChar); + } + + }//is not a separator inside quite, thus handle as usual + else if($strChar === ',' && !$quoteStart){ + //echo "#comma#"; + //if(!empty($myValueEntry)){ + $tmpValues[] = array( FILTER_TMP_MODE => $this->SetFilterIncludeMode($myValueEntry), FILTER_TMP_VALUE => $myValueEntry ); + $myValueEntry = ""; + //} + $prevChar = $strChar; + + }//it's not escaped quote, handle it specially + else if($strChar === '"' && $prevChar !== '\\'){ + //echo "#quote#"; + if($quoteStart){//quoted str parsed; add filter into array as is + //echo "#qend#".$myValueEntry."
"; + $tmpValues[] = array( FILTER_TMP_MODE => $this->SetFilterIncludeMode($myValueEntry), FILTER_TMP_VALUE => $myValueEntry ); + $myValueEntry = ""; + $prevChar = ""; + $quoteStart = false; + }else{ + //echo "#qstart#"; + $quoteStart = true; + //$prevChar = $strChar; + } + }else{//build filter string + //echo "#concat#"; + $myValueEntry .= $strChar; + $prevChar = $strChar; + if(($i+1) == strlen($tmpArrayFilt)){//on last char insert filter instantly + $tmpValues[] = array( FILTER_TMP_MODE => $this->SetFilterIncludeMode($myValueEntry), FILTER_TMP_VALUE => $myValueEntry ); + } + + } + } } @@ -865,13 +929,6 @@ abstract class LogStream { } } -/* OBSELETE CODE - foreach( $tmpValues as $mykey => $szValue ) - { - // First set Filter Mode - $tmpValues[$mykey][FILTER_TMP_MODE] = $this->SetFilterIncludeMode($szValue); - } -*/ } else { @@ -1322,4 +1379,4 @@ abstract class LogStream { } } -?> \ No newline at end of file +?> From 27bb2db6d69f0deff84df2309d1a2c8c035a189a Mon Sep 17 00:00:00 2001 From: Vitaly X Date: Tue, 3 Jan 2023 15:01:59 +0200 Subject: [PATCH 10/18] readme changes --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index ced17c1..453860b 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ Adiscon LogAnalyzer, a web frontend to log data from the same folks the created rsyslog # changes + - support number ranges in filter, i.e. severity:3-6 -> where severity in (3,4,5,6) + - support quoted filters, i.e. syslogtag:-="dhcp,info",-="wireless,info",-"system%,account" -> where (syslogtag <> 'dhcp,info' AND syslogtag <> 'wireless,info' AND syslogtag NOT LIKE '%system%,account%' ) - support TRACE syslog level; - add loglevel style colors and change color for full line; - limit empty search to 6h; From 0e1114846d1739c1f47d8e4e067f81be52b887ea Mon Sep 17 00:00:00 2001 From: Vitaly X Date: Tue, 3 Jan 2023 23:39:16 +0200 Subject: [PATCH 11/18] charts orderby config; see readme for more details --- .gitignore | 2 ++ README.md | 4 +++ src/admin/charts.php | 20 +++++++++++---- src/chartgenerator.php | 21 +++++++++------ src/classes/logstreamdb.class.php | 37 +++++++++------------------ src/include/db_update_v14.txt | 7 +++++ src/include/functions_common.php | 2 ++ src/include/functions_config.php | 3 ++- src/index.php | 5 +++- src/statistics.php | 8 +++++- src/templates/admin/admin_charts.html | 11 +++++--- src/templates/statistics.html | 13 ++++++++-- 12 files changed, 87 insertions(+), 46 deletions(-) create mode 100644 .gitignore create mode 100644 src/include/db_update_v14.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3809eae --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +src/config.php + diff --git a/README.md b/README.md index 453860b..67b9b40 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,10 @@ Adiscon LogAnalyzer, a web frontend to log data from the same folks the created rsyslog # changes + - Maximize view by default + - fix chart double adding same key into search + - allow to configure ORDER BY clause + - add custom filter to chart value redirection link if such exists - support number ranges in filter, i.e. severity:3-6 -> where severity in (3,4,5,6) - support quoted filters, i.e. syslogtag:-="dhcp,info",-="wireless,info",-"system%,account" -> where (syslogtag <> 'dhcp,info' AND syslogtag <> 'wireless,info' AND syslogtag NOT LIKE '%system%,account%' ) - support TRACE syslog level; diff --git a/src/admin/charts.php b/src/admin/charts.php index e4d1ed2..75bd537 100644 --- a/src/admin/charts.php +++ b/src/admin/charts.php @@ -154,7 +154,8 @@ if ( isset($_GET['op']) ) $content['CHECKED_ISSHOWPERCENT'] = ""; $content['chart_defaultfilter'] = ""; // Chart Field - $content['chart_field'] = SYSLOG_HOST; + $content['chart_field'] = SYSLOG_HOST; + $content['chart_orderby'] = ''; CreateChartFields($content['chart_field']); // COMMON Fields @@ -194,7 +195,6 @@ if ( isset($_GET['op']) ) { // Get Source reference $myChart = $content['Charts'][ $content['CHARTID'] ]; - // Copy basic properties $content['Name'] = $myChart['DisplayName']; $content['chart_type'] = $myChart['chart_type']; @@ -216,7 +216,8 @@ if ( isset($_GET['op']) ) // Chart Field $content['chart_field'] = $myChart['chart_field']; CreateChartFields($content['chart_field']); - + $content['chart_orderby'] = $myChart['chart_orderby']; + // COMMON Fields $content['userid'] = $myChart['userid']; if ( $content['userid'] != null ) @@ -317,6 +318,7 @@ if ( isset($_POST['op']) ) if ( isset($_POST['chart_type']) ) { $content['chart_type'] = intval(DB_RemoveBadChars($_POST['chart_type'])); } if ( isset($_POST['chart_width']) ) { $content['chart_width'] = intval(DB_RemoveBadChars($_POST['chart_width'])); } else {$content['chart_width'] = 400; } if ( isset($_POST['chart_field']) ) { $content['chart_field'] = DB_RemoveBadChars($_POST['chart_field']); } + if ( isset($_POST['chart_orderby']) ) { $content['chart_orderby'] = DB_RemoveBadChars($_POST['chart_orderby']); } if ( isset($_POST['maxrecords']) ) { $content['maxrecords'] = intval(DB_RemoveBadChars($_POST['maxrecords'])); } if ( isset($_POST['showpercent']) ) { $content['showpercent'] = intval(DB_RemoveBadChars($_POST['showpercent'])); } else {$content['showpercent'] = 0; } if ( isset($_POST['chart_defaultfilter']) ) { $content['chart_defaultfilter'] = DB_RemoveBadChars($_POST['chart_defaultfilter']); } @@ -369,12 +371,13 @@ if ( isset($_POST['op']) ) if ( $_POST['op'] == "addnewchart" ) { // Add custom search now! - $sqlquery = "INSERT INTO " . DB_CHARTS . " (DisplayName, chart_enabled, chart_type, chart_width, chart_field, chart_defaultfilter, maxrecords, showpercent, userid, groupid) + $sqlquery = "INSERT INTO " . DB_CHARTS . " (DisplayName, chart_enabled, chart_type, chart_width, chart_field, chart_orderby, chart_defaultfilter, maxrecords, showpercent, userid, groupid) VALUES ('" . $content['Name'] . "', " . $content['chart_enabled'] . ", " . $content['chart_type'] . ", " . $content['chart_width'] . ", '" . $content['chart_field'] . "', + '" . $content['chart_orderby'] . "', '" . $content['chart_defaultfilter'] . "', " . $content['maxrecords'] . ", " . $content['showpercent'] . ", @@ -405,6 +408,7 @@ if ( isset($_POST['op']) ) chart_type = " . $content['chart_type'] . ", chart_width = " . $content['chart_width'] . ", chart_field = '" . $content['chart_field'] . "', + chart_orderby = '" . $content['chart_orderby'] . "', chart_defaultfilter = '" . $content['chart_defaultfilter'] . "', maxrecords = " . $content['maxrecords'] . ", showpercent = " . $content['showpercent'] . ", @@ -514,6 +518,12 @@ if ( !isset($_POST['op']) && !isset($_GET['op']) ) $myChart['chart_defaultfilter_urldecoded'] = urlencode($myChart['chart_defaultfilter']); else $myChart['chart_defaultfilter_urldecoded'] = ""; + + if ( ( isset($myChart['chart_orderby']) ) && ( strlen($myChart['chart_orderby']) > 0 ) ) + $myChart['chart_orderby_urldecoded'] = urlencode($myChart['chart_orderby']); + else + $myChart['chart_orderby_urldecoded'] = ""; + // --- // --- Set CSS Class @@ -544,4 +554,4 @@ $page -> parser($content, "admin/admin_charts.html"); $page -> output(); // --- -?> \ No newline at end of file +?> diff --git a/src/chartgenerator.php b/src/chartgenerator.php index d52e9a9..20bd30d 100644 --- a/src/chartgenerator.php +++ b/src/chartgenerator.php @@ -98,6 +98,11 @@ else $content['error_details'] = $content['LN_GEN_ERROR_MISSINGCHARTFIELD']; } +if ( isset($_GET['orderby']) ) +{ + $content['chart_orderby'] = $_GET['orderby']; +}else { $content['chart_orderby'] = NULL; } + if ( isset($_GET['maxrecords']) ) { // read and verify value @@ -148,7 +153,7 @@ if ( !$content['error_occured'] ) { // Obtain and get the Config Object $stream_config = $content['Sources'][$currentSourceID]['ObjRef']; - + //echo "filter:".$content['chart_defaultfilter']."
"; // Create LogStream Object $stream = $stream_config->LogStreamFactory($stream_config); $stream->SetFilter($content['chart_defaultfilter']); @@ -160,7 +165,7 @@ if ( !$content['error_occured'] ) if ( $aFilterFields != null ) $content['ChartColumns'] = $aFilterFields; - // Append mandetory fields + // Append mandatory fields if ( !in_array(SYSLOG_UID, $content['ChartColumns']) ) $content['ChartColumns'][] = SYSLOG_UID; if ( !in_array($content['chart_field'], $content['ChartColumns']) ) @@ -182,9 +187,9 @@ if ( !$content['error_occured'] ) // Split key and value $tmpArray = explode(":", $myFilter, 2); - // Check if keyfield is valid and add to our Columns array if available + // Check if keyfield is valid and add to our Columns array only if it's not there yet $newField = $stream->ReturnFilterKeyBySearchField($tmpArray[FILTER_TMP_KEY]); - if ( $newField ) + if ( $newField && !in_array($newField,$content['ChartColumns'])) $content['ChartColumns'][] = $newField; } } @@ -195,8 +200,8 @@ if ( !$content['error_occured'] ) if ( $res == SUCCESS ) { // Obtain data from the logstream! - $chartData = $stream->GetCountSortedByField($content['chart_field'], $content['chart_fieldtype'], $content['maxrecords']); - + $chartData = $stream->GetCountSortedByField($content['chart_field'], $content['chart_fieldtype'], $content['maxrecords'], $content['chart_orderby']); +//echo "
";echo print_r($chartData); echo "

"; // If data is valid, we have an array! if ( is_array($chartData) && count($chartData) > 0 ) { @@ -210,7 +215,7 @@ if ( !$content['error_occured'] ) $YchartData[] = intval($myData); $XchartData[] = strlen($myKey) > 0 ? $myKey : "Unknown"; if ( isset($fields[$content['chart_field']]['SearchField']) && strlen($myKey) > 0 ) - $chartImageMapLinks[] = $content['custombasepath'] . "index.php?filter=" . $fields[$content['chart_field']]['SearchField'] . "%3A%3D" . urlencode($szEncodedKeyStr) . "&search=Search"; + $chartImageMapLinks[] = $content['custombasepath'] . "index.php?filter=" . $fields[$content['chart_field']]['SearchField'] . "%3A%3D" . urlencode($szEncodedKeyStr) .(empty($content['chart_defaultfilter'])?"":urlencode(" ".$content['chart_defaultfilter'])). "&search=Search"; else $chartImageMapLinks[] = ""; @@ -552,4 +557,4 @@ function OutpuCustomErrorMessage() { // Exit in any case exit; } -?> \ No newline at end of file +?> diff --git a/src/classes/logstreamdb.class.php b/src/classes/logstreamdb.class.php index ab3fc8c..86b7062 100644 --- a/src/classes/logstreamdb.class.php +++ b/src/classes/logstreamdb.class.php @@ -1270,8 +1270,11 @@ class LogStreamDB extends LogStream { * * @return integer Error stat */ - public function GetCountSortedByField($szFieldId, $nFieldType, $nRecordLimit) + public function GetCountSortedByField($szFieldId, $nFieldType, $nRecordLimit, $orderBy='') { + if(empty($orderBy)){ + $orderBy = 'totalcount DESC'; + } global $content, $dbmapping; // Copy helper variables, this is just for better readability @@ -1283,13 +1286,14 @@ class LogStreamDB extends LogStream { $myDBFieldName = $dbmapping[$szTableType]['DBMAPPINGS'][$szFieldId]; $myDBQueryFieldName = $myDBFieldName; $mySelectFieldName = $myDBFieldName; - + // Special handling for date fields if ( $nFieldType == FILTER_TYPE_DATE ) { // Helper variable for the select statement $mySelectFieldName = $mySelectFieldName . "grouped"; $myDBQueryFieldName = "DATE( " . $myDBFieldName . ") AS " . $mySelectFieldName ; + //$orderBy = $mySelectFieldName." DESC"; } // Create SQL Where Clause! @@ -1307,7 +1311,7 @@ class LogStreamDB extends LogStream { " FROM `" . $this->_logStreamConfigObj->DBTableName . "`" . $this->_SQLwhereClause . " GROUP BY " . $mySelectFieldName . - " ORDER BY totalcount DESC" . + " ORDER BY ".$orderBy. " LIMIT " . $nRecordLimit; // Perform Database Query @@ -1365,6 +1369,7 @@ class LogStreamDB extends LogStream { // --- Build Query Array $arrayQueryProperties = $this->_arrProperties; + //"
".$arrayQueryProperties."

" if ( isset($this->_arrFilterProperties) && $this->_arrFilterProperties != null) { foreach ( $this->_arrFilterProperties as $filterproperty ) @@ -1373,8 +1378,9 @@ class LogStreamDB extends LogStream { $arrayQueryProperties[] = $filterproperty; } } - // --- - + // --- + //echo 'DEBUG
'; print_r($arrayQueryProperties); echo '
'; + //echo 'DEBUG
'; print_r($this->_filters); echo '
'; // Loop through all available properties foreach( $arrayQueryProperties as $propertyname ) { @@ -1496,26 +1502,8 @@ class LogStreamDB extends LogStream { if ( $myfilter[FILTER_DATEMODE] == DATEMODE_LASTX ) { // Get current timestamp - $nNowTimeStamp = time() - (60 * 60 * intval($myfilter[FILTER_VALUE])); - /*if ( $myfilter[FILTER_VALUE] == DATE_LASTX_HOUR ) - $nNowTimeStamp -= 60 * 60; // One Hour! - else if ( $myfilter[FILTER_VALUE] == DATE_LASTX_12HOURS ) - $nNowTimeStamp -= 60 * 60 * 12; // 12 Hours! - else if ( $myfilter[FILTER_VALUE] == DATE_LASTX_24HOURS ) - $nNowTimeStamp -= 60 * 60 * 24; // 24 Hours! - else if ( $myfilter[FILTER_VALUE] == DATE_LASTX_7DAYS ) - $nNowTimeStamp -= 60 * 60 * 24 * 7; // 7 days - else if ( $myfilter[FILTER_VALUE] == DATE_LASTX_31DAYS ) - $nNowTimeStamp -= 60 * 60 * 24 * 31; // 31 days - else - { - // Set filter to unknown and Abort in this case! - $tmpfilters[$propertyname][FILTER_TYPE] = FILTER_TYPE_UNKNOWN; - break; - }*/ - // Append filter $tmpfilters[$propertyname][FILTER_VALUE] .= $dbmapping[$szTableType]['DBMAPPINGS'][$propertyname] . " > '" . date("Y-m-d H:i:s", $nNowTimeStamp) . "'"; } @@ -1554,7 +1542,6 @@ class LogStreamDB extends LogStream { } } } - // Check and combine all filters now! if ( isset($tmpfilters) ) { @@ -1587,7 +1574,7 @@ class LogStreamDB extends LogStream { } } -// echo $this->_SQLwhereClause; +//echo $this->_SQLwhereClause."
"; //$dbmapping[$szTableType][SYSLOG_UID] } else // No filters means nothing to do! diff --git a/src/include/db_update_v14.txt b/src/include/db_update_v14.txt new file mode 100644 index 0000000..27ce130 --- /dev/null +++ b/src/include/db_update_v14.txt @@ -0,0 +1,7 @@ +-- New Database Structure Updates +ALTER TABLE `logcon_charts` ADD `chart_orderby` VARCHAR( 255 ) NULL AFTER `chart_defaultfilter` ; + + +-- Insert data + +-- Updated Data diff --git a/src/include/functions_common.php b/src/include/functions_common.php index cef4820..c30bbf7 100644 --- a/src/include/functions_common.php +++ b/src/include/functions_common.php @@ -510,6 +510,8 @@ function CreateReloadTimesList() $tmpReloadSeconds = GetConfigSetting("ViewEnableAutoReloadSeconds", "", CFGLEVEL_USER); if ( $tmpReloadSeconds > 0 ) { + //by default select predefined value + $_SESSION['AUTORELOAD_ID'] = 1; $content['reloadtimes'][$iCounter] = array( "ID" => $iCounter, "Selected" => "", "DisplayName" => $content['LN_AUTORELOAD_PRECONFIGURED'] . " (" . $tmpReloadSeconds . " " . $content['LN_AUTORELOAD_SECONDS'] . ") ", "Value" => $tmpReloadSeconds ); $iCounter++; } $content['reloadtimes'][$iCounter] = array( "ID" => $iCounter, "Selected" => "", "DisplayName" => " 5 " . $content['LN_AUTORELOAD_SECONDS'], "Value" => 5 ); $iCounter++; diff --git a/src/include/functions_config.php b/src/include/functions_config.php index fd8e647..d5189c3 100644 --- a/src/include/functions_config.php +++ b/src/include/functions_config.php @@ -930,7 +930,8 @@ function LoadChartsFromDatabase() DB_CHARTS . ".chart_enabled, " . DB_CHARTS . ".chart_type, " . DB_CHARTS . ".chart_width, " . - DB_CHARTS . ".chart_field, " . + DB_CHARTS . ".chart_field, " . + DB_CHARTS . ".chart_orderby, " . DB_CHARTS . ".chart_defaultfilter, " . DB_CHARTS . ".maxrecords, " . DB_CHARTS . ".showpercent, " . diff --git a/src/index.php b/src/index.php index bcc18a2..c69fc8a 100644 --- a/src/index.php +++ b/src/index.php @@ -122,11 +122,14 @@ $content['main_pager_last_found'] = false; // Init Sorting variables $content['sorting'] = ""; $content['searchstr'] = ""; -$content['searchstr_htmlform'] = "datelastx:6"; +$content['searchstr_htmlform'] = "datelastx:6 severity:-8"; $content['highlightstr'] = ""; $content['highlightstr_htmlform'] = ""; $content['EXPAND_HIGHLIGHT'] = "false"; +// hide header by default +$_SESSION['SESSION_MAXIMIZED'] = true; + // --- Read and process filters from search dialog! if ( (isset($_POST['search']) || isset($_GET['search'])) || (isset($_POST['filter']) || isset($_GET['filter'])) ) { diff --git a/src/statistics.php b/src/statistics.php index 8e3fe37..1709793 100644 --- a/src/statistics.php +++ b/src/statistics.php @@ -110,6 +110,12 @@ if ( isset($content['Charts']) ) $myChart['chart_defaultfilter_urldecoded'] = urlencode($myChart['chart_defaultfilter']); else $myChart['chart_defaultfilter_urldecoded'] = ""; + + if ( isset($myChart['chart_orderby']) && strlen($myChart['chart_orderby']) > 0 ) + $myChart['chart_orderby_urldecoded'] = urlencode($myChart['chart_orderby']); + else + $myChart['chart_orderby_urldecoded'] = ""; + // --- // --- Set CSS Class @@ -159,4 +165,4 @@ $page -> output(); //include($gl_root_path . 'include/functions_installhelpers.php'); //ConvertCustomCharts(); -?> \ No newline at end of file +?> diff --git a/src/templates/admin/admin_charts.html b/src/templates/admin/admin_charts.html index 1e64b1c..fbadec3 100644 --- a/src/templates/admin/admin_charts.html +++ b/src/templates/admin/admin_charts.html @@ -68,7 +68,7 @@   - \ No newline at end of file + diff --git a/src/templates/statistics.html b/src/templates/statistics.html index 3417ad7..450f2e4 100644 --- a/src/templates/statistics.html +++ b/src/templates/statistics.html @@ -43,6 +43,15 @@ {LN_CHART_FIELD}  {CHART_FIELD_DISPLAYNAME} + + {LN_CHART_ORDERBY} +  {chart_orderby} + + + {LN_CHART_FILTER} +  {chart_defaultfilter} + + {LN_CHART_WIDTH}  {chart_width} @@ -59,7 +68,7 @@
@@ -70,4 +79,4 @@ - \ No newline at end of file + From ed8e4f225669a99f6a2a7dcd9139b045c753ffdd Mon Sep 17 00:00:00 2001 From: Vitaly Date: Wed, 4 Jan 2023 00:07:48 +0200 Subject: [PATCH 12/18] Update README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 67b9b40..f0391db 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ -![loganalizer_example](https://user-images.githubusercontent.com/8426197/209875963-b7438f3b-9052-4e8f-9f22-05794e1e54a5.png) # loganalyzer + +![loganalizer_example](https://user-images.githubusercontent.com/8426197/209875963-b7438f3b-9052-4e8f-9f22-05794e1e54a5.png) Adiscon LogAnalyzer, a web frontend to log data from the same folks the created rsyslog # changes @@ -7,6 +8,8 @@ Adiscon LogAnalyzer, a web frontend to log data from the same folks the created - fix chart double adding same key into search - allow to configure ORDER BY clause - add custom filter to chart value redirection link if such exists + +![chart_custom](https://user-images.githubusercontent.com/8426197/210448944-9a67c91c-1ca7-4f00-99ac-a5eebd566927.png) - support number ranges in filter, i.e. severity:3-6 -> where severity in (3,4,5,6) - support quoted filters, i.e. syslogtag:-="dhcp,info",-="wireless,info",-"system%,account" -> where (syslogtag <> 'dhcp,info' AND syslogtag <> 'wireless,info' AND syslogtag NOT LIKE '%system%,account%' ) - support TRACE syslog level; From 4845e6fc37d01fab05a3c70a1414f8fb6b14a8fb Mon Sep 17 00:00:00 2001 From: Vitaly X Date: Sun, 15 Jan 2023 01:50:06 +0200 Subject: [PATCH 13/18] Custom trace; bug fixes; txt plain export; page limit; See Readme for details. --- .gitignore | 2 + README.md | 35 ++++++++++--- src/admin/index.php | 13 +++++ src/classes/logstream.class.php | 60 ++++++++++++----------- src/classes/logstreamdb.class.php | 39 +++++++++++---- src/details.php | 2 +- src/export.php | 55 ++++++++++++--------- src/include/config.sample.php | 14 ++++-- src/include/constants_filters.php | 2 +- src/include/constants_general.php | 5 +- src/include/functions_common.php | 13 ++++- src/include/functions_filters.php | 2 +- src/include/functions_frontendhelpers.php | 12 +++-- src/index.php | 6 +-- src/lang/en/admin.php | 3 ++ src/lang/en/main.php | 3 ++ src/templates/admin/admin_index.html | 24 +++++++++ src/templates/admin/admin_searches.html | 4 +- src/templates/index.html | 2 +- 19 files changed, 204 insertions(+), 92 deletions(-) diff --git a/.gitignore b/.gitignore index 3809eae..019eeb7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ src/config.php +*.bak +src/index.html diff --git a/README.md b/README.md index 67b9b40..3f20447 100644 --- a/README.md +++ b/README.md @@ -2,19 +2,38 @@ # loganalyzer Adiscon LogAnalyzer, a web frontend to log data from the same folks the created rsyslog +# changes 230114 + - fix bug: WHERE ( message LIKE '%LTE%unreachable%' ) give no result on filter page, yet works for charts, i.e. input = msg:LTE%unreachable (todo# in chart records have wrong date today merged with yesterday) + - cfg[EventEmptySearchDefaultFilter] - config to use in case filter is empty (first load) + - cfg[ExportUseTodayYesterday] - allow to export date in case today/yesterday enabled + - CFG[Default_AUTORELOAD_ID] - control default autoreload mode + - cfg[SESSION_MAXIMIZED] - control maximized mode + - filter: support "limit:int" tag - disable paging and query less than configured for page (LogStreamDB->_SQLcustomLimitHaltSearchAfter) + - filter: datelastx - handle as float number + - export: allow to EXPORT_PLAIN text format + - custom bug fixes + - rename SYSLOG_TRACE to CUSTOM_TRACE; + - translations: {LN_CHART_ORDERBY, LN_CHART_FILTER, LN_GEN_EMPTYSRCHFILTR, LN_GEN_EXPORT_PLAIN, LN_GEN_EXPORT_USETODAY, LN_GEN_SESSION_MAX} + # changes - - Maximize view by default - - fix chart double adding same key into search + - fix bug: chart double adding same key into search - allow to configure ORDER BY clause - add custom filter to chart value redirection link if such exists - - support number ranges in filter, i.e. severity:3-6 -> where severity in (3,4,5,6) - - support quoted filters, i.e. syslogtag:-="dhcp,info",-="wireless,info",-"system%,account" -> where (syslogtag <> 'dhcp,info' AND syslogtag <> 'wireless,info' AND syslogtag NOT LIKE '%system%,account%' ) - - support TRACE syslog level; - - add loglevel style colors and change color for full line; - - limit empty search to 6h; - - change datelastx behaviour - use number as hours indicator, i.e. datelastx:3 is 3 hours limit + - filter: support number ranges, i.e. severity:3-6 -> where severity in (3,4,5,6) + - filter: support quoted filters, i.e. syslogtag:-="dhcp,info",-="wireless,info",-"system%,account" -> where (syslogtag <> 'dhcp,info' AND syslogtag <> 'wireless,info' AND syslogtag NOT LIKE '%system%,account%' ) + - filter: support TRACE severity level; + - gui: add loglevel style colors and change color for full line; + - filter: change datelastx behaviour - use number as hours indicator, i.e. datelastx:3 is 3 hours limit # todo + - export: add checkbox to export full filtered history (now exports selected page only) + - export: configure columns for file export (allow to remove unnecessary columns) <- exclude list of columns + - export: place ts into export filename (range from-to) + + #obsolete + - filter: allow to OR msg, i.e. key1 &key2 |key3; + - filter: date{from,to} - allow to use today/yesterday + short time, i.e. today 1h same as 1h, yesterday 2h, since/after/before/etc. - "Maximize view" - reloads page and resets search filter, hide toolbars with js instead - changing "Autoreload" does the same as "Max. view" - allow to manually configure log levels (severity) instead of using constants + - cfg[ExportCSVDelimiter,ExportCSVQuoteValues] - allow to EXPORT_PLAIN text format diff --git a/src/admin/index.php b/src/admin/index.php index 0cc3c48..8f39e15 100644 --- a/src/admin/index.php +++ b/src/admin/index.php @@ -167,6 +167,8 @@ if ( isset($_POST['op']) ) if ( isset ($_POST['DefaultFontSize']) ) { $content['DefaultFontSize'] = $_POST['DefaultFontSize']; } // Read checkboxes + if ( isset ($_POST['ExportUseTodayYesterday']) ) { $content['ExportUseTodayYesterday'] = 1; } else { $content['ExportUseTodayYesterday'] = 0; } + if ( isset ($_POST['SESSION_MAXIMIZED']) ) { $content['SESSION_MAXIMIZED'] = 1; } else { $content['SESSION_MAXIMIZED'] = 0; } if ( isset ($_POST['ViewUseTodayYesterday']) ) { $content['ViewUseTodayYesterday'] = 1; } else { $content['ViewUseTodayYesterday'] = 0; } if ( isset ($_POST['ViewEnableDetailPopups']) ) { $content['ViewEnableDetailPopups'] = 1; } else { $content['ViewEnableDetailPopups'] = 0; } if ( isset ($_POST['EnableContextLinks']) ) { $content['EnableContextLinks'] = 1; } else { $content['EnableContextLinks'] = 0; } @@ -195,6 +197,7 @@ if ( isset($_POST['op']) ) if ( isset ($_POST['PrependTitle']) ) { $content['PrependTitle'] = $_POST['PrependTitle']; } if ( isset ($_POST['SearchCustomButtonCaption']) ) { $content['SearchCustomButtonCaption'] = $_POST['SearchCustomButtonCaption']; } if ( isset ($_POST['SearchCustomButtonSearch']) ) { $content['SearchCustomButtonSearch'] = $_POST['SearchCustomButtonSearch']; } + if ( isset ($_POST['EventEmptySearchDefaultFilter']) ) { $content['EventEmptySearchDefaultFilter'] = $_POST['EventEmptySearchDefaultFilter']; } if ( isset ($_POST['InjectHtmlHeader']) ) { $content['InjectHtmlHeader'] = $_POST['InjectHtmlHeader']; } if ( isset ($_POST['InjectBodyHeader']) ) { $content['InjectBodyHeader'] = $_POST['InjectBodyHeader']; } @@ -256,6 +259,8 @@ if ( isset($_POST['op']) ) if ( isset ($_POST['User_PrependTitle']) ) { $USERCFG['PrependTitle'] = $_POST['User_PrependTitle']; } if ( isset ($_POST['User_SearchCustomButtonCaption']) ) { $USERCFG['SearchCustomButtonCaption'] = $_POST['User_SearchCustomButtonCaption']; } if ( isset ($_POST['User_SearchCustomButtonSearch']) ) { $USERCFG['SearchCustomButtonSearch'] = $_POST['User_SearchCustomButtonSearch']; } + if ( isset ($_POST['User_EventEmptySearchDefaultFilter']) ) { $USERCFG['EventEmptySearchDefaultFilter'] = $_POST['User_EventEmptySearchDefaultFilter']; } + // Save configuration variables now SaveUserGeneralSettingsIntoDB(); @@ -273,6 +278,9 @@ if ( !isset($content['InlineOnlineSearchIcons']) ) { $content['InlineOnlineSearc if ( !isset($content['AdminChangeWaitTime']) ) { $content['AdminChangeWaitTime'] = 2; } // Set checkbox States +if (isset($content['ExportUseTodayYesterday']) && $content['ExportUseTodayYesterday'] == 1) { $content['ExportUseTodayYesterday_checked'] = "checked"; } else { $content['ExportUseTodayYesterday_checked'] = ""; } +if (isset($content['SESSION_MAXIMIZED']) && $content['SESSION_MAXIMIZED'] == 1) { $content['SESSION_MAXIMIZED_checked'] = "checked"; } else { $content['SESSION_MAXIMIZED_checked'] = ""; } + if (isset($content['ViewUseTodayYesterday']) && $content['ViewUseTodayYesterday'] == 1) { $content['ViewUseTodayYesterday_checked'] = "checked"; } else { $content['ViewUseTodayYesterday_checked'] = ""; } if (isset($content['ViewEnableDetailPopups']) && $content['ViewEnableDetailPopups'] == 1) { $content['ViewEnableDetailPopups_checked'] = "checked"; } else { $content['ViewEnableDetailPopups_checked'] = ""; } if (isset($content['EnableContextLinks']) && $content['EnableContextLinks'] == 1) { $content['EnableContextLinks_checked'] = "checked"; } else { $content['EnableContextLinks_checked'] = ""; } @@ -388,6 +396,9 @@ foreach ( $content['ENCODINGS'] as &$myEncoding) if ( $content['ENABLEUSEROPTIONS'] ) { // Set checkbox States + if ( GetConfigSetting('ExportUseTodayYesterday', $content['ExportUseTodayYesterday'], CFGLEVEL_USER) == 1) { $content['User_ExportUseTodayYesterday_checked'] = "checked"; } else { $content['User_ExportUseTodayYesterday_checked'] = ""; } + if ( GetConfigSetting('SESSION_MAXIMIZED', $content['SESSION_MAXIMIZED'], CFGLEVEL_USER) == 1) { $content['User_SESSION_MAXIMIZED_checked'] = "checked"; } else { $content['User_SESSION_MAXIMIZED_checked'] = ""; } + if ( GetConfigSetting('ViewUseTodayYesterday', $content['ViewUseTodayYesterday'], CFGLEVEL_USER) == 1) { $content['User_ViewUseTodayYesterday_checked'] = "checked"; } else { $content['User_ViewUseTodayYesterday_checked'] = ""; } if ( GetConfigSetting('ViewEnableDetailPopups', $content['ViewEnableDetailPopups'], CFGLEVEL_USER) == 1) { $content['User_ViewEnableDetailPopups_checked'] = "checked"; } else { $content['User_ViewEnableDetailPopups_checked'] = ""; } if ( GetConfigSetting('EnableContextLinks', $content['EnableContextLinks'], CFGLEVEL_USER) == 1) { $content['User_EnableContextLinks_checked'] = "checked"; } else { $content['User_EnableContextLinks_checked'] = ""; } @@ -412,6 +423,8 @@ if ( $content['ENABLEUSEROPTIONS'] ) $content['User_AdminChangeWaitTime'] = GetConfigSetting('AdminChangeWaitTime', $content['AdminChangeWaitTime'], CFGLEVEL_USER); $content['User_SearchCustomButtonCaption'] = GetConfigSetting('SearchCustomButtonCaption', $content['SearchCustomButtonCaption'], CFGLEVEL_USER); $content['User_SearchCustomButtonSearch'] = GetConfigSetting('SearchCustomButtonSearch', $content['SearchCustomButtonSearch'], CFGLEVEL_USER); + $content['User_EventEmptySearchDefaultFilter'] = GetConfigSetting('EventEmptySearchDefaultFilter', $content['EventEmptySearchDefaultFilter'], CFGLEVEL_USER); + // --- // --- Init for ViewDefaultTheme field! diff --git a/src/classes/logstream.class.php b/src/classes/logstream.class.php index 27f30b7..0d26a6b 100644 --- a/src/classes/logstream.class.php +++ b/src/classes/logstream.class.php @@ -472,19 +472,21 @@ abstract class LogStream { // Only filter if value is non zero if ( strlen($propertyvalue) > 0 && strlen($myfilter[FILTER_VALUE]) > 0 ) { + //check for % inside keyword and handle it accordingly, i.e. "key1%key2" + $strPosLike = strpos($myfilter[FILTER_VALUE], "%"); // If Syslog message, we have AND handling! if ( $propertyname == SYSLOG_MESSAGE ) { // Include Filter if ( $myfilter[FILTER_MODE] & FILTER_MODE_INCLUDE ) { - if ( stripos($propertyvalue, $myfilter[FILTER_VALUE]) === false ) + if ( stripos($propertyvalue, $myfilter[FILTER_VALUE]) === false && $strPosLike === false ) $bEval = false; } // Exclude Filter else if ( $myfilter[FILTER_MODE] & FILTER_MODE_EXCLUDE ) { - if ( stripos($propertyvalue, $myfilter[FILTER_VALUE]) !== false ) + if ( stripos($propertyvalue, $myfilter[FILTER_VALUE]) !== false && $strPosLike !== false) $bEval = false; } } @@ -566,25 +568,12 @@ abstract class LogStream { $nLogTimeStamp = $arrProperitesOut[$propertyname][EVTIME_TIMESTAMP]; if ( $myfilter[FILTER_DATEMODE] == DATEMODE_LASTX ) { - // Get current timestamp - $nNowTimeStamp = time(); + //datelastx:x handle x as hours instead of constant + //Get range timestamp + $nLastXTime = time() - (60 * 60 * floatval($myfilter[FILTER_VALUE])); - if ( $myfilter[FILTER_VALUE] == DATE_LASTX_HOUR ) - $nLastXTime = 60 * 60; // One Hour! - else if ( $myfilter[FILTER_VALUE] == DATE_LASTX_12HOURS ) - $nLastXTime = 60 * 60 * 12; // 12 Hours! - else if ( $myfilter[FILTER_VALUE] == DATE_LASTX_24HOURS ) - $nLastXTime = 60 * 60 * 24; // 24 Hours! - else if ( $myfilter[FILTER_VALUE] == DATE_LASTX_7DAYS ) - $nLastXTime = 60 * 60 * 24 * 7; // 7 days - else if ( $myfilter[FILTER_VALUE] == DATE_LASTX_31DAYS ) - $nLastXTime = 60 * 60 * 24 * 31; // 31 days - else - // WTF default? - $nLastXTime = 86400; - - // If Nowtime + LastX is higher then the log timestamp, the this logline is to old for us. - if ( ($nNowTimeStamp - $nLastXTime) > $nLogTimeStamp ) + // If Nowtime + LastX is higher then the log timestamp, then this logline is too old for us. + if ( $nLastXTime > $nLogTimeStamp ) $bEval = false; } else if ( $myfilter[FILTER_DATEMODE] == DATEMODE_RANGE_FROM ) @@ -768,7 +757,7 @@ abstract class LogStream { { // Split key and value $tmpArray = explode(":", $myEntry, 2); -//print_r ( $tmpArray ); + //echo "DEBUG:
"; print_r (  $tmpArray ); echo "
"; // Continue if empty filter! if ( strlen(trim($tmpArray[FILTER_TMP_VALUE])) == 0 ) @@ -792,12 +781,9 @@ abstract class LogStream { if($numberRange){ //echo "#range#end#"; - $range = $rangeStart; - for($j = $rangeStart; $j < intval($strChar); $j++){ - $range .= ($j == $rangeStart)?(""):(",").$j; + for($j = $rangeStart; $j < intval($strChar)+1; $j++){ + $tmpValues[] = array( FILTER_TMP_MODE => $this->SetFilterIncludeMode($j), FILTER_TMP_VALUE => $j); } - $tmpValues[] = array( FILTER_TMP_MODE => $this->SetFilterIncludeMode($range), FILTER_TMP_VALUE => $range); - $myValueEntry = ''; $rangeStart = 0; $numberRange = false; @@ -848,11 +834,27 @@ abstract class LogStream { } } + }else{ + //parse severity number range, i.e. 1-8 into 1,2,3,4,5,6,7,8 + if($tmpArray[FILTER_TMP_KEY] == "severity" && !isset($tmpValues) && strpos($tmpArray[FILTER_TMP_VALUE],"-")){ + $rangeBounds = explode("-", $tmpArray[FILTER_TMP_VALUE]); + for($j = intval($rangeBounds[0]); $j < intval($rangeBounds[1])+1; $j++){ + $tmpValues[] = array( FILTER_TMP_MODE => $this->SetFilterIncludeMode($j), FILTER_TMP_VALUE => $j); + } + } } // Handle filter based switch( $tmpArray[FILTER_TMP_KEY] ) { + case "limit": + $defaultPageLimit = GetConfigSetting("ViewEntriesPerPage", 50, CFGLEVEL_USER); + if($tmpArray[FILTER_TMP_VALUE] < $defaultPageLimit){ + $this->_filters["limit"][FILTER_VALUE] = $tmpArray[FILTER_TMP_VALUE]; + }else + $this->_filters["limit"][FILTER_VALUE] = $defaultPageLimit; + break; + case "facility": $tmpKeyName = SYSLOG_FACILITY; $tmpFilterType = FILTER_TYPE_NUMBER; @@ -1285,7 +1287,7 @@ abstract class LogStream { $pos = strpos($szValue, "+"); if ( $pos !== false && $pos == 0 ) { - //trunscate + + //truncate + $szValue = substr( $szValue, 1); $myBits = FILTER_MODE_INCLUDE; } @@ -1303,7 +1305,7 @@ abstract class LogStream { $pos = strpos($szValue, "="); if ( $pos !== false && $pos == 0 ) { - //trunscate - + //truncate - $szValue = substr( $szValue, 1); // Add BIT if not NUMBER FIELD! @@ -1315,7 +1317,7 @@ abstract class LogStream { $pos = strpos($szValue, "~"); if ( $pos !== false && $pos == 0 ) { - //trunscate - + //truncate - $szValue = substr( $szValue, 1); // Add BIT if not NUMBER FIELD! if ( $myFilterType != FILTER_TYPE_NUMBER ) diff --git a/src/classes/logstreamdb.class.php b/src/classes/logstreamdb.class.php index 86b7062..c7ab5d3 100644 --- a/src/classes/logstreamdb.class.php +++ b/src/classes/logstreamdb.class.php @@ -62,6 +62,7 @@ class LogStreamDB extends LogStream { private $_SQLwhereClause = ""; private $_myDBQuery = null; + private $_SQLcustomLimitHaltSearchAfter = null; //if set, then search will stop after getting this records // Constructor public function __construct ($streamConfigObj) { @@ -545,6 +546,12 @@ class LogStreamDB extends LogStream { $ret = $this->ReadNextRecordsFromDB($uID); else { + // Override default value if custom limit is less - act as tail without paging + // NB it won't work if custom limit gt page limit + $limit = $this->_SQLcustomLimitHaltSearchAfter; + if(isset($limit) && $this->_currentRecordNum >= $limit) + $ret = ERROR_NOMORERECORDS; + if ( !isset($this->bufferedRecords[$this->_currentRecordNum] ) ) { // We need to load new records, so clear the old ones first! @@ -590,7 +597,6 @@ class LogStreamDB extends LogStream { if ( isset($arrProperitesOut[SYSLOG_MESSAGE]) ) { $retParser = $this->_logStreamConfigObj->ProcessMsgParsers($arrProperitesOut[SYSLOG_MESSAGE], $arrProperitesOut); - // Check if we have to skip the message! if ( $retParser == ERROR_MSG_SKIPMESSAGE ) $ret = $retParser; @@ -618,7 +624,7 @@ class LogStreamDB extends LogStream { // This additional filter check will take care on dynamic fields from the message parser! } while ( $this->ApplyFilters($ret, $arrProperitesOut) != SUCCESS && $ret == SUCCESS ); - + // reached here means return result! return $ret; } @@ -1350,7 +1356,7 @@ class LogStreamDB extends LogStream { /* - * ============= Beginn of private functions ============= + * ============= Begin of private functions ============= */ /* @@ -1361,6 +1367,11 @@ class LogStreamDB extends LogStream { { if ( $this->_filters != null ) { + //if filter limit set, then apply it to a query + if( isset($this->_filters['limit']) ){ + $this->_SQLcustomLimitHaltSearchAfter= $this->_filters['limit'][FILTER_VALUE]; + } + global $dbmapping; $szTableType = $this->_logStreamConfigObj->DBTableType; @@ -1379,8 +1390,8 @@ class LogStreamDB extends LogStream { } } // --- - //echo 'DEBUG
'; print_r($arrayQueryProperties); echo '
'; - //echo 'DEBUG
'; print_r($this->_filters); echo '
'; + //echo 'DEBUG
'; print_r($arrayQueryProperties); echo '
'; + //echo 'DEBUG
'; print_r($this->_filters); echo '
'; // Loop through all available properties foreach( $arrayQueryProperties as $propertyname ) { @@ -1502,7 +1513,7 @@ class LogStreamDB extends LogStream { if ( $myfilter[FILTER_DATEMODE] == DATEMODE_LASTX ) { // Get current timestamp - $nNowTimeStamp = time() - (60 * 60 * intval($myfilter[FILTER_VALUE])); + $nNowTimeStamp = time() - (60 * 60 * floatval($myfilter[FILTER_VALUE])); // Append filter $tmpfilters[$propertyname][FILTER_VALUE] .= $dbmapping[$szTableType]['DBMAPPINGS'][$propertyname] . " > '" . date("Y-m-d H:i:s", $nNowTimeStamp) . "'"; @@ -1573,8 +1584,11 @@ class LogStreamDB extends LogStream { } } } - -//echo $this->_SQLwhereClause."
"; + + // print direct debug only on search page + //if(strpos($_SERVER['REQUEST_URI'], "export.php") === false && strpos($_SERVER['REQUEST_URI'], "chartgenerator.php") === false){ + // echo "DEBUG: ".$this->_SQLwhereClause."
"; + //} //$dbmapping[$szTableType][SYSLOG_UID] } else // No filters means nothing to do! @@ -1663,9 +1677,14 @@ class LogStreamDB extends LogStream { $szSql = $this->CreateSQLStatement($uID); // --- Append LIMIT - $szSql .= " LIMIT " . $this->_logStreamConfigObj->RecordsPerQuery; + // Override default value if custom is less - act as tail without paging + $limit = $this->_SQLcustomLimitHaltSearchAfter; + if ( isset($limit) === true && ($limit < $this->_logStreamConfigObj->RecordsPerQuery)){ + $szSql .= " LIMIT " . $limit; + }else + $szSql .= " LIMIT " . $this->_logStreamConfigObj->RecordsPerQuery; // --- - + // Perform Database Query $this->_myDBQuery = mysqli_query($this->_dbhandle, $szSql); if ( !$this->_myDBQuery ) diff --git a/src/details.php b/src/details.php index 739b10d..d94c3dd 100644 --- a/src/details.php +++ b/src/details.php @@ -117,7 +117,7 @@ if ( isset($_GET['direction']) ) } // Read filter property in - if ( isset($_POST['filter']) ) + if ( isset($_POST['filter']) ) $myfilter = $_POST['filter']; else if ( isset($_GET['filter']) ) $myfilter = $_GET['filter']; diff --git a/src/export.php b/src/export.php index 0c4dd5d..973c0b4 100644 --- a/src/export.php +++ b/src/export.php @@ -245,7 +245,7 @@ if ( !$content['error_occured'] ) // Now handle fields types differently if ( $content['fields'][$mycolkey]['FieldType'] == FILTER_TYPE_DATE ) { - $content['syslogmessages'][$counter][$mycolkey]['fieldvalue'] = GetFormatedDate($logArray[$mycolkey]); + $content['syslogmessages'][$counter][$mycolkey]['fieldvalue'] = GetFormatedDate($logArray[$mycolkey], true); } else if ( $content['fields'][$mycolkey]['FieldType'] == FILTER_TYPE_NUMBER ) { @@ -333,28 +333,33 @@ else $szOutputFileName = "ExportMessages"; $szOutputFileExtension = ".txt"; - if ( $content['exportformat'] == EXPORT_CVS ) - { + $szOPFieldSeparator = " "; + $szOPFirstLineFieldNames = true; + $szOPQuoteValues = false; + if( $content['exportformat'] == EXPORT_CVS ){ // Set MIME TYPE and File Extension - $szOutputMimeType = "text/csv"; - $szOutputFileExtension = ".csv"; + $szOutputMimeType = "text/csv"; + $szOutputFileExtension = ".csv"; + $szOPFieldSeparator = ","; + $szOPQuoteValues = true; + } - // Set Column line in cvs file! - foreach($content['Columns'] as $mycolkey) - { - if ( isset($fields[$mycolkey]) ) + if ( $content['exportformat'] == EXPORT_CVS || $content['exportformat'] == EXPORT_PLAIN) { + if($szOPFirstLineFieldNames === true){ + foreach($content['Columns'] as $mycolkey) { - // Prepend Comma if needed - if (strlen($szOutputContent) > 0) - $szOutputContent .= ","; + if ( isset($fields[$mycolkey]) ) + { + // Prepend Comma if needed + if (strlen($szOutputContent) > 0) $szOutputContent .= $szOPFieldSeparator; - // Append column name - $szOutputContent .= $fields[$mycolkey]['FieldCaption']; + // Append column name + $szOutputContent .= $fields[$mycolkey]['FieldCaption']; + } } - } - // Append line break - $szOutputContent .= "\n"; + $szOutputContent .= "\n"; + } // Append messages into output foreach ( $content['syslogmessages'] as $myIndex => $mySyslogMessage ) @@ -364,19 +369,23 @@ else // --- Process columns foreach($mySyslogMessage as $myColkey => $mySyslogField) { - // Prepend Comma if needed - if (strlen($szLine) > 0) - $szLine .= ","; + // Prepend separator if needed + if (strlen($szLine) > 0) $szLine .= $szOPFieldSeparator; // Append field contents - $szLine .= '"' . str_replace('"', '\\"', $mySyslogField['fieldvalue']) . '"'; + if($szOPQuoteValues === true) { + $szLine .= '"' . str_replace('"', '\\"', $mySyslogField['fieldvalue']) . '"'; + }else{ + $szLine .= $mySyslogField['fieldvalue']; + } } - // --- + // --- // Append line! $szOutputContent .= $szLine . "\n"; } - } + + } else if ( $content['exportformat'] == EXPORT_XML ) { // Set MIME TYPE and File Extension diff --git a/src/include/config.sample.php b/src/include/config.sample.php index cf39fc9..1ee46e8 100644 --- a/src/include/config.sample.php +++ b/src/include/config.sample.php @@ -80,6 +80,9 @@ $CFG['MiscMaxExecutionTime'] = 30; // LogAnalyzer will try to overwrite the de $CFG['DebugUserLogin'] = 0; // if enabled, you will see additional informations on failed logins // --- +// --- Default Export options +$CFG['ExportUseTodayYesterday'] = 0; // Same as ViewUseTodayYesterday. By default export normal dates + // --- Default Frontend Options $CFG['PrependTitle'] = ""; // If set, this text will be prepended withint the title tag $CFG['ViewUseTodayYesterday'] = 1; // If enabled, the date from today and yesterday is displayed as "today" and "yesterday" @@ -92,6 +95,9 @@ $CFG['ViewDefaultTheme'] = "default"; // This sets the default theme the user i $CFG['ViewDefaultLanguage'] = "en"; // Sets the default display language $CFG['ViewEnableAutoReloadSeconds'] = 0; // If "ViewEnableAutoReloadSeconds" is set to anything higher the 0 (which means disabled), this means auto reload is enabled by default. +$CFG['Default_AUTORELOAD_ID'] = 0; // By default disable autoreload (select id, 1 for user-defined) +$CFG['SESSION_MAXIMIZED'] = 0; // If enabled start session in maximized mode + $CFG['SearchCustomButtonCaption'] = "I'd like to feel sad"; // Default caption for the custom fast search button $CFG['SearchCustomButtonSearch'] = "error"; // Default search string for the custom search button @@ -125,10 +131,10 @@ $CFG['DefaultViewsID'] = ""; $CFG['Search'][] = array ( "DisplayName" => "Syslog Warnings and Errors", "SearchQuery" => "filter=severity%3A0%2C1%2C2%2C3%2C4&search=Search" ); $CFG['Search'][] = array ( "DisplayName" => "Syslog Errors", "SearchQuery" => "filter=severity%3A0%2C1%2C2%2C3&search=Search" ); $CFG['Search'][] = array ( "DisplayName" => "All messages from the last hour", "SearchQuery" => "filter=datelastx%3A1&search=Search" ); -$CFG['Search'][] = array ( "DisplayName" => "All messages from last 12 hours", "SearchQuery" => "filter=datelastx%3A2&search=Search" ); -$CFG['Search'][] = array ( "DisplayName" => "All messages from last 24 hours", "SearchQuery" => "filter=datelastx%3A3&search=Search" ); -$CFG['Search'][] = array ( "DisplayName" => "All messages from last 7 days", "SearchQuery" => "filter=datelastx%3A4&search=Search" ); -$CFG['Search'][] = array ( "DisplayName" => "All messages from last 31 days", "SearchQuery" => "filter=datelastx%3A5&search=Search" ); +$CFG['Search'][] = array ( "DisplayName" => "All messages from last 12 hours", "SearchQuery" => "filter=datelastx%3A12&search=Search" ); +$CFG['Search'][] = array ( "DisplayName" => "All messages from last 24 hours", "SearchQuery" => "filter=datelastx%3A24&search=Search" ); +$CFG['Search'][] = array ( "DisplayName" => "All messages from last 7 days", "SearchQuery" => "filter=datelastx%3A168&search=Search" ); +$CFG['Search'][] = array ( "DisplayName" => "All messages from last 31 days", "SearchQuery" => "filter=datelastx%3A744&search=Search" ); // $CFG['Search'][] = array ( "DisplayName" => "", "SearchQuery" => "" ); // --- diff --git a/src/include/constants_filters.php b/src/include/constants_filters.php index 11b74de..64384ce 100644 --- a/src/include/constants_filters.php +++ b/src/include/constants_filters.php @@ -109,7 +109,7 @@ $content['filter_severity_list'][] = array( "ID" => SYSLOG_WARNING, "DisplayName $content['filter_severity_list'][] = array( "ID" => SYSLOG_NOTICE, "DisplayName" => "NOTICE", "selected" => "" ); $content['filter_severity_list'][] = array( "ID" => SYSLOG_INFO, "DisplayName" => "INFO", "selected" => "" ); $content['filter_severity_list'][] = array( "ID" => SYSLOG_DEBUG, "DisplayName" => "DEBUG", "selected" => "" ); -$content['filter_severity_list'][] = array( "ID" => SYSLOG_TRACE, "DisplayName" => "TRACE", "selected" => "" ); +$content['filter_severity_list'][] = array( "ID" => CUSTOM_TRACE, "DisplayName" => "TRACE", "selected" => "" ); // --- diff --git a/src/include/constants_general.php b/src/include/constants_general.php index 993432c..cf571e1 100644 --- a/src/include/constants_general.php +++ b/src/include/constants_general.php @@ -76,6 +76,7 @@ define('SOURCE_CLICKHOUSE', '5'); // --- // --- Exportformat defines +define('EXPORT_PLAIN', 'TXT'); define('EXPORT_CVS', 'CVS'); define('EXPORT_XML', 'XML'); // --- @@ -169,7 +170,7 @@ define('SYSLOG_WARNING', 4); define('SYSLOG_NOTICE', 5); define('SYSLOG_INFO', 6); define('SYSLOG_DEBUG', 7); -define('SYSLOG_TRACE', 8); +define('CUSTOM_TRACE', 8); $severity_colors[SYSLOG_EMERG] = "#840A15"; $severity_colors[SYSLOG_ALERT] = "#BA0716"; @@ -179,7 +180,7 @@ $severity_colors[SYSLOG_WARNING] = "#EF8200"; $severity_colors[SYSLOG_NOTICE] = "#14AD42"; $severity_colors[SYSLOG_INFO] = "#0C9C91"; $severity_colors[SYSLOG_DEBUG] = "#119BDE"; -$severity_colors[SYSLOG_TRACE] = "#C0C381"; +$severity_colors[CUSTOM_TRACE] = "#C0C381"; // --- diff --git a/src/include/functions_common.php b/src/include/functions_common.php index c30bbf7..1252d1b 100644 --- a/src/include/functions_common.php +++ b/src/include/functions_common.php @@ -511,7 +511,7 @@ function CreateReloadTimesList() if ( $tmpReloadSeconds > 0 ) { //by default select predefined value - $_SESSION['AUTORELOAD_ID'] = 1; + $_SESSION['AUTORELOAD_ID'] = GetConfigSetting("Default_AUTORELOAD_ID", 0, CFGLEVEL_USER); $content['reloadtimes'][$iCounter] = array( "ID" => $iCounter, "Selected" => "", "DisplayName" => $content['LN_AUTORELOAD_PRECONFIGURED'] . " (" . $tmpReloadSeconds . " " . $content['LN_AUTORELOAD_SECONDS'] . ") ", "Value" => $tmpReloadSeconds ); $iCounter++; } $content['reloadtimes'][$iCounter] = array( "ID" => $iCounter, "Selected" => "", "DisplayName" => " 5 " . $content['LN_AUTORELOAD_SECONDS'], "Value" => 5 ); $iCounter++; @@ -537,6 +537,7 @@ function CreateExportFormatList() global $content; // Add basic formats! + $content['EXPORTTYPES'][EXPORT_PLAIN] = array( "ID" => EXPORT_PLAIN, "Selected" => "", "DisplayName" => $content['LN_GEN_EXPORT_PLAIN'] ); $content['EXPORTTYPES'][EXPORT_CVS] = array( "ID" => EXPORT_CVS, "Selected" => "", "DisplayName" => $content['LN_GEN_EXPORT_CVS'] ); $content['EXPORTTYPES'][EXPORT_XML] = array( "ID" => EXPORT_XML, "Selected" => "", "DisplayName" => $content['LN_GEN_EXPORT_XML'] ); @@ -1798,6 +1799,9 @@ function SaveGeneralSettingsIntoDB($bForceStripSlahes = false) WriteConfigValue( "ViewDefaultLanguage", true, null, null,$bForceStripSlahes ); WriteConfigValue( "ViewDefaultTheme", true, null, null,$bForceStripSlahes ); + WriteConfigValue( "ExportUseTodayYesterday", true, null, null,$bForceStripSlahes ); + WriteConfigValue( "SESSION_MAXIMIZED", true, null, null,$bForceStripSlahes ); + WriteConfigValue( "ViewUseTodayYesterday", true, null, null,$bForceStripSlahes ); WriteConfigValue( "ViewEnableDetailPopups", true, null, null,$bForceStripSlahes ); WriteConfigValue( "EnableContextLinks", true, null, null,$bForceStripSlahes ); @@ -1820,6 +1824,7 @@ function SaveGeneralSettingsIntoDB($bForceStripSlahes = false) WriteConfigValue( "PrependTitle", true, null, null,$bForceStripSlahes ); WriteConfigValue( "SearchCustomButtonCaption", true, null, null,$bForceStripSlahes ); WriteConfigValue( "SearchCustomButtonSearch", true, null, null,$bForceStripSlahes ); + WriteConfigValue( "EventEmptySearchDefaultFilter", true, null, null,$bForceStripSlahes ); // Extra Fields WriteConfigValue( "DefaultViewsID", true, null, null,$bForceStripSlahes ); @@ -1849,6 +1854,9 @@ function SaveUserGeneralSettingsIntoDB() WriteConfigValue( "ViewDefaultLanguage", false, $content['SESSION_USERID']); WriteConfigValue( "ViewDefaultTheme", false, $content['SESSION_USERID'] ); + WriteConfigValue( "ExportUseTodayYesterday", false, $content['SESSION_USERID']); + WriteConfigValue( "SESSION_MAXIMIZED", false, $content['SESSION_USERID']); + WriteConfigValue( "ViewUseTodayYesterday", false, $content['SESSION_USERID'] ); WriteConfigValue( "ViewEnableDetailPopups", false, $content['SESSION_USERID'] ); WriteConfigValue( "EnableContextLinks", false, $content['SESSION_USERID'] ); @@ -1871,7 +1879,8 @@ function SaveUserGeneralSettingsIntoDB() WriteConfigValue( "PrependTitle", false, $content['SESSION_USERID'] ); WriteConfigValue( "SearchCustomButtonCaption", false, $content['SESSION_USERID'] ); WriteConfigValue( "SearchCustomButtonSearch", false, $content['SESSION_USERID'] ); - + WriteConfigValue( "EventEmptySearchDefaultFilter", false, $content['SESSION_USERID'] ); + // Extra Fields WriteConfigValue( "DefaultViewsID", false, $content['SESSION_USERID'] ); WriteConfigValue( "DefaultSourceID", false, $content['SESSION_USERID'] ); diff --git a/src/include/functions_filters.php b/src/include/functions_filters.php index bb239e5..74f21ed 100644 --- a/src/include/functions_filters.php +++ b/src/include/functions_filters.php @@ -237,7 +237,7 @@ function InitFilterHelpers() if ( isset($_SESSION['filter_severity']) ) $filters['filter_severity'] = intval($_SESSION['filter_severity']); else - $filters['filter_severity'] = array ( SYSLOG_EMERG, SYSLOG_ALERT, SYSLOG_CRIT, SYSLOG_ERR, SYSLOG_WARNING, SYSLOG_NOTICE, SYSLOG_INFO, SYSLOG_DEBUG, SYSLOG_TRACE ); + $filters['filter_severity'] = array ( SYSLOG_EMERG, SYSLOG_ALERT, SYSLOG_CRIT, SYSLOG_ERR, SYSLOG_WARNING, SYSLOG_NOTICE, SYSLOG_INFO, SYSLOG_DEBUG, CUSTOM_TRACE ); $iCount = count($content['filter_severity_list']); for ( $i = 0; $i < $iCount; $i++ ) diff --git a/src/include/functions_frontendhelpers.php b/src/include/functions_frontendhelpers.php index 762bc71..95673a9 100644 --- a/src/include/functions_frontendhelpers.php +++ b/src/include/functions_frontendhelpers.php @@ -220,17 +220,19 @@ function CreateCurrentUrl() // done } -function GetFormatedDate($evttimearray) +function GetFormatedDate($evttimearray, $onExport = false) { global $content; if ( is_array($evttimearray) ) { if ( - GetConfigSetting("ViewUseTodayYesterday", 0, CFGLEVEL_USER) == 1 - && - ( date('m', $evttimearray[EVTIME_TIMESTAMP]) == date('m') && date('Y', $evttimearray[EVTIME_TIMESTAMP]) == date('Y') ) - ) + ($onExport == true && GetConfigSetting("ExportUseTodayYesterday", 0, CFGLEVEL_USER) == 1) + || ( + $onExport == false && GetConfigSetting("ViewUseTodayYesterday", 0, CFGLEVEL_USER) == 1 + && ( date('m', $evttimearray[EVTIME_TIMESTAMP]) == date('m') && date('Y', $evttimearray[EVTIME_TIMESTAMP]) == date('Y') ) + ) + ) { if ( date('d', $evttimearray[EVTIME_TIMESTAMP]) == date('d') ) return "Today " . date("H:i:s", $evttimearray[EVTIME_TIMESTAMP] ); diff --git a/src/index.php b/src/index.php index c69fc8a..a9fd781 100644 --- a/src/index.php +++ b/src/index.php @@ -122,13 +122,13 @@ $content['main_pager_last_found'] = false; // Init Sorting variables $content['sorting'] = ""; $content['searchstr'] = ""; -$content['searchstr_htmlform'] = "datelastx:6 severity:-8"; +$content['searchstr_htmlform'] = GetConfigSetting("EventEmptySearchDefaultFilter", "", CFGLEVEL_USER); $content['highlightstr'] = ""; $content['highlightstr_htmlform'] = ""; $content['EXPAND_HIGHLIGHT'] = "false"; -// hide header by default -$_SESSION['SESSION_MAXIMIZED'] = true; +// Control header visibility +$_SESSION['SESSION_MAXIMIZED'] = GetConfigSetting("SESSION_MAXIMIZED", 0, CFGLEVEL_USER); // --- Read and process filters from search dialog! if ( (isset($_POST['search']) || isset($_GET['search'])) || (isset($_POST['filter']) || isset($_GET['filter'])) ) diff --git a/src/lang/en/admin.php b/src/lang/en/admin.php index e5180c3..a1cc4df 100644 --- a/src/lang/en/admin.php +++ b/src/lang/en/admin.php @@ -87,6 +87,7 @@ $content['LN_GEN_ADMINCHANGEWAITTIME'] = "Reloadtime in Adminpanel"; $content['LN_GEN_IPADRRESOLVE'] = "Resolve IP Addresses using DNS"; $content['LN_GEN_CUSTBTNCAPT'] = "Custom search caption"; $content['LN_GEN_CUSTBTNSRCH'] = "Custom search string"; +$content['LN_GEN_EMPTYSRCHFILTR'] = "Override empty search filter"; $content['LN_GEN_SUCCESSFULLYSAVED'] = "The configuration Values have been successfully saved"; $content['LN_GEN_INTERNAL'] = "Internal"; $content['LN_GEN_DISABLED'] = "Function disabled"; @@ -104,6 +105,7 @@ $content['LN_GEN_GLOBALVALUE'] = "Global value"; $content['LN_GEN_PERSONALVALUE'] = "Personal (User)value"; $content['LN_GEN_DISABLEUSEROPTIONS'] = "Click here to disable personal options"; $content['LN_GEN_ENABLEUSEROPTIONS'] = "Click here to enable personal options"; +$content['LN_GEN_EXPORT_USETODAY'] = "Use Today and Yesterday in timefields of export"; $content['LN_ADMIN_GLOBALONLY'] = "Global Options Only"; $content['LN_GEN_DEBUGTOSYSLOG'] = "Send Debug to local syslog server"; $content['LN_GEN_POPUPMENUTIMEOUT'] = "Popupmenu Timeout in milli seconds"; @@ -118,6 +120,7 @@ $content['LN_ADMIN_USEPROXYSERVER'] = "Leave empty if you do not want to use a p $content['LN_ADMIN_DEFAULTENCODING'] = "Default character encoding"; $content['LN_GEN_CONTEXTLINKS'] = "Enable Contextlinks (Question marks)"; $content['LN_GEN_DISABLEADMINUSERS'] = "Disable Adminpanel for normal users"; +$content['LN_GEN_SESSION_MAX'] = "Load page in maximized mode"; // User Center $content['LN_USER_CENTER'] = "User Options"; diff --git a/src/lang/en/main.php b/src/lang/en/main.php index 9f984ea..2fd9d6e 100644 --- a/src/lang/en/main.php +++ b/src/lang/en/main.php @@ -86,6 +86,7 @@ $content['LN_GEN_SELECTEXPORT'] = "> Select Exportformat <"; $content['LN_GEN_EXPORT_CVS'] = "CSV (Comma separated)"; $content['LN_GEN_EXPORT_XML'] = "XML"; $content['LN_GEN_EXPORT_PDF'] = "PDF"; +$content['LN_GEN_EXPORT_PLAIN'] = "Plain TXT"; $content['LN_GEN_ERROR_EXPORING'] = "Error exporting data"; $content['LN_GEN_ERROR_INVALIDEXPORTTYPE'] = "Invalid Export format selected, or other parameters were wrong."; $content['LN_GEN_ERROR_SOURCENOTFOUND'] = "The Source with ID '%1' could not be found."; @@ -337,6 +338,8 @@ $content['LN_CONVERT_ERROR_SOURCEIMPORT'] = "Critical Error while importing the $content['LN_CHART_TYPE'] = "Chart type"; $content['LN_CHART_WIDTH'] = "Chart width"; $content['LN_CHART_FIELD'] = "Chart field"; + $content['LN_CHART_FILTER'] = "SQL Query filter"; + $content['LN_CHART_ORDERBY'] = "SQL ORDER BY"; $content['LN_CHART_MAXRECORDS'] = "Top records count"; $content['LN_CHART_SHOWPERCENT'] = "Show percentage data"; $content['LN_CHART_TYPE_CAKE'] = "Cake (Pie)"; diff --git a/src/templates/admin/admin_index.html b/src/templates/admin/admin_index.html index 4898825..e70e226 100644 --- a/src/templates/admin/admin_index.html +++ b/src/templates/admin/admin_index.html @@ -228,6 +228,14 @@ + + {LN_GEN_EMPTYSRCHFILTR} + + + + + + {LN_GEN_USETODAY} @@ -235,6 +243,22 @@ + + {LN_GEN_EXPORT_USETODAY} + + + + + + + {LN_GEN_SESSION_MAX} + + + + + + + {LN_GEN_DETAILPOPUPS} diff --git a/src/templates/admin/admin_searches.html b/src/templates/admin/admin_searches.html index 1b8c89d..80b36c1 100644 --- a/src/templates/admin/admin_searches.html +++ b/src/templates/admin/admin_searches.html @@ -41,7 +41,7 @@ {DisplayName} - {SearchQuery_Display} + {SearchQuery_Display} {SearchTypeText} @@ -74,7 +74,7 @@ {LN_SEARCH_QUERY} - + {LN_GEN_USERONLY} diff --git a/src/templates/index.html b/src/templates/index.html index c80de2a..862ab23 100644 --- a/src/templates/index.html +++ b/src/templates/index.html @@ -15,7 +15,7 @@ From 350a4c02acdbeba8511d35f71c10e49fef66b39f Mon Sep 17 00:00:00 2001 From: Vitaly Date: Sun, 15 Jan 2023 02:04:15 +0200 Subject: [PATCH 14/18] force page limit --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index f2347b2..8fcc60f 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,9 @@ Adiscon LogAnalyzer, a web frontend to log data from the same folks the created - CFG[Default_AUTORELOAD_ID] - control default autoreload mode - cfg[SESSION_MAXIMIZED] - control maximized mode - filter: support "limit:int" tag - disable paging and query less than configured for page (LogStreamDB->_SQLcustomLimitHaltSearchAfter) + +![limit_10](https://user-images.githubusercontent.com/8426197/212502393-d05d0cb9-4baf-4008-838b-ce078b6eeb8b.png) + - filter: datelastx - handle as float number - export: allow to EXPORT_PLAIN text format - custom bug fixes @@ -20,6 +23,9 @@ Adiscon LogAnalyzer, a web frontend to log data from the same folks the created - fix bug: chart double adding same key into search - allow to configure ORDER BY clause - add custom filter to chart value redirection link if such exists + +![chart_custom](https://user-images.githubusercontent.com/8426197/210448944-9a67c91c-1ca7-4f00-99ac-a5eebd566927.png) + - filter: support number ranges, i.e. severity:3-6 -> where severity in (3,4,5,6) - filter: support quoted filters, i.e. syslogtag:-="dhcp,info",-="wireless,info",-"system%,account" -> where (syslogtag <> 'dhcp,info' AND syslogtag <> 'wireless,info' AND syslogtag NOT LIKE '%system%,account%' ) - filter: support TRACE severity level; From 77bed422e049ef6f0a52edd00c06a8c2aa80f5e9 Mon Sep 17 00:00:00 2001 From: Vitaly X Date: Sat, 21 Jan 2023 14:14:38 +0200 Subject: [PATCH 15/18] datelastx backward compatibility --- README.md | 16 ++++++++----- src/classes/logstream.class.php | 37 ++++++++++++++++++++++++++++--- src/classes/logstreamdb.class.php | 29 ++++++++++++++++++++++-- src/include/config.sample.php | 10 ++++----- src/include/constants_filters.php | 9 ++++---- src/include/functions_filters.php | 4 ++-- src/js/searchhelpers.js | 10 ++++----- src/search.php | 4 ++-- 8 files changed, 91 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 8fcc60f..203124a 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,17 @@ ![loganalizer_example](https://user-images.githubusercontent.com/8426197/209875963-b7438f3b-9052-4e8f-9f22-05794e1e54a5.png) Adiscon LogAnalyzer, a web frontend to log data from the same folks the created rsyslog +# todo + - export: add checkbox to export full filtered history (now exports only current page) + - export: place ts into export filename (range from-to) + - BUG: "Suppress duplicated messages" doesn't work + - filter: allow to specify AFTER:n BEFORE:n (if possible/fast to implement) <- include records before and after match + - export: configure columns for file export (allow to remove unnecessary columns) <- exclude list of columns + - BUG: sometimes spinner on index page is drawn in the middle of page irrespective of it's size, but should be drawn in the middle of screen + +# changes 230121 + - datelastx - keep for backward compatibility (for saved searches); add datelastxx + # changes 230114 - fix bug: WHERE ( message LIKE '%LTE%unreachable%' ) give no result on filter page, yet works for charts, i.e. input = msg:LTE%unreachable (todo# in chart records have wrong date today merged with yesterday) - cfg[EventEmptySearchDefaultFilter] - config to use in case filter is empty (first load) @@ -31,11 +42,6 @@ Adiscon LogAnalyzer, a web frontend to log data from the same folks the created - filter: support TRACE severity level; - gui: add loglevel style colors and change color for full line; - filter: change datelastx behaviour - use number as hours indicator, i.e. datelastx:3 is 3 hours limit - -# todo - - export: add checkbox to export full filtered history (now exports selected page only) - - export: configure columns for file export (allow to remove unnecessary columns) <- exclude list of columns - - export: place ts into export filename (range from-to) #obsolete - filter: allow to OR msg, i.e. key1 &key2 |key3; diff --git a/src/classes/logstream.class.php b/src/classes/logstream.class.php index 0d26a6b..daa450d 100644 --- a/src/classes/logstream.class.php +++ b/src/classes/logstream.class.php @@ -566,9 +566,35 @@ abstract class LogStream { case FILTER_TYPE_DATE: // Get Log TimeStamp $nLogTimeStamp = $arrProperitesOut[$propertyname][EVTIME_TIMESTAMP]; - if ( $myfilter[FILTER_DATEMODE] == DATEMODE_LASTX ) + + //FIXME keep for backward compatibility + if ( $myfilter[FILTER_DATEMODE] == DATEMODE_LASTX ) { - //datelastx:x handle x as hours instead of constant + // Get current timestamp + $nNowTimeStamp = time(); + + //Get range timestamp + $nLastXTime = time() - (60 * 60 * floatval($myfilter[FILTER_VALUE])); + if ( $myfilter[FILTER_VALUE] == 1 /*DATE_LASTX_HOUR*/ ) + $nLastXTime = 60 * 60; // One Hour! + else if ( $myfilter[FILTER_VALUE] == 2 /*DATE_LASTX_12HOURS*/ ) + $nLastXTime = 60 * 60 * 12; // 12 Hours! + else if ( $myfilter[FILTER_VALUE] == 3 /*DATE_LASTX_24HOURS*/ ) + $nLastXTime = 60 * 60 * 24; // 24 Hours! + else if ( $myfilter[FILTER_VALUE] == 4 /*DATE_LASTX_7DAYS*/ ) + $nLastXTime = 60 * 60 * 24 * 7; // 7 days + else if ( $myfilter[FILTER_VALUE] == 5 /*DATE_LASTX_31DAYS*/ ) + $nLastXTime = 60 * 60 * 24 * 31; // 31 days + else + // WTF default? + $nLastXTime = 86400; + + // If Nowtime + LastX is higher then the log timestamp, the this logline is to old for us. + if ( ($nNowTimeStamp - $nLastXTime) > $nLogTimeStamp ) + $bEval = false; + } + else if ( $myfilter[FILTER_DATEMODE] == DATEMODE_LASTXX ) + {//handle x as hours //Get range timestamp $nLastXTime = time() - (60 * 60 * floatval($myfilter[FILTER_VALUE])); @@ -1027,11 +1053,16 @@ abstract class LogStream { $tmpFilterType = FILTER_TYPE_DATE; $tmpTimeMode = DATEMODE_RANGE_TO; break; - case "datelastx": + case "datelastx": //FIXME keep for backward compatibility $tmpKeyName = SYSLOG_DATE; $tmpFilterType = FILTER_TYPE_DATE; $tmpTimeMode = DATEMODE_LASTX; break; + case "datelastxx": + $tmpKeyName = SYSLOG_DATE; + $tmpFilterType = FILTER_TYPE_DATE; + $tmpTimeMode = DATEMODE_LASTXX; + break; case "timereported": $tmpKeyName = SYSLOG_DATE; $tmpFilterType = FILTER_TYPE_DATE; diff --git a/src/classes/logstreamdb.class.php b/src/classes/logstreamdb.class.php index c7ab5d3..26709c6 100644 --- a/src/classes/logstreamdb.class.php +++ b/src/classes/logstreamdb.class.php @@ -1510,9 +1510,34 @@ class LogStreamDB extends LogStream { $tmpfilters[$propertyname][FILTER_TYPE] = FILTER_TYPE_DATE; } + //FIXME keep for backward compatibility if ( $myfilter[FILTER_DATEMODE] == DATEMODE_LASTX ) - { - // Get current timestamp + { + // Get current timestamp + $nNowTimeStamp = time(); + if ( $myfilter[FILTER_VALUE] == 1 /*DATE_LASTX_HOUR*/ ) + $nNowTimeStamp -= 60 * 60; // One Hour! + else if ( $myfilter[FILTER_VALUE] == 2 /*DATE_LASTX_12HOURS*/) + $nNowTimeStamp -= 60 * 60 * 12; // 12 Hours! + else if ( $myfilter[FILTER_VALUE] == 3 /*DATE_LASTX_24HOURS*/ ) + $nNowTimeStamp -= 60 * 60 * 24; // 24 Hours! + else if ( $myfilter[FILTER_VALUE] == 4 /*DATE_LASTX_7DAYS*/ ) + $nNowTimeStamp -= 60 * 60 * 24 * 7; // 7 days + else if ( $myfilter[FILTER_VALUE] == 5 /*DATE_LASTX_31DAYS*/ ) + $nNowTimeStamp -= 60 * 60 * 24 * 31; // 31 days + else + { + // Set filter to unknown and Abort in this case! + $tmpfilters[$propertyname][FILTER_TYPE] = FILTER_TYPE_UNKNOWN; + break; + } + + // Append filter + $tmpfilters[$propertyname][FILTER_VALUE] .= $dbmapping[$szTableType]['DBMAPPINGS'][$propertyname] . " > '" . date("Y-m-d H:i:s", $nNowTimeStamp) . "'"; + } + else if ( $myfilter[FILTER_DATEMODE] == DATEMODE_LASTXX ) + {//handle x as hours + // Calculate offset timestamp $nNowTimeStamp = time() - (60 * 60 * floatval($myfilter[FILTER_VALUE])); // Append filter diff --git a/src/include/config.sample.php b/src/include/config.sample.php index 1ee46e8..9dfd00f 100644 --- a/src/include/config.sample.php +++ b/src/include/config.sample.php @@ -130,11 +130,11 @@ $CFG['DefaultViewsID'] = ""; // --- Predefined Searches! $CFG['Search'][] = array ( "DisplayName" => "Syslog Warnings and Errors", "SearchQuery" => "filter=severity%3A0%2C1%2C2%2C3%2C4&search=Search" ); $CFG['Search'][] = array ( "DisplayName" => "Syslog Errors", "SearchQuery" => "filter=severity%3A0%2C1%2C2%2C3&search=Search" ); -$CFG['Search'][] = array ( "DisplayName" => "All messages from the last hour", "SearchQuery" => "filter=datelastx%3A1&search=Search" ); -$CFG['Search'][] = array ( "DisplayName" => "All messages from last 12 hours", "SearchQuery" => "filter=datelastx%3A12&search=Search" ); -$CFG['Search'][] = array ( "DisplayName" => "All messages from last 24 hours", "SearchQuery" => "filter=datelastx%3A24&search=Search" ); -$CFG['Search'][] = array ( "DisplayName" => "All messages from last 7 days", "SearchQuery" => "filter=datelastx%3A168&search=Search" ); -$CFG['Search'][] = array ( "DisplayName" => "All messages from last 31 days", "SearchQuery" => "filter=datelastx%3A744&search=Search" ); +$CFG['Search'][] = array ( "DisplayName" => "All messages from the last hour", "SearchQuery" => "filter=datelastxx%3A1&search=Search" ); +$CFG['Search'][] = array ( "DisplayName" => "All messages from last 12 hours", "SearchQuery" => "filter=datelastxx%3A12&search=Search" ); +$CFG['Search'][] = array ( "DisplayName" => "All messages from last 24 hours", "SearchQuery" => "filter=datelastxx%3A24&search=Search" ); +$CFG['Search'][] = array ( "DisplayName" => "All messages from last 7 days", "SearchQuery" => "filter=datelastxx%3A168&search=Search" ); +$CFG['Search'][] = array ( "DisplayName" => "All messages from last 31 days", "SearchQuery" => "filter=datelastxx%3A744&search=Search" ); // $CFG['Search'][] = array ( "DisplayName" => "", "SearchQuery" => "" ); // --- diff --git a/src/include/constants_filters.php b/src/include/constants_filters.php index 64384ce..23abca0 100644 --- a/src/include/constants_filters.php +++ b/src/include/constants_filters.php @@ -47,15 +47,16 @@ if ( !defined('IN_PHPLOGCON') ) define('DATEMODE_ALL', 1); define('DATEMODE_RANGE', 2); define('DATEMODE_LASTX', 3); +define('DATEMODE_LASTXX', 33); define('DATEMODE_RANGE_FROM', 4); define('DATEMODE_RANGE_TO', 5); define('DATEMODE_RANGE_DATE', 6); define('DATE_LASTX_HOUR', 1); -define('DATE_LASTX_12HOURS', 2); -define('DATE_LASTX_24HOURS', 3); -define('DATE_LASTX_7DAYS', 4); -define('DATE_LASTX_31DAYS', 5); +define('DATE_LASTX_12HOURS', 12); +define('DATE_LASTX_24HOURS', 24); +define('DATE_LASTX_7DAYS', 168); +define('DATE_LASTX_31DAYS', 744); // --- diff --git a/src/include/functions_filters.php b/src/include/functions_filters.php index 74f21ed..6524e09 100644 --- a/src/include/functions_filters.php +++ b/src/include/functions_filters.php @@ -60,9 +60,9 @@ function InitFilterHelpers() $content['datemodes'][1]['ID'] = DATEMODE_RANGE; $content['datemodes'][1]['DisplayName'] = $content['LN_DATEMODE_RANGE']; if ( $filters['filter_datemode'] == DATEMODE_RANGE ) { $content['datemodes'][1]['selected'] = "selected"; } else { $content['datemodes'][1]['selected'] = ""; } - $content['datemodes'][2]['ID'] = DATEMODE_LASTX; + $content['datemodes'][2]['ID'] = DATEMODE_LASTXX; $content['datemodes'][2]['DisplayName'] = $content['LN_DATEMODE_LASTX']; - if ( $filters['filter_datemode'] == DATEMODE_LASTX ) { $content['datemodes'][2]['selected'] = "selected"; } else { $content['datemodes'][2]['selected'] = ""; } + if ( $filters['filter_datemode'] == DATEMODE_LASTXX ) { $content['datemodes'][2]['selected'] = "selected"; } else { $content['datemodes'][2]['selected'] = ""; } // Init Date Range Parameters global $currentTime, $currentDay, $currentMonth, $currentYear, $tomorrowTime, $tomorrowDay, $tomorrowMonth, $tomorrowYear; diff --git a/src/js/searchhelpers.js b/src/js/searchhelpers.js index 181e658..32be574 100644 --- a/src/js/searchhelpers.js +++ b/src/js/searchhelpers.js @@ -1,8 +1,8 @@ /* Helper Javascript Constants */ -const DATEMODE_ALL = 1, DATEMODE_RANGE = 2, DATEMODE_LASTX = 3; -const DATE_LASTX_HOUR = 1, DATE_LASTX_12HOURS = 2, DATE_LASTX_24HOURS = 3, DATE_LASTX_7DAYS = 4,DATE_LASTX_31DAYS = 5; +const DATEMODE_ALL = 1, DATEMODE_RANGE = 2, DATEMODE_LASTXX = 33; +const DATE_LASTX_HOUR = 1, DATE_LASTX_12HOURS = 12, DATE_LASTX_24HOURS = 24, DATE_LASTX_7DAYS = 168, DATE_LASTX_31DAYS = 744; /* Helper Javascript functions @@ -54,7 +54,7 @@ function toggleDatefiltervisibility(FormName) toggleformelement('filter_daterange_last_x', false); } - else if (myform.elements['filter_datemode'].value == DATEMODE_LASTX) + else if (myform.elements['filter_datemode'].value == DATEMODE_LASTXX) { togglevisibility('HiddenDateLastXOptions'); hidevisibility('HiddenDateFromOptions'); @@ -99,9 +99,9 @@ function CalculateSearchPreview(szSearchFormName, szPreviewArea) + mySearchform.elements['filter_daterange_to_minute'].value + ":" + mySearchform.elements['filter_daterange_to_second'].value + " "; } - else if (mySearchform.elements['filter_datemode'].value == DATEMODE_LASTX) + else if (mySearchform.elements['filter_datemode'].value == DATEMODE_LASTXX) { - szOutString += "datelastx:" + mySearchform.elements['filter_daterange_last_x'].value + " "; + szOutString += "datelastxx:" + mySearchform.elements['filter_daterange_last_x'].value + " "; } // --- Syslog Facility diff --git a/src/search.php b/src/search.php index 5336808..df77d94 100644 --- a/src/search.php +++ b/src/search.php @@ -149,12 +149,12 @@ if ( (isset($_POST['search']) || isset($_GET['search'])) ) $filters['filter_daterange_to_second'] . " "; } - else if ( $filters['filter_datemode'] == DATEMODE_LASTX ) + else if ( $filters['filter_datemode'] == DATEMODE_LASTXX ) { if ( isset($_GET['filter_daterange_last_x']) ) { $filters['filter_daterange_last_x'] = intval($_GET['filter_daterange_last_x']); - $content['searchstr'] .= "datelastx:" . $filters['filter_daterange_last_x'] . " "; + $content['searchstr'] .= "datelastxx:" . $filters['filter_daterange_last_x'] . " "; } } } From d1e501b1f4d2387cbe2c91905f8f392cc46a15a3 Mon Sep 17 00:00:00 2001 From: Vitaly X Date: Sat, 21 Jan 2023 14:21:27 +0200 Subject: [PATCH 16/18] fix non event links style --- src/themes/default/main.css | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/themes/default/main.css b/src/themes/default/main.css index a9cb627..644b237 100644 --- a/src/themes/default/main.css +++ b/src/themes/default/main.css @@ -23,9 +23,8 @@ a:link,a:active,a:visited,a.postlink { font-weight: bold; text-decoration:none; - background-color: transparent; - color:#ffffff; + color:#005989; } a:hover { @@ -34,6 +33,13 @@ a:hover } /*---*/ +/* Gridline Link Classes */ +td .gridline a:link,td .gridline a:active,td .gridline a:visited,td .gridline a.postlink +{ + color:#ffffff; +} + + /* Context Link Classes */ a.contextlink:link,a.contextlink:active,a.contextlink:visited,a.contextlink { From c2345c5a6fd93cf1d793f574dd7946469a2b869a Mon Sep 17 00:00:00 2001 From: Andre Lorbach Date: Fri, 3 Feb 2023 16:11:56 +0100 Subject: [PATCH 17/18] Update index.php Fixed cell css for events that miss syslog severity (old format) --- src/index.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.php b/src/index.php index a9fd781..e623a5b 100644 --- a/src/index.php +++ b/src/index.php @@ -371,9 +371,9 @@ if ( isset($content['Sources'][$currentSourceID]) ) // --- Set CSS Class if ( $counter % 2 == 0 ) - $content['syslogmessages'][$counter]['cssclass'] = "line1_".$logArray[SYSLOG_SEVERITY]; + $content['syslogmessages'][$counter]['cssclass'] = "line1" . (isset($logArray[SYSLOG_SEVERITY]) && strlen($logArray[SYSLOG_SEVERITY]) > 0 ? "_" . $logArray[SYSLOG_SEVERITY] : ""); else - $content['syslogmessages'][$counter]['cssclass'] = "line2_".$logArray[SYSLOG_SEVERITY]; + $content['syslogmessages'][$counter]['cssclass'] = "line2" . (isset($logArray[SYSLOG_SEVERITY]) && strlen($logArray[SYSLOG_SEVERITY]) > 0 ? "_" . $logArray[SYSLOG_SEVERITY] : ""); // --- // --- Copy other needed properties From a6ba71f50c22218253cefe613ec5c43212030c4b Mon Sep 17 00:00:00 2001 From: Andre Lorbach Date: Fri, 3 Feb 2023 16:13:03 +0100 Subject: [PATCH 18/18] Update functions_common.php Increased memory usage max