Merge pull request #448 from mkoch227/add-logging
Basic Logging Support
This commit is contained in:
commit
8ec86ffb9c
98
admin/view_message_log.php
Normal file
98
admin/view_message_log.php
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
define('IN_SCRIPT', 1);
|
||||||
|
define('HESK_PATH', '../');
|
||||||
|
define('PAGE_TITLE', 'ADMIN_TOOLS');
|
||||||
|
|
||||||
|
/* Get all the required files and functions */
|
||||||
|
require(HESK_PATH . 'hesk_settings.inc.php');
|
||||||
|
require(HESK_PATH . 'inc/common.inc.php');
|
||||||
|
require(HESK_PATH . 'inc/admin_functions.inc.php');
|
||||||
|
hesk_load_database_functions();
|
||||||
|
|
||||||
|
hesk_session_start();
|
||||||
|
hesk_dbConnect();
|
||||||
|
hesk_isLoggedIn();
|
||||||
|
|
||||||
|
hesk_checkPermission('can_view_logs');
|
||||||
|
|
||||||
|
define('EXTRA_JS', '<script src="'.HESK_PATH.'internal-api/js/view-message-log.js"></script>');
|
||||||
|
|
||||||
|
/* Print header */
|
||||||
|
require_once(HESK_PATH . 'inc/headerAdmin.inc.php');
|
||||||
|
|
||||||
|
/* Print main manage users page */
|
||||||
|
require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="row pad-20">
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<?php echo $hesklang['search_logs']; ?>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="form-horizontal">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="location" class="control-label col-sm-4">
|
||||||
|
<?php echo $hesklang['custom_place']; ?>
|
||||||
|
</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="text" name="location" class="form-control" placeholder="<?php echo hesk_htmlspecialchars($hesklang['custom_place']); ?>">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="date" class="control-label col-sm-4">
|
||||||
|
<?php echo $hesklang['date_logged']; ?>
|
||||||
|
</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="text" name="from-date" class="datepicker form-control white-readonly no-bottom-round-corners no-bottom-border" placeholder="<?php echo hesk_htmlspecialchars($hesklang['from_date']); ?>" readonly>
|
||||||
|
<input type="text" name="to-date" class="datepicker form-control white-readonly no-top-round-corners" placeholder="<?php echo hesk_htmlspecialchars($hesklang['to_date']); ?>" readonly>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="severity" class="control-label col-sm-4"><?php echo $hesklang['severity']; ?></label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<select name="severity" class="form-control">
|
||||||
|
<option value="-1" selected><?php echo $hesklang['all']; ?></option>
|
||||||
|
<option value="0"><?php echo $hesklang['debug']; ?></option>
|
||||||
|
<option value="1"><?php echo $hesklang['info']; ?></option>
|
||||||
|
<option value="2"><?php echo $hesklang['warning_title_case']; ?></option>
|
||||||
|
<option value="3"><?php echo $hesklang['sm_error']; ?></option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-8 col-sm-offset-4">
|
||||||
|
<button class="btn btn-default" id="search-button"><?php echo $hesklang['search']; ?></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<?php echo $hesklang['logs']; ?>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<table class="table table-striped" id="results-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th><?php echo $hesklang['date']; ?></th>
|
||||||
|
<th><?php echo $hesklang['user']; ?></th>
|
||||||
|
<th><?php echo $hesklang['custom_place']; ?></th>
|
||||||
|
<th><?php echo $hesklang['message']; ?></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody></tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
require_once(HESK_PATH . 'inc/footer.inc.php');
|
||||||
|
exit();
|
4
build.php
Normal file
4
build.php
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// Define the current build
|
||||||
|
define('MODS_FOR_HESK_BUILD', 23);
|
@ -301,4 +301,18 @@ div.setupButtons {
|
|||||||
|
|
||||||
.pad-20 {
|
.pad-20 {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-bottom-round-corners {
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-top-round-corners {
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-bottom-border {
|
||||||
|
border-bottom: none;
|
||||||
}
|
}
|
@ -1761,6 +1761,7 @@ function hesk_getFeatureArray()
|
|||||||
'can_man_permission_tpl', /* User can manage permission templates */
|
'can_man_permission_tpl', /* User can manage permission templates */
|
||||||
'can_man_settings', /* User can manage helpdesk settings */
|
'can_man_settings', /* User can manage helpdesk settings */
|
||||||
'can_change_notification_settings', /* User can change notification settings */
|
'can_change_notification_settings', /* User can change notification settings */
|
||||||
|
'can_view_logs', /* User can view the message logs */
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1811,4 +1812,28 @@ function mfh_getSettings()
|
|||||||
$settings[$row['Key']] = $row['Value'];
|
$settings[$row['Key']] = $row['Value'];
|
||||||
}
|
}
|
||||||
return $settings;
|
return $settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
function mfh_log($location, $message, $severity, $user) {
|
||||||
|
global $hesk_settings;
|
||||||
|
|
||||||
|
$sql = "INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "logging` (`username`, `message`, `severity`, `location`, `timestamp`)
|
||||||
|
VALUES ('" . hesk_dbEscape($user) . "',
|
||||||
|
'" . hesk_dbEscape($message) . "', " . intval($severity) . ", '" . hesk_dbEscape($location) . "', NOW())";
|
||||||
|
}
|
||||||
|
|
||||||
|
function mfh_log_debug($location, $message, $user) {
|
||||||
|
mfh_log($location, $message, 0, $user);
|
||||||
|
}
|
||||||
|
|
||||||
|
function mfh_log_info($location, $message, $user) {
|
||||||
|
mfh_log($location, $message, 1, $user);
|
||||||
|
}
|
||||||
|
|
||||||
|
function mfh_log_warning($location, $message, $user) {
|
||||||
|
mfh_log($location, $message, 2, $user);
|
||||||
|
}
|
||||||
|
|
||||||
|
function mfh_log_error($location, $message, $user) {
|
||||||
|
mfh_log($location, $message, 3, $user);
|
||||||
}
|
}
|
@ -28,8 +28,7 @@
|
|||||||
* https://www.hesk.com/buy.php
|
* https://www.hesk.com/buy.php
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
// Define the current build
|
require_once(HESK_PATH . 'build.php');
|
||||||
define('MODS_FOR_HESK_BUILD', 23);
|
|
||||||
|
|
||||||
/* Check if this is a valid include */
|
/* Check if this is a valid include */
|
||||||
if (!defined('IN_SCRIPT')) {
|
if (!defined('IN_SCRIPT')) {
|
||||||
@ -41,7 +40,7 @@ if (!function_exists('mfh_getSettings')) {
|
|||||||
|
|
||||||
$modsForHesk_settings = array();
|
$modsForHesk_settings = array();
|
||||||
if (is_dir(HESK_PATH . 'install')) {
|
if (is_dir(HESK_PATH . 'install')) {
|
||||||
$modsForHesk_settings['navbar_title_url'] = '#';
|
$modsForHesk_settings['navbar_title_url'] = 'javascript:;';
|
||||||
$modsForHesk_settings['rtl'] = 0;
|
$modsForHesk_settings['rtl'] = 0;
|
||||||
$modsForHesk_settings['use_bootstrap_theme'] = 1;
|
$modsForHesk_settings['use_bootstrap_theme'] = 1;
|
||||||
$modsForHesk_settings['show_icons'] = 1;
|
$modsForHesk_settings['show_icons'] = 1;
|
||||||
|
@ -28,8 +28,7 @@
|
|||||||
* https://www.hesk.com/buy.php
|
* https://www.hesk.com/buy.php
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
// Define the current build
|
require_once(HESK_PATH . 'build.php');
|
||||||
define('MODS_FOR_HESK_BUILD', 23);
|
|
||||||
|
|
||||||
/* Check if this is a valid include */
|
/* Check if this is a valid include */
|
||||||
if (!defined('IN_SCRIPT')) {
|
if (!defined('IN_SCRIPT')) {
|
||||||
|
@ -180,6 +180,10 @@ if (hesk_check_kb_only(false)) {
|
|||||||
$tools_count++;
|
$tools_count++;
|
||||||
$dropdown_items .= '<li><a href="manage_statuses.php">' . $hesklang['manage_statuses'] . '</a></li>';
|
$dropdown_items .= '<li><a href="manage_statuses.php">' . $hesklang['manage_statuses'] . '</a></li>';
|
||||||
}
|
}
|
||||||
|
if (hesk_checkPermission('can_view_logs', 0)) {
|
||||||
|
$tools_count++;
|
||||||
|
$dropdown_items .= '<li><a href="view_message_log.php">' . $hesklang['view_message_log'] . '</a></li>';
|
||||||
|
}
|
||||||
$dropdown_items .= '</ul>';
|
$dropdown_items .= '</ul>';
|
||||||
|
|
||||||
if ($tools_count > 1) {
|
if ($tools_count > 1) {
|
||||||
@ -224,6 +228,12 @@ if (hesk_check_kb_only(false)) {
|
|||||||
$active = ' class="active"';
|
$active = ' class="active"';
|
||||||
}
|
}
|
||||||
echo '<li'.$active.'><a href="manage_statuses.php"><i class="fa fa-wrench" ' . $iconDisplay . '></i> ' . $hesklang['tools'] . '</a></li>';
|
echo '<li'.$active.'><a href="manage_statuses.php"><i class="fa fa-wrench" ' . $iconDisplay . '></i> ' . $hesklang['tools'] . '</a></li>';
|
||||||
|
} elseif (hesk_checkPermission('can_view_logs', 0)) {
|
||||||
|
$active = '';
|
||||||
|
if (defined('PAGE_TITLE') && PAGE_TITLE == 'ADMIN_TOOLS') {
|
||||||
|
$active = ' class="active"';
|
||||||
|
}
|
||||||
|
echo '<li'.$active.'><a href="view_message_log.php"><i class="fa fa-wrench" ' . $iconDisplay . '></i> ' . $hesklang['tools'] . '</a></li>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hesk_checkPermission('can_man_settings', 0)) {
|
if (hesk_checkPermission('can_man_settings', 0)) {
|
||||||
|
@ -702,6 +702,13 @@ function execute260Scripts()
|
|||||||
hesk_dbConnect();
|
hesk_dbConnect();
|
||||||
|
|
||||||
executeQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "settings` (`Key`, `Value`) VALUES ('public_api', '1')");
|
executeQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "settings` (`Key`, `Value`) VALUES ('public_api', '1')");
|
||||||
|
executeQuery("CREATE TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "logging` (
|
||||||
|
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`username` VARCHAR(200),
|
||||||
|
`message` MEDIUMTEXT NOT NULL,
|
||||||
|
`severity` INT NOT NULL,
|
||||||
|
`location` MEDIUMTEXT,
|
||||||
|
`timestamp` TIMESTAMP NOT NULL) ENGINE = MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci");
|
||||||
executeQuery("CREATE TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "user_api_tokens` (
|
executeQuery("CREATE TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "user_api_tokens` (
|
||||||
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
`user_id` INT NOT NULL,
|
`user_id` INT NOT NULL,
|
||||||
|
24
internal-api/admin/message-log/index.php
Normal file
24
internal-api/admin/message-log/index.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
define('IN_SCRIPT', 1);
|
||||||
|
define('HESK_PATH', '../../../');
|
||||||
|
define('INTERNAL_API_PATH', '../../');
|
||||||
|
require_once(HESK_PATH . 'hesk_settings.inc.php');
|
||||||
|
require_once(HESK_PATH . 'inc/common.inc.php');
|
||||||
|
require_once(INTERNAL_API_PATH . 'core/output.php');
|
||||||
|
require_once(INTERNAL_API_PATH . 'dao/message_log_dao.php');
|
||||||
|
|
||||||
|
hesk_load_internal_api_database_functions();
|
||||||
|
hesk_dbConnect();
|
||||||
|
|
||||||
|
// Routing
|
||||||
|
$request_method = $_SERVER['REQUEST_METHOD'];
|
||||||
|
if ($request_method == 'POST') {
|
||||||
|
$location = $_POST['location'];
|
||||||
|
$from_date = $_POST['fromDate'];
|
||||||
|
$to_date = $_POST['toDate'];
|
||||||
|
$severity_id = $_POST['severityId'];
|
||||||
|
|
||||||
|
$results = search_log($hesk_settings, $location, $from_date, $to_date, $severity_id);
|
||||||
|
print json_encode($results);
|
||||||
|
return http_response_code(200);
|
||||||
|
}
|
36
internal-api/dao/message_log_dao.php
Normal file
36
internal-api/dao/message_log_dao.php
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
function search_log($hesk_settings, $location, $from_date, $to_date, $severity_id) {
|
||||||
|
if (!function_exists('hesk_date')) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = "SELECT * FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "logging` WHERE 1=1 ";
|
||||||
|
|
||||||
|
if ($location != NULL) {
|
||||||
|
$sql .= "AND `location` LIKE '%" . hesk_dbEscape(hesk_dbLike($location)) . "%' ";
|
||||||
|
}
|
||||||
|
$from_date_format = preg_match("/\d{4}-\d{2}-\d{2}/", $from_date);
|
||||||
|
if ($from_date != NULL
|
||||||
|
&& $from_date_format === 1) {
|
||||||
|
$sql .= "AND `timestamp` >= '" . hesk_dbEscape($from_date) . " 00:00:00' ";
|
||||||
|
}
|
||||||
|
$to_date_format = preg_match("/\d{4}-\d{2}-\d{2}/", $to_date);
|
||||||
|
if ($to_date != NULL
|
||||||
|
&& $to_date_format === 1) {
|
||||||
|
$sql .= "AND `timestamp` <= '" . hesk_dbEscape($to_date) . " 23:59:59' ";
|
||||||
|
}
|
||||||
|
if ($severity_id != NULL) {
|
||||||
|
$sql .= "AND `severity` = " . intval($severity_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
$rs = hesk_dbQuery($sql);
|
||||||
|
|
||||||
|
$results = [];
|
||||||
|
while ($row = hesk_dbFetchAssoc($rs)) {
|
||||||
|
$row['timestamp'] = hesk_date($row['timestamp'], true);
|
||||||
|
$results[] = $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
}
|
72
internal-api/js/view-message-log.js
Normal file
72
internal-api/js/view-message-log.js
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
$(document).ready(function() {
|
||||||
|
// We should show the latest 50 logs when the user first views the page.
|
||||||
|
searchLogs(null, null, null, null);
|
||||||
|
|
||||||
|
$('#search-button').click(function() {
|
||||||
|
var location = getNullableField($('input[name="location"]').val());
|
||||||
|
var dateFrom = getNullableField($('input[name="from-date"]').val());
|
||||||
|
var dateTo = getNullableField($('input[name="to-date"]').val());
|
||||||
|
var severity = $('select[name="severity"]').val();
|
||||||
|
if (severity == -1) {
|
||||||
|
severity = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
searchLogs(location, dateFrom, dateTo, severity);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function getNullableField(value) {
|
||||||
|
return value !== "" ? value : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function searchLogs(location, fromDate, toDate, severity) {
|
||||||
|
var endpoint = getHelpdeskUrl();
|
||||||
|
endpoint += '/internal-api/admin/message-log/';
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: endpoint,
|
||||||
|
data: {
|
||||||
|
location: location,
|
||||||
|
fromDate: fromDate,
|
||||||
|
toDate: toDate,
|
||||||
|
severityId: severity
|
||||||
|
},
|
||||||
|
method: 'POST',
|
||||||
|
success: displayResults,
|
||||||
|
error: function(data) {
|
||||||
|
console.error(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function displayResults(data) {
|
||||||
|
data = $.parseJSON(data);
|
||||||
|
var table = $('#results-table > tbody');
|
||||||
|
table.empty();
|
||||||
|
|
||||||
|
if (data.length === 0) {
|
||||||
|
table.append('<tr><td colspan="4">No results found</td></tr>');
|
||||||
|
} else {
|
||||||
|
for (var index in data) {
|
||||||
|
var result = data[index];
|
||||||
|
table.append('<tr ' + getRowColor(result) + '>' +
|
||||||
|
'<td>' + result.timestamp + '</td>' +
|
||||||
|
'<td>' + result.username + '</td>' +
|
||||||
|
'<td>' + result.location + '</td>' +
|
||||||
|
'<td>' + result.message + '</td>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRowColor(result) {
|
||||||
|
switch (result.severity) {
|
||||||
|
case "1":
|
||||||
|
return 'class="info"';
|
||||||
|
case "2":
|
||||||
|
return 'class="warning"';
|
||||||
|
case "3":
|
||||||
|
return 'class="danger"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
@ -21,6 +21,18 @@ $hesklang['_COLLATE']='utf8_unicode_ci';
|
|||||||
// This is the email break line that will be used in email piping
|
// This is the email break line that will be used in email piping
|
||||||
$hesklang['EMAIL_HR']='------ Reply above this line ------';
|
$hesklang['EMAIL_HR']='------ Reply above this line ------';
|
||||||
|
|
||||||
|
// ADDED OR MODIFIED IN Mods for HESK 2.6.0
|
||||||
|
$hesklang['search_logs'] = 'Search Logs';
|
||||||
|
$hesklang['date_logged'] = 'Date Logged';
|
||||||
|
$hesklang['from_date'] = 'From Date';
|
||||||
|
$hesklang['to_date'] = 'To Date';
|
||||||
|
$hesklang['severity'] = 'Severity';
|
||||||
|
$hesklang['debug'] = 'Debug';
|
||||||
|
$hesklang['warning_title_case'] = 'Warning';
|
||||||
|
$hesklang['logs'] = 'Logs';
|
||||||
|
$hesklang['view_message_log'] = 'View Message Log';
|
||||||
|
$hesklang['can_view_logs'] = 'Can view message logs';
|
||||||
|
|
||||||
// ADDED OR MODIFIED IN Mods for HESK 2.5.2
|
// ADDED OR MODIFIED IN Mods for HESK 2.5.2
|
||||||
$hesklang['manage_statuses'] = 'Manage Statuses';
|
$hesklang['manage_statuses'] = 'Manage Statuses';
|
||||||
$hesklang['manage_service_messages'] = 'Manage Service Messages';
|
$hesklang['manage_service_messages'] = 'Manage Service Messages';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user