Skip to content

Commit

Permalink
Date/Time display locale format selector
Browse files Browse the repository at this point in the history
Remains unchanged as log raw (ISO 8601: YYYY-MM-DDThh:mm:ss+/-hh:mm) unless a different display format is selected.

A major purpose of a GUI is human ease of use.  Date/Time strings in ISO 8601 format are great for data transfer between systems.  Though not humanly convenient.
This patch makes possible to optionally select a humanly convenient date/time log display format based on the client locale or the OPNsense web GUI language.  ex: Mar 25 13:15:45

The logged ISO 8601 date/time string is not altered by this patch.

Display Formats:

SYSTEM: SETTINGS: LOGGING
 + Web GUI Language (MMM DD hh:mm:ss)
 + Client Locale (MMM DD hh:mm:ss)
 + Log Raw (YYYY-MM-DDThh:mm:ss+/-hh:mm)
 + Log Long (YYYY-MM-DD hh:mm:ss+/-hh)
 + Log Long w/o TZ (YYYY-MM-DD hh:mm:ss)
 + Log Short (MM-DD hh:mm:ss)

SYSTEM: LOG FILES: BOOT (does not include TZ)
 + Log Raw (YYYY-MM-DDThh:mm:ss)
 + Log Long (YYYY-MM-DD hh:mm:ss)

FIREWALL: SETTINGS: ADVANCED -> Logging
 + Web GUI Language (MMM DD hh:mm:ss)
 + Client Locale (MMM DD hh:mm:ss)
 + Log Raw (YYYY-MM-DDThh:mm:ss+/-hh:mm)
 + Log Long (YYYY-MM-DD hh:mm:ss+/-hh)
 + Log Long w/o TZ (YYYY-MM-DD hh:mm:ss)
 + Log Short (MM-DD hh:mm:ss)

FIREWALL: ALIASES -> Last Updated (does not include TZ)
 + Log Raw (YYYY-MM-DDThh:mm:ss.nnnnnn)
 + Log Long (YYYY-MM-DD hh:mm:ss)

Firewall Log Widget
System Log Widget
 + Web GUI Language (MMM DD hh:mm)
 + Client Locale (MMM DD hh:mm)
 + Log Raw (YYYY-MM-DDThh:mm:ss+/-hh:mm)
 + Log Long (YYYY-MM-DD hh:mm:ss+/-hh)
 + Log Long w/o TZ (YYYY-MM-DD hh:mm:ss)
 + Log Short (MM-DD hh:mm)
  • Loading branch information
NOYB committed Apr 13, 2024
1 parent 8f9ee84 commit bb600fe
Show file tree
Hide file tree
Showing 11 changed files with 265 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
namespace OPNsense\Diagnostics;

use OPNsense\Base\IndexController;
use OPNsense\Core\Config;

