luci-mod-status: auto-refresh system log and kernel log
[project/luci.git] / modules / luci-mod-status / htdocs / luci-static / resources / view / status / syslog.js
1 'use strict';
2 'require view';
3 'require fs';
4 'require poll';
5 'require ui';
6
7 return view.extend({
8 retrieveLog: async function() {
9 return Promise.all([
10 L.resolveDefault(fs.stat('/sbin/logread'), null),
11 L.resolveDefault(fs.stat('/usr/sbin/logread'), null)
12 ]).then(function(stat) {
13 var logger = stat[0] ? stat[0].path : stat[1] ? stat[1].path : null;
14
15 return fs.exec_direct(logger, [ '-e', '^' ]).then(logdata => {
16 const loglines = logdata.trim().split(/\n/);
17 return { value: loglines.join('\n'), rows: loglines.length + 1 };
18 }).catch(function(err) {
19 ui.addNotification(null, E('p', {}, _('Unable to load log data: ' + err.message)));
20 return '';
21 });
22 });
23 },
24
25 pollLog: async function() {
26 const element = document.getElementById('syslog');
27 if (element) {
28 const log = await this.retrieveLog();
29 element.value = log.value;
30 element.rows = log.rows;
31 }
32 },
33
34 load: async function() {
35 poll.add(this.pollLog.bind(this));
36 return await this.retrieveLog();
37 },
38
39 render: function(loglines) {
40 var scrollDownButton = E('button', {
41 'id': 'scrollDownButton',
42 'class': 'cbi-button cbi-button-neutral'
43 }, _('Scroll to tail', 'scroll to bottom (the tail) of the log file')
44 );
45 scrollDownButton.addEventListener('click', function() {
46 scrollUpButton.focus();
47 });
48
49 var scrollUpButton = E('button', {
50 'id' : 'scrollUpButton',
51 'class': 'cbi-button cbi-button-neutral'
52 }, _('Scroll to head', 'scroll to top (the head) of the log file')
53 );
54 scrollUpButton.addEventListener('click', function() {
55 scrollDownButton.focus();
56 });
57
58 return E([], [
59 E('h2', {}, [ _('System Log') ]),
60 E('div', { 'id': 'content_syslog' }, [
61 E('div', {'style': 'padding-bottom: 20px'}, [scrollDownButton]),
62 E('textarea', {
63 'id': 'syslog',
64 'style': 'font-size:12px',
65 'readonly': 'readonly',
66 'wrap': 'off',
67 'rows': loglines.rows,
68 }, [ loglines.value ]),
69 E('div', {'style': 'padding-bottom: 20px'}, [scrollUpButton])
70 ])
71 ]);
72 },
73
74 handleSaveApply: null,
75 handleSave: null,
76 handleReset: null
77 });