plexpy/data/interfaces/default/logs.html
2023-03-03 22:37:57 -08:00

556 lines
26 KiB
HTML

<%inherit file="base.html"/>
<%!
from plexpy import helpers
%>
<%def name="headIncludes()">
<link rel="stylesheet" href="${http_root}css/dataTables.bootstrap.min.css">
<link rel="stylesheet" href="${http_root}css/tautulli-dataTables.css">
<style>
td {word-break: break-all;}
</style>
</%def>
<%def name="headerIncludes()">
</%def>
<%def name="body()">
<div class='container-fluid'>
<div class='table-card-header'>
<div class="header-bar">
<span><i class="fa fa-list-alt"></i> Logs</span>
</div>
<div class="button-bar">
<div class="btn-group" id="tautulli-log-levels">
<label>
<select name="tautulli-log-level-filter" id="tautulli-log-level-filter" class="btn" style="color: inherit;">
<option value="">All log levels</option>
<option disabled>&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;</option>
<option value="DEBUG">Debug</option>
<option value="INFO">Info</option>
<option value="WARNING">Warning</option>
<option value="ERROR">Error</option>
</select>
</label>
</div>
% if plex_log_files:
<div class="btn-group" id="plex-log-files" style="display: none;">
<label>
<select name="plex-log-files-filter" id="plex-log-files-filter" class="btn" style="color: inherit;">
<option value="">Select Plex Media Server log file</option>
<option disabled>&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;</option>
% for file in plex_log_files:
<option value="${file}">${file}</option>
% endfor
</select>
</label>
</div>
% endif
<div class="btn-group" id="plex-log-levels" style="display: none;">
<label>
<select name="plex-log-level-filter" id="plex-log-level-filter" class="btn" style="color: inherit;">
<option value="">All log levels</option>
<option disabled>&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;</option>
<option value="DEBUG">Debug</option>
<option value="INFO">Info</option>
<option value="WARN">Warning</option>
<option value="ERROR">Error</option>
</select>
</label>
</div>
<button class="btn btn-dark" id="download-tautullilog"><i class="fa fa-download"></i> Download logs</button>
<button class="btn btn-dark" id="download-plexserverlog" style="display: none;"><i class="fa fa-download"></i> Download logs</button>
<button class="btn btn-dark" id="clear-notify-logs" style="display: none;"><i class="fa fa-trash-o"></i> Clear logs</button>
<button class="btn btn-dark" id="clear-newsletter-logs" style="display: none;"><i class="fa fa-trash-o"></i> Clear logs</button>
<button class="btn btn-dark" id="clear-login-logs" style="display: none;"><i class="fa fa-trash-o"></i> Clear logs</button>
</div>
</div>
<div class='table-card-back'>
<div>
<ul id="log_tabs" class="nav nav-pills" role="tablist">
<li role="presentation" class="active"><a id="tautulli-logs-btn" href="#tabs-tautulli_log" aria-controls="tabs-tautulli_log" role="tab" data-toggle="tab">Tautulli Logs</a></li>
<li role="presentation"><a id="tautulli-api-logs-btn" href="#tabs-tautulli_api_log" aria-controls="tabs-tautulli_api_log" role="tab" data-toggle="tab">Tautulli API Logs</a></li>
<li role="presentation"><a id="plex-logs-btn" href="#tabs-plex_log" aria-controls="tabs-plex_log" role="tab" data-toggle="tab">Plex Media Server Logs</a></li>
<li role="presentation"><a id="plex-websocket-logs-btn" href="#tabs-plex_websocket_log" aria-controls="tabs-plex_websocket_log" role="tab" data-toggle="tab">Plex Websocket Logs</a></li>
<li role="presentation"><a id="notification-logs-btn" href="#tabs-notification_log" aria-controls="tabs-notification_log" role="tab" data-toggle="tab">Notification Logs</a></li>
<li role="presentation"><a id="newsletter-logs-btn" href="#tabs-newsletter_log" aria-controls="tabs-newsletter_log" role="tab" data-toggle="tab">Newsletter Logs</a></li>
<li role="presentation"><a id="login-logs-btn" href="#tabs-login_log" aria-controls="tabs-login_log" role="tab" data-toggle="tab">Login Logs</a></li>
</ul>
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="tabs-tautulli_log" data-logfile="tautulli">
<table class="display" id="tautulli_log_table" width="100%">
<thead>
<tr>
<th class="min-tablet" align="left" id="timestamp">Timestamp</th>
<th class="desktop" align="left" id="level">Level</th>
<th class="all" align="left" id="message">Message</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<div role="tabpanel" class="tab-pane" id="tabs-tautulli_api_log" data-logfile="tautulli_api">
<table class="display" id="tautulli_api_log_table" width="100%">
<thead>
<tr>
<th class="min-tablet" align="left" id="timestamp">Timestamp</th>
<th class="desktop" align="left" id="level">Level</th>
<th class="all" align="left" id="message">Message</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<div role="tabpanel" class="tab-pane" id="tabs-plex_websocket_log" data-logfile="plex_websocket">
<table class="display" id="plex_websocket_log_table" width="100%">
<thead>
<tr>
<th class="min-tablet" align="left" id="timestamp">Timestamp</th>
<th class="desktop" align="left" id="level">Level</th>
<th class="all" align="left" id="message">Message</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<div role="tabpanel" class="tab-pane" id="tabs-plex_log">
<table class="display" id="plex_log_table" width="100%">
<thead>
<tr>
<th align="left" id="plex_timestamp">Timestamp</th>
<th align="left" id="plex_level">Level</th>
<th align="left" id="plex_message">Message</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<div role="tabpanel" class="tab-pane" id="tabs-notification_log">
<table class="display" id="notification_log_table" width="100%">
<thead>
<tr>
<th align="left" id="notification_timestamp">Timestamp</th>
<th align="left" id="notification_notifier_id">Notifier ID</th>
<th align="left" id="notification_agent_name">Agent</th>
<th align="left" id="notification_notify_action">Action</th>
<th align="left" id="notification_subject_text">Subject Text</th>
<th align="left" id="notification_body_text">Body Text</th>
<th align="left" id="notification_success"></th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<div role="tabpanel" class="tab-pane" id="tabs-newsletter_log">
<table class="display" id="newsletter_log_table" width="100%">
<thead>
<tr>
<th align="left" id="newsletter_timestamp">Timestamp</th>
<th align="left" id="newsletter_newsletter_id">Newsletter ID</th>
<th align="left" id="newsletter_agent_name">Agent</th>
<th align="left" id="newsletter_notify_action">Action</th>
<th align="left" id="newsletter_subject_text">Subject Text</th>
<th align="left" id="newsletter_body_text">Body Text</th>
<th align="left" id="newsletter_start_date">Start Date</th>
<th align="left" id="newsletter_end_date">End Date</th>
<th align="left" id="newsletter_uuid">UUID</th>
<th align="left" id="newsletter_success"></th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<div role="tabpanel" class="tab-pane" id="tabs-login_log">
<table class="display login_log_table" id="login_log_table" width="100%">
<thead>
<tr>
<th align="left" id="login_timestamp">Timestamp</th>
<th align="left" id="login_friendly_name">User</th>
<th align="left" id="login_user_group">User Group</th>
<th align="left" id="login_ip_address">IP Address</th>
<th align="left" id="login_host">Host</th>
<th align="left" id="login_os">Operating System</th>
<th align="left" id="login_browser">Browser</th>
<th align="left" id="login_expiry">Expiry</th>
<th align="left" id="login_success"></th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<br>
<div align="center">
Refresh rate:
<select id="refreshrate" onchange="setRefresh()">
<option value="0" selected="selected">No Refresh</option>
<option value="5">5 Seconds</option>
<option value="15">15 Seconds</option>
<option value="30">30 Seconds</option>
<option value="60">60 Seconds</option>
<option value="300">5 Minutes</option>
<option value="600">10 Minutes</option>
</select>
</div>
</%def>
<%def name="modalIncludes()">
<div class="modal fade" id="ip-info-modal" tabindex="-1" role="dialog" aria-labelledby="ip-info-modal">
</div>
</%def>
<%def name="javascriptIncludes()">
<script src="${http_root}js/jquery.dataTables.min.js"></script>
<script src="${http_root}js/dataTables.bootstrap.min.js"></script>
<script src="${http_root}js/dataTables.bootstrap.pagination.js"></script>
<script src="${http_root}js/tables/logs.js${cache_param}"></script>
<script src="${http_root}js/tables/plex_logs.js${cache_param}"></script>
<script src="${http_root}js/tables/notification_logs.js${cache_param}"></script>
<script src="${http_root}js/tables/newsletter_logs.js${cache_param}"></script>
<script src="${http_root}js/tables/login_logs.js${cache_param}"></script>
<script>
$(document).ready(function() {
loadtautullilogs('tautulli', selected_log_level);
clearSearchButton('tautulli_log_table', log_table);
});
var log_levels = ['DEBUG', 'INFO', 'WARN', 'ERROR'];
function bindLogLevelFilter() {
clearLogLevelFilter();
var log_level_column = this.api().column(1);
var select = $('#plex-log-level-filter');
select.on('change', function () {
var val = $.fn.dataTable.util.escapeRegex(
$(this).val()
);
var search_string = '';
var levelIndex = log_levels.indexOf(val);
if (levelIndex >= 0) {
search_string = '^' + log_levels
.slice(levelIndex)
.join('|') + '$';
}
log_level_column
.search(search_string, true, false)
.draw();
}).change();
}
function clearLogLevelFilter() {
$('#plex-log-level-filter').off('change');
}
var selected_log_level = null;
function loadtautullilogs(logfile, selected_log_level) {
log_table_options.ajax = {
url: 'get_log',
type: 'POST',
data: function (d) {
return {
logfile: logfile,
json_data: JSON.stringify(d),
log_level: selected_log_level
};
}
};
log_table = $('#' + logfile + '_log_table').DataTable(log_table_options);
$('#tautulli-log-level-filter').on('change', function () {
selected_log_level = $(this).val() || null;
log_table.draw();
});
}
function loadPlexLogs(logfile) {
plex_log_table_options.ajax = {
url: 'get_plex_log',
type: 'POST',
data: {
logfile: logfile
}
};
plex_log_table_options.initComplete = bindLogLevelFilter;
plex_log_table = $('#plex_log_table').DataTable(plex_log_table_options);
}
function loadNotificationLogs() {
notification_log_table_options.ajax = {
url: 'get_notification_log',
type: 'POST',
data: function (d) {
return {
json_data: JSON.stringify(d)
};
}
};
notification_log_table = $('#notification_log_table').DataTable(notification_log_table_options);
}
function loadNewsletterLogs() {
newsletter_log_table_options.ajax = {
url: "get_newsletter_log",
data: function (d) {
return {
json_data: JSON.stringify(d)
};
}
};
newsletter_log_table = $('#newsletter_log_table').DataTable(newsletter_log_table_options);
}
function loadLoginLogs() {
login_log_table_options.pageLength = 50;
login_log_table_options.ajax = {
url: 'get_user_logins',
type: 'POST',
data: function (d) {
return {
json_data: JSON.stringify(d)
};
}
};
login_log_table = $('#login_log_table').DataTable(login_log_table_options);
}
$("#tautulli-logs-btn").click(function () {
$("#tautulli-log-levels").show();
$("#plex-log-files").hide();
$("#plex-log-levels").hide();
$("#clear-logs").show();
$("#download-tautullilog").show();
$("#download-plexserverlog").hide();
$("#clear-notify-logs").hide();
$("#clear-newsletter-logs").hide();
$("#clear-login-logs").hide();
loadtautullilogs('tautulli', selected_log_level);
clearSearchButton('tautulli_log_table', log_table);
});
$("#tautulli-api-logs-btn").click(function () {
$("#tautulli-log-levels").show();
$("#plex-log-files").hide();
$("#plex-log-levels").hide();
$("#clear-logs").show();
$("#download-tautullilog").show();
$("#download-plexserverlog").hide();
$("#clear-notify-logs").hide();
$("#clear-newsletter-logs").hide();
$("#clear-login-logs").hide();
loadtautullilogs('tautulli_api', selected_log_level);
clearSearchButton('tautulli_api_log_table', log_table);
});
$("#plex-websocket-logs-btn").click(function () {
$("#tautulli-log-levels").show();
$("#plex-log-files").hide();
$("#plex-log-levels").hide();
$("#clear-logs").show();
$("#download-tautullilog").show();
$("#download-plexserverlog").hide();
$("#clear-notify-logs").hide();
$("#clear-newsletter-logs").hide();
$("#clear-login-logs").hide();
loadtautullilogs('plex_websocket', selected_log_level);
clearSearchButton('plex_websocket_log_table', log_table);
});
$("#plex-logs-btn").click(function () {
$("#tautulli-log-levels").hide();
$("#plex-log-files").show();
$("#plex-log-levels").show();
$("#clear-logs").hide();
$("#download-tautullilog").hide();
$("#download-plexserverlog").show();
$("#clear-notify-logs").hide();
$("#clear-newsletter-logs").hide();
$("#clear-login-logs").hide();
loadPlexLogs();
clearSearchButton('plex_log_table', plex_log_table);
});
$("#notification-logs-btn").click(function () {
$("#tautulli-log-levels").hide();
$("#plex-log-files").hide();
$("#plex-log-levels").hide();
$("#clear-logs").hide();
$("#download-tautullilog").hide();
$("#download-plexserverlog").hide();
$("#clear-notify-logs").show();
$("#clear-newsletter-logs").hide();
$("#clear-login-logs").hide();
loadNotificationLogs();
clearSearchButton('notification_log_table', notification_log_table);
});
$("#newsletter-logs-btn").click(function () {
$("#tautulli-log-levels").hide();
$("#plex-log-files").hide();
$("#plex-log-levels").hide();
$("#clear-logs").hide();
$("#download-tautullilog").hide();
$("#download-plexserverlog").hide();
$("#clear-notify-logs").hide();
$("#clear-newsletter-logs").show();
$("#clear-login-logs").hide();
loadNewsletterLogs();
clearSearchButton('newsletter_log_table', newsletter_log_table);
});
$("#login-logs-btn").click(function () {
$("#tautulli-log-levels").hide();
$("#plex-log-files").hide();
$("#plex-log-levels").hide();
$("#clear-logs").hide();
$("#download-tautullilog").hide();
$("#download-plexserverlog").hide();
$("#clear-notify-logs").hide();
$("#clear-newsletter-logs").hide();
$("#clear-login-logs").show();
loadLoginLogs();
clearSearchButton('login_log_table', notification_log_table);
});
$("#plex-log-files").on('change', function () {
var logfile = $("option:selected", this).val();
loadPlexLogs(logfile);
clearSearchButton('plex_log_table', plex_log_table);
});
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
$.fn.dataTable.tables({ visible: true, api: true }).columns.adjust();
});
$("#clear-logs").click(function () {
var logfile = $(".tab-pane.active").data('logfile');
var title = $("#log_tabs li.active a").text();
$("#confirm-message").text("Are you sure you want to clear the " + title + "?");
$('#confirm-modal').modal();
$('#confirm-modal').one('click', '#confirm-button', function () {
$.ajax({
url: 'delete_logs',
type: 'POST',
data: { logfile: logfile },
complete: function (xhr, status) {
result = $.parseJSON(xhr.responseText);
msg = result.message;
if (result.result === 'success') {
showMsg('<i class="fa fa-check"></i> ' + msg, false, true, 5000)
} else {
showMsg('<i class="fa fa-times"></i> ' + msg, false, true, 5000, true)
}
log_table.draw();
}
});
});
});
$("#download-tautullilog").click(function () {
var logfile = $(".tab-pane.active").data('logfile');
window.location.href = "download_log?logfile=" + window.encodeURIComponent(logfile);
});
$("#download-plexserverlog").click(function () {
var logfile = $("option:selected", "#plex-log-files").val();
window.location.href = "download_plex_log?logfile=" + window.encodeURIComponent(logfile);
});
$("#clear-notify-logs").click(function () {
$("#confirm-message").text("Are you sure you want to clear the Tautulli Notification Logs?");
$('#confirm-modal').modal();
$('#confirm-modal').one('click', '#confirm-button', function () {
$.ajax({
url: 'delete_notification_log',
type: 'POST',
complete: function (xhr, status) {
result = $.parseJSON(xhr.responseText);
msg = result.message;
if (result.result === 'success') {
showMsg('<i class="fa fa-check"></i> ' + msg, false, true, 5000)
} else {
showMsg('<i class="fa fa-times"></i> ' + msg, false, true, 5000, true)
}
notification_log_table.draw();
}
});
});
});
$("#clear-newsletter-logs").click(function () {
$("#confirm-message").text("Are you sure you want to clear the Tautulli Newsletter Logs?");
$('#confirm-modal').modal();
$('#confirm-modal').one('click', '#confirm-button', function () {
$.ajax({
url: 'delete_newsletter_log',
type: 'POST',
complete: function (xhr, status) {
result = $.parseJSON(xhr.responseText);
msg = result.message;
if (result.result === 'success') {
showMsg('<i class="fa fa-check"></i> ' + msg, false, true, 5000)
} else {
showMsg('<i class="fa fa-times"></i> ' + msg, false, true, 5000, true)
}
newsletter_log_table.draw();
}
});
});
});
$("#clear-login-logs").click(function () {
$("#confirm-message").text("Are you sure you want to clear the Tautulli Login Logs?");
$('#confirm-modal').modal();
$('#confirm-modal').one('click', '#confirm-button', function () {
$.ajax({
url: 'delete_login_log',
type: 'POST',
complete: function (xhr, status) {
result = $.parseJSON(xhr.responseText);
msg = result.message;
if (result.result === 'success') {
showMsg('<i class="fa fa-check"></i> ' + msg, false, true, 5000)
} else {
showMsg('<i class="fa fa-times"></i> ' + msg, false, true, 5000, true)
}
window.location = 'auth/logout';
}
});
});
});
var timer;
function setRefresh()
{
refreshrate = document.getElementById('refreshrate');
if(refreshrate != null)
{
if(timer)
{
clearInterval(timer);
}
if(refreshrate.value !== 0)
{
timer = setInterval(function() {
if ($("#tabs-tautulli_log").hasClass("active") || $("#tabs-tautulli_api_log").hasClass("active") || $("#tabs-plex_websocket_log").hasClass("active")) {
log_table.ajax.reload();
} else if ($("#tabs-plex_log").hasClass("active")) {
plex_log_table.ajax.reload();
} else if ($("#tabs-notificaiton_log").hasClass("active")) {
notification_log_table.ajax.reload();
} else if ($("#tabs-login_log").hasClass("active")) {
login_log_table.ajax.reload();
}
}, 1000*refreshrate.value);
}
}
}
</script>
</%def>