loggingDashboard.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. /* global logConfigFileLocation, SockJS, Stomp */
  2. var stompClient = null;
  3. function setConnected(connected) {
  4. var el = document.getElementById('websocketStatus');
  5. el.style.visibility = connected ? 'visible' : 'hidden';
  6. el.class = connected ? 'alert alert-info' : 'alert alert-danger';
  7. if (!connected) {
  8. el.innerHTML = 'Disconnected!';
  9. } else {
  10. el.innerHTML = 'Connected to CAS. Streaming and tailing logs based on <kbd>[' + logConfigFileLocation + ']</kbd>...';
  11. }
  12. }
  13. function connect() {
  14. $('#logoutputarea').empty();
  15. var socket = new SockJS(urls.reportsWebsocket);
  16. stompClient = Stomp.over(socket);
  17. stompClient.connect({}, function () {
  18. setConnected(true);
  19. stompClient.subscribe('/topic/logs', function (msg) {
  20. if (msg != null && msg.body != '') {
  21. showLogs(msg.body);
  22. }
  23. });
  24. });
  25. }
  26. function disconnect() {
  27. $('#logoutputarea').empty();
  28. $('#logoutputarea').attr('readonly', 'readonly');
  29. if (stompClient != null) {
  30. stompClient.disconnect();
  31. }
  32. setConnected(false);
  33. }
  34. function showLogs(message) {
  35. if (message != '') {
  36. $('#logoutputarea').val($('#logoutputarea').val() + '\n' + message);
  37. $('#logoutputarea').scrollTop(document.getElementById('logoutputarea').scrollHeight);
  38. }
  39. }
  40. disconnect();
  41. connect();
  42. setInterval(function () {
  43. }, 100);
  44. /*************
  45. *
  46. ***************/
  47. $('#myTabs a').click(function (e) {
  48. e.preventDefault();
  49. $(this).tab('show');
  50. });
  51. var alertHandler = (function () {
  52. var alertContainer = $('#alert-container');
  53. var create = function (message, state) {
  54. //console.log('create the alert');
  55. alertContainer.html('<div class="alert alert-' + state + ' alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button><span>' + message + '</span></div>');
  56. alertContainer.delay(2000).fadeOut('slow');
  57. };
  58. var destroy = function () {
  59. alertContainer.empty();
  60. };
  61. return {
  62. dismiss: function () {
  63. destroy();
  64. },
  65. show: function (msg, state) {
  66. create(msg, state);
  67. }
  68. };
  69. })();
  70. var loggingDashboard = (function () {
  71. var json = null;
  72. var logLevels = ['trace', 'debug', 'info', 'warn', 'error'];
  73. var getData = function () {
  74. $.getJSON(urls.getConfiguration, function (data) {
  75. json = data;
  76. loggerTable();
  77. });
  78. };
  79. var getAuditData = function () {
  80. $.getJSON(urls.getAuditLog, function (data) {
  81. if ($(data).length > 0) {
  82. loggerTableAudit(data);
  83. } else {
  84. $('#auditLogTable').DataTable();
  85. }
  86. });
  87. };
  88. var loggerTableAudit = function (jsonData) {
  89. var t = $('#auditLogTable').DataTable({
  90. 'autoWidth': false,
  91. 'order': [[3, 'desc']],
  92. retrieve: true,
  93. columnDefs: [
  94. {'width': '5%', 'targets': 0},
  95. {'width': '100%', 'targets': 1},
  96. {
  97. 'targets': 2,
  98. render: function (data) {
  99. var dd = data.toLowerCase();
  100. if (dd.indexOf('created') != -1) {
  101. return '<span class="glyphicon glyphicon-plus" aria-hidden="true">&nbsp;</span>' + data;
  102. }
  103. if (dd.indexOf('validated') != -1) {
  104. return '<span class="glyphicon glyphicon-ok" aria-hidden="true">&nbsp;</span>' + data;
  105. }
  106. if (dd.indexOf('destroyed') != -1 || dd.indexOf('deleted') != -1) {
  107. return '<span class="glyphicon glyphicon-minus" aria-hidden="true">&nbsp;</span>' + data;
  108. }
  109. if (dd.indexOf('success') != -1) {
  110. return '<span class="glyphicon glyphicon-thumbs-up" aria-hidden="true">&nbsp;</span>' + data;
  111. }
  112. if (dd.indexOf('failed') != -1) {
  113. return '<span class="glyphicon glyphicon-thumbs-down" aria-hidden="true">&nbsp;</span>' + data;
  114. }
  115. return data;
  116. }
  117. }
  118. ]
  119. });
  120. for (var i = 0; i < jsonData.length; i++) {
  121. var rec = jsonData[i];
  122. t.row.add([
  123. rec.principal,
  124. rec.resourceOperatedUpon,
  125. rec.actionPerformed,
  126. new Date(rec.whenActionWasPerformed),
  127. rec.clientIpAddress,
  128. rec.serverIpAddress
  129. ]).draw(false);
  130. }
  131. };
  132. var loggerTable = function () {
  133. $('#loggersTable').DataTable({
  134. 'autoWidth': false,
  135. 'order': [[1, 'desc']],
  136. data: json.loggers,
  137. 'drawCallback': function () {
  138. var api = this.api();
  139. if (api.page.info().pages > 1) {
  140. $('#' + $.fn.dataTable.tables()[0].id + '_paginate')[0].style.display = 'block';
  141. } else {
  142. $('#' + $.fn.dataTable.tables()[0].id + '_paginate')[0].style.display = 'none';
  143. }
  144. },
  145. 'initComplete': function (settings) {
  146. if (!settings.aoData || settings.aoData.length == 0) {
  147. $('#loadingMessage').addClass('d-none');
  148. $('#errorLoadingData').removeClass('d-none');
  149. } else {
  150. $('#loadingMessage').addClass('d-none');
  151. $('#errorLoadingData').addClass('d-none');
  152. $('#loggingDashboard .tabsContainer').removeClass('d-none');
  153. }
  154. },
  155. 'processing': true,
  156. columnDefs: [
  157. {
  158. 'targets': 0,
  159. 'className': 'details-control',
  160. 'orderable': false,
  161. 'data': 'appenders',
  162. 'defaultContent': '',
  163. render: function (data) {
  164. if (data.length > 0) {
  165. return '<span></span>';
  166. } else {
  167. return '';
  168. }
  169. }
  170. },
  171. {
  172. targets: 1,
  173. data: 'name',
  174. className: 'col-xs-5'
  175. },
  176. {
  177. targets: 2,
  178. data: 'additive',
  179. className: 'additive col-xs-2',
  180. render: function (data) {
  181. if (data) {
  182. return '<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>';
  183. } else {
  184. return '<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>';
  185. }
  186. }
  187. },
  188. {
  189. targets: 3,
  190. data: 'state',
  191. className: 'col-xs-2'
  192. },
  193. {
  194. targets: 4,
  195. data: 'level',
  196. className: 'col-xs-3',
  197. render: function (data, type, full, meta) {
  198. return toggleSwitch(data, type, full, meta);
  199. }
  200. }
  201. ]
  202. });
  203. };
  204. var toggleSwitch = function (data, type, full) {
  205. // Todo: Add additional colors for the other options
  206. //console.log('toggleSwitch data',data);
  207. //console.log('type',type);
  208. //console.log('full',full);
  209. //console.log('meta',meta);
  210. //console.log(logLevels);
  211. var btnColor;
  212. switch (data.toLowerCase()) {
  213. case 'error':
  214. btnColor = 'danger';
  215. break;
  216. case 'info':
  217. btnColor = 'info';
  218. break;
  219. case 'warn':
  220. btnColor = 'warning';
  221. break;
  222. default:
  223. btnColor = 'default';
  224. }
  225. var btnGroup = '<div class="dropdown" data-logger="' + full + '"><button class="btn btn-sm btn-block bg-' + btnColor + ' dropdown-toggle" name="recordinput" data-toggle="dropdown">' + data + ' <span class="caret"></span></button>' +
  226. '<div class="dropdown-menu">';
  227. for (var i = 0; i < logLevels.length; i++) {
  228. btnGroup += '<a class="dropdown-item" href="#">' + logLevels[i].toUpperCase() + '</a>';
  229. }
  230. btnGroup += '</div>';
  231. return btnGroup;
  232. };
  233. /* Formatting function for row details - modify as you need */
  234. var viewAppenders = function (data) {
  235. return '<table class="table table-bordered row-detail"><tbody><tr class="">' +
  236. '<td class="field-label active">Appenders:</td>' +
  237. '<td><kbd>' + JSON.stringify(data.appenders, null, 2) + '</kbd></td>' +
  238. '</tr>' +
  239. '</tbody></table>';
  240. };
  241. var addEventHandlers = function () {
  242. //console.log('addEventHAndlers()');
  243. $(document).on('click', '#loggersTable .dropdown-menu a', function (e) {
  244. //console.log('status change', this);
  245. e.preventDefault();
  246. var selText = $(this).text();
  247. changeLogLevel(selText, this);
  248. });
  249. $(document).on('click', '#loggersTable tbody td.details-control span', function () {
  250. var table = $('#loggersTable').DataTable();
  251. var tr = $(this).closest('tr');
  252. var row = table.row(tr);
  253. if (row.child.isShown()) {
  254. // This row is already open - close it
  255. row.child.hide();
  256. tr.removeClass('shown');
  257. } else {
  258. // Open this row
  259. row.child(viewAppenders(row.data()), 'info').show();
  260. tr.addClass('shown');
  261. }
  262. });
  263. };
  264. var changeLogLevel = function (newLevel, el) {
  265. /**
  266. * POST - /cas/status/logging/updateLoggerLevel
  267. * Allows you to change the log level for given LOGGER. Parameters are:
  268. * loggerName, loggerLevel, additive (true/false)
  269. */
  270. var table = $('#loggersTable').DataTable();
  271. var data = table.row($(el).closest('tr')[0]).data();
  272. if (newLevel != data.level) {
  273. var cell = table.cell($(el).closest('td')[0]);
  274. $.post(urls.updateLevel, {
  275. loggerName: data.name,
  276. loggerLevel: newLevel,
  277. additive: data.additive
  278. }, function () {
  279. cell.data(newLevel).draw();
  280. alertHandler.show('Successfully changed.', 'success');
  281. }).fail(function () {
  282. alertHandler.show('Error saving change. Please try again', 'danger');
  283. });
  284. }
  285. };
  286. // initialization *******
  287. (function init() {
  288. })();
  289. return {
  290. init: function () {
  291. getData();
  292. addEventHandlers();
  293. getAuditData();
  294. },
  295. getJson: function () {
  296. return json;
  297. },
  298. showLoggersTable: function () {
  299. loggerTable();
  300. }
  301. };
  302. })();
  303. loggingDashboard.init();