mirror of
https://github.com/Tautulli/Tautulli.git
synced 2024-11-21 04:50:36 -08:00
556 lines
26 KiB
HTML
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>────────────</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>────────────</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>────────────</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>
|