/**
* Class FirewallController
Expand Down Expand Up @@ -61,6 +62,7 @@ protected function templateCSSIncludes()
public function logAction()
{
$this->view->pick('OPNsense/Diagnostics/fw_log');
$this->view->timefmt = !empty(Config::getInstance()->object()->syslog->timefmt) ? Config::getInstance()->object()->syslog->timefmt : 'Log_Raw';
}
/**
* firewall statistical view
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
namespace OPNsense\Diagnostics;

use OPNsense\Base\IndexController;
use OPNsense\Core\Config;

/**
* @inherit
Expand All @@ -42,6 +43,7 @@ public function renderPage($module, $scope)
$this->view->scope = htmlspecialchars($scope, ENT_QUOTES | ENT_HTML401);
$this->view->service = '';
$this->view->default_log_severity = 'Warning';
$this->view->timefmt = !empty(Config::getInstance()->object()->OPNsense->Syslog->general->timefmt) ? Config::getInstance()->object()->OPNsense->Syslog->general->timefmt : 'Log_Raw';

$service = $module == 'core' ? $scope : $module;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
namespace OPNsense\Firewall;

use OPNsense\Base\IndexController;
use OPNsense\Core\Config;

/**
* @package OPNsense\Firewall
Expand All @@ -41,5 +42,6 @@ public function indexAction($selected = null)
$this->view->selected_alias = $selected;
$this->view->formGeoIPSettings = $this->getForm("geoIPSettings");
$this->view->pick('OPNsense/Firewall/alias');
$this->view->timefmt = !empty(Config::getInstance()->object()->syslog->timefmt) ? Config::getInstance()->object()->syslog->timefmt : 'Log_Raw';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,12 @@
<type>text</type>
<help>Maximum file size per log file. When set and a log file exceeds the amount specified, it will be rotated.</help>
</field>
<field>
<id>syslog.general.timefmt</id>
<label>Time Display Format</label>
<type>dropdown</type>
<help><![CDATA[Time format to display on system log pages.<br>
(boot log does not include timezone)]]>
</help>
</field>
</form>
12 changes: 12 additions & 0 deletions src/opnsense/mvc/app/models/OPNsense/Syslog/Syslog.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@
<Required>Y</Required>
</maxpreserve>
<maxfilesize type="IntegerField"/>
<timefmt type="OptionField">
<Default>Log_Raw</Default>
<Required>Y</Required>
<OptionValues>
<Web_GUI_Language>Web GUI Language (MMM DD hh:mm:ss)</Web_GUI_Language>
<Client_Locale>Client Locale (MMM DD hh:mm:ss)</Client_Locale>
<Log_Raw>Log Raw (YYYY-MM-DDThh:mm:ss+/-hh:mm)</Log_Raw>
<Log_Long>Log Long (YYYY-MM-DD hh:mm:ss+/-hh)</Log_Long>
<Log_Long_No_TZ>Log Long w/o TZ (YYYY-MM-DD hh:mm:ss)</Log_Long_No_TZ>
<Log_Short>Log Short (MM-DD hh:mm:ss)</Log_Short>
</OptionValues>
</timefmt>
</general>
<destinations>
<destination type="ArrayField">
Expand Down
27 changes: 27 additions & 0 deletions src/opnsense/mvc/app/views/OPNsense/Diagnostics/fw_log.volt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,17 @@
<script>
'use strict';

// Time display format: Use or override log raw time format
var timefmt =
"{{ timefmt }}" == 'Web_GUI_Language' ? "{{ langcode }}"
: "{{ timefmt }}" == 'Client_Locale' ? 'default'
: "{{ timefmt }}";

// Implement as Intl.DateTimeFormat object for efficiency (toLocaleString).
if (timefmt == "{{ langcode }}" || timefmt == 'default') {
var IDTF_obj = new Intl.DateTimeFormat(timefmt, { month:'short', day:'2-digit', hour:'numeric', hourCycle:'h23', minute: 'numeric', second: 'numeric'});
}

$( document ).ready(function() {
var field_type_icons = {
'binat': 'fa-exchange',
Expand Down Expand Up @@ -258,6 +269,22 @@
} else {
record['interface_name'] = record.interface;
}
switch (timefmt) {
case 'Log_Raw':
record['__timestamp__'] = record['__timestamp__'];
break;
case 'Log_Long':
record['__timestamp__'] = record['__timestamp__'].substring(0,22).replace('T', ' ');
break;
case 'Log_Long_No_TZ':
record['__timestamp__'] = record['__timestamp__'].substring(0,19).replace('T', ' ');
break;
case 'Log_Short':
record['__timestamp__'] = record['__timestamp__'].substring(5,19).replace('T', ' ');
break;
default:
record['__timestamp__'] = IDTF_obj.format(new Date(record['__timestamp__'])).replace(/[.,]/g, '');
}
log_tr.data('details', record);
log_tr.hide();
$.each(record_spec, function(idx, field){
Expand Down
34 changes: 33 additions & 1 deletion src/opnsense/mvc/app/views/OPNsense/Diagnostics/log.volt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@
#}

<script>
// Time display format: Use or override log raw time format
var timefmt =
"{{ timefmt }}" == 'Web_GUI_Language' ? "{{ langcode }}"
: "{{ timefmt }}" == 'Client_Locale' ? 'default'
: "{{ timefmt }}";

// Implement as Intl.DateTimeFormat object for efficiency (toLocaleString).
if (timefmt == "{{ langcode }}" || timefmt == 'default') {
var IDTF_obj = new Intl.DateTimeFormat(timefmt, { month:'short', day:'2-digit', hour:'numeric', hourCycle:'h23', minute: 'numeric', second: 'numeric'});
}

$( document ).ready(function() {
var filter_exact = false;
let s_filter_val = '{{default_log_severity}}';
Expand Down Expand Up @@ -64,6 +75,27 @@
return "";
}
},
timestamp: function (column, row) {
if (row[column.id]) {
switch (timefmt) {
case 'Log_Raw':
return row[column.id];
break;
case 'Log_Long':
return row[column.id].substring(0,22).replace('T', ' ');
break;
case 'Log_Long_No_TZ':
return row[column.id].substring(0,19).replace('T', ' ');
break;
case 'Log_Short':
return row[column.id].substring(5,19).replace('T', ' ');
break;
default:
return IDTF_obj.format(new Date(row[column.id])).replace(/[.,]/g, '');
}
}
return row[column.id];
},
},
requestHandler: function(request){
if ( $('#severity_filter').val().length > 0) {
Expand Down Expand Up @@ -214,7 +246,7 @@
<table id="grid-log" class="table table-condensed table-hover table-striped table-responsive">
<thead>
<tr>
<th data-column-id="timestamp" data-width="11em" data-type="string">{{ lang._('Date') }}</th>
<th data-column-id="timestamp" data-width="9.5em" data-formatter="timestamp" data-type="string">{{ lang._('Date') }}</th>
<th data-column-id="facility" data-type="string" data-visible="false">{{ lang._('Facility') }}</th>
<th data-column-id="severity" data-type="string" data-width="2em">{{ lang._('Severity') }}</th>
<th data-column-id="process_name" data-width="2em" data-type="string">{{ lang._('Process') }}</th>
Expand Down
28 changes: 26 additions & 2 deletions src/opnsense/mvc/app/views/OPNsense/Firewall/alias.volt
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,17 @@

</style>
<script>
// Time display format: Use or override log raw time format
var timefmt =
"{{ timefmt }}" == 'Web_GUI_Language' ? "{{ langcode }}"
: "{{ timefmt }}" == 'Client_Locale' ? 'default'
: "{{ timefmt }}";

// Implement as Intl.DateTimeFormat object for efficiency (toLocaleString).
if (timefmt == "{{ langcode }}" || timefmt == 'default') {
var IDTF_obj = new Intl.DateTimeFormat(timefmt, { month:'short', day:'2-digit', hour:'numeric', hourCycle:'h23', minute: 'numeric', second: 'numeric'});
}

$( document ).ready(function() {
$("#grid-aliases").UIBootgrid({
search:'/api/firewall/alias/searchItem',
Expand Down Expand Up @@ -116,8 +127,21 @@
}
},
timestamp: function (column, row) {
if (row[column.id] && row[column.id].includes('.')) {
return row[column.id].split('.')[0].replace('T', ' ');
if (row[column.id]) {
switch (timefmt) {
case 'Log_Raw':
return row[column.id];
break;
case 'Log_Long':
case 'Log_Long_No_TZ':
return row[column.id].substring(0,19).replace('T', ' ');
break;
case 'Log_Short':
return row[column.id].substring(5,19).replace('T', ' ');
break;
default:
return IDTF_obj.format(new Date(row[column.id])).replace(/[.,]/g, '');
}
}
return row[column.id];
}
Expand Down
38 changes: 38 additions & 0 deletions src/www/system_advanced_firewall.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@
$pconfig['logoutboundnat'] = !empty($config['syslog']['logoutboundnat']);
$pconfig['logbogons'] = empty($config['syslog']['nologbogons']);
$pconfig['logprivatenets'] = empty($config['syslog']['nologprivatenets']);

// Time display format: Use or override log raw time format
$pconfig['timefmt'] = !empty($config['syslog']['timefmt']) ? $config['syslog']['timefmt'] : 'Log_Raw';

} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
$pconfig = $_POST;
$input_errors = array();
Expand Down Expand Up @@ -262,6 +266,13 @@
$config['syslog']['nologprivatenets'] = empty($pconfig['logprivatenets']);
$config['syslog']['logoutboundnat'] = !empty($pconfig['logoutboundnat']);

// Time display format: Use or override log raw time format
if (!empty($pconfig['timefmt']) && $pconfig['timefmt'] != 'Log_Raw') {
$config['syslog']['timefmt'] = $pconfig['timefmt'];
} else {
unset($config['syslog']['timefmt']);
}

write_config();

$savemsg = get_std_save_message();
Expand Down Expand Up @@ -538,6 +549,33 @@
<?=gettext("Log packets blocked by 'Block Private Networks' rules");?>
</td>
</tr>
<?php
// Time formats (language locales)
$locales = array(
'Web_GUI_Language' => gettext('Web GUI Language (MMM DD hh:mm:ss)'),
'Client_Locale' => gettext('Client Locale (MMM DD hh:mm:ss)'),
'Log_Raw' => gettext('Log Raw (YYYY-MM-DDThh:mm:ss+/-hh:mm)'),
'Log_Long' => gettext('Log Long (YYYY-MM-DD hh:mm:ss+/-hh)'),
'Log_Long_No_TZ' => gettext('Log Long w/o TZ (YYYY-MM-DD hh:mm:ss)'),
'Log_Short' => gettext('Log Short (MM-DD hh:mm:ss)'),
);
?>
<tr>
<td><a id="help_for_timefmt" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext('Time display format') ?></td>
<td>
<label for="timefmt">
<select id="timefmt" name="timefmt" class="selectpicker" data-style="btn-default">
<?php foreach ($locales as $lcode => $ldesc): ?>
<option value="<?= html_safe($lcode) ?>" <?= $lcode == $pconfig['timefmt'] ? 'selected="selected"' : '' ?>><?= html_safe($ldesc) ?></option>
<?php endforeach ?>
</select>
</label>
<div class="hidden" data-for="help_for_timefmt">
<?=gettext('Time format to display on firewall log pages and aliases last updated.');?><br>
<?=gettext('(aliases last updated does not include timezone)');?>
</div>
</td>
</tr>
</table>
</div>
<div class="content-box tab-content table-responsive __mb">
Expand Down
56 changes: 55 additions & 1 deletion src/www/widgets/widgets/log.widget.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,13 @@
unset($config['widgets']['filterlogentriesinterfaces']);
}

// Time display format: Use or override log raw time format
if (!empty($pconfig['timefmt']) && $pconfig['timefmt'] != 'Log_Raw') {
$config['widgets']['filterlogentriestimefmt'] = $pconfig['timefmt'];
} else {
unset($config['widgets']['filterlogentriestimefmt']);
}

write_config('Saved Filter Log Entries via Dashboard');
header(url_safe('Location: /index.php'));
exit;
Expand All @@ -73,8 +80,23 @@
$nentriesacts = isset($config['widgets']['filterlogentriesacts']) ? explode(" ", $config['widgets']['filterlogentriesacts']) : array('Pass', 'Block', 'Reject');
$nentriesinterfaces = isset($config['widgets']['filterlogentriesinterfaces']) ? $config['widgets']['filterlogentriesinterfaces'] : '';

// Time display format: Use or override log raw time format
$langcode = !empty($config['system']['language']) ? $config['system']['language'] : 'en_US';
$timefmt = !empty($config['widgets']['filterlogentriestimefmt']) ? $config['widgets']['filterlogentriestimefmt'] : 'Log_Raw';

?>
<script>
// Time display format: Use or override log raw time format
var timefmt =
"<?= $timefmt ?>" == 'Web_GUI_Language' ? "<?= $langcode ?>".replaceAll('_', '-')
: "<?= $timefmt ?>" == 'Client_Locale' ? 'default'
: "<?= $timefmt ?>";

// Implement as Intl.DateTimeFormat object for efficiency (toLocaleString).
if (timefmt == "<?= $langcode ?>".replaceAll('_', '-') || timefmt == 'default') {
var IDTF_obj = new Intl.DateTimeFormat(timefmt, { month:'short', day:'2-digit', hour:'numeric', hourCycle:'h23', minute: 'numeric'});
}

$("#dashboard_container").on("WidgetsReady", function() {
// needed to display the widget settings menu
$("#log-configure").removeClass("disabled");
Expand Down Expand Up @@ -142,7 +164,22 @@ function fetch_log(){
}
break;
case 'time':
log_td.text(record[column_name].replace(/:[0-9]{2}$/, ''));
switch (timefmt) {
case 'Log_Raw':
log_td.text(record[column_name]);
break;
case 'Log_Long':
log_td.text(record[column_name].substring(0,22).replace('T', ' '));
break;
case 'Log_Long_No_TZ':
log_td.text(record[column_name].substring(0,19).replace('T', ' '));
break;
case 'Log_Short':
log_td.text(record[column_name].substring(5,16).replace('T', ' '));
break;
default:
log_td.text(IDTF_obj.format(new Date(record[column_name])).replace(/[.,]/g, ''));
}
break;
case 'interface':
if (interface_descriptions[record[column_name]] != undefined) {
Expand Down Expand Up @@ -214,6 +251,23 @@ function fetch_log(){
<label for="filterlogentriesinterfaces"><?= gettext('Interfaces to display:'); ?></label><br/>
<select id="filterlogentriesinterfaces" name="filterlogentriesinterfaces[]" class="selectpicker_widget" multiple="multiple" title=<?= gettext('All'); ?>>
</select><br/><br/>
<?php
// Time formats (language locales)
$locales = array(
'Web_GUI_Language' => gettext('Web GUI Language (MMM DD hh:mm)'),
'Client_Locale' => gettext('Client Locale (MMM DD hh:mm)'),
'Log_Raw' => gettext('Log Raw (YYYY-MM-DDThh:mm:ss+/-hh:mm)'),
'Log_Long' => gettext('Log Long (YYYY-MM-DD hh:mm:ss+/-hh)'),
'Log_Long_No_TZ' => gettext('Log Long w/o TZ (YYYY-MM-DD hh:mm:ss)'),
'Log_Short' => gettext('Log Short (MM-DD hh:mm)'),
);
?>
<label for="timefmt"><?= gettext('Time display format:') ?></label><br/>
<select id="timefmt" name="timefmt" class="selectpicker_widget">
<?php foreach ($locales as $lcode => $ldesc): ?>
<option value="<?= html_safe($lcode) ?>" <?= $lcode == $timefmt ? 'selected="selected"' : '' ?>><?= html_safe($ldesc) ?></option>
<?php endforeach ?>
</select><br/>
<table style="width:348px">
<tr>
<td><label for="actblock"><input id="actblock" name="actblock" type="checkbox" value="Block" <?=in_array('Block', $nentriesacts) ? "checked=\"checked\"" : "";?> /><?= gettext('Block') ?></label></td>
Expand Down

0 comments on commit bb600fe

Please sign in to comment.