]> jfr.im git - irc/unrealircd/unrealircd-webpanel.git/blame - logs/index.php
Logs: Add some explanation in the initial header. At least for now when
[irc/unrealircd/unrealircd-webpanel.git] / logs / index.php
CommitLineData
0ba71cfd
BM
1<?php
2require_once "../inc/common.php";
3require_once "../inc/header.php";
4?>
5<h4>Log viewer</h4>
1c8f86d1 6<p>This fetches up to 1000 historical log entries from UnrealIRCd (requires 6.1.1-git+) and then follows the logs 'live'.</p>
0ba71cfd
BM
7 <!-- The log table -->
8 <form method="post">
9 <table id="data_list" class="table-striped display nowrap" style="width:100%">
c69491f1 10 <thead class="table-primary">
0ba71cfd
BM
11 <th scope="col">Time</th>
12 <th scope="col">Level</th>
13 <th scope="col">Subsystem</th>
14 <th scope="col">Event</th>
15 <th scope="col">Message</th>
16 </thead>
17 </table>
18 </form>
19
ff6f464f
BM
20<!-- View log entry -->
21 <div class="modal" id="view_log_entry" tabindex="-1" role="dialog" aria-labelledby="confirmModalCenterTitle" aria-hidden="true">
22 <div class="modal-dialog modal-xl" role="document">
23 <form method="post">
24 <div class="modal-content">
25 <div class="modal-header">
26 <h5 class="modal-title" id="view_log_entry_title">View log entry</h5>
27 <button type="button" class="close" data-dismiss="modal" aria-label="Close">
28 <span aria-hidden="true">&times;</span></button>
29 </div>
30 <div class="modal-body">
31 <ul class="nav nav-tabs" role="tablist">
32 <li class="nav-item" role="presentation"><a class="nav-link active" href="#event_pane" aria-controls="event_pane" role="tab" data-toggle="tab">Log entry</a></li>
33 <li class="nav-item" role="presentation"><a class="nav-link" href="#json_pane" aria-controls="json_pane" role="tab" data-toggle="tab">JSON</a></li>
34 </ul>
35
36 <div class="tab-content">
37 <div class="tab-pane show active" id="event_pane">
38 <table class="table-sm table-responsive caption-top table-hover">
39 <tbody>
40 <tr><td>Time</td><td id="view_log_entry_time"></td></tr>
41 <tr><td>Level</td><td id="view_log_entry_level"></td></tr>
42 <tr><td>Subsystem</td><td id="view_log_entry_subsystem"></td></tr>
43 <tr><td>Event</td><td id="view_log_entry_event"></td></tr>
44 <tr><td>Message</td><td id="view_log_entry_message" class="tdwrap"></td></tr>
45 </tbody>
46 </table>
47 </div>
48 <div class="tab-pane" id="json_pane">
49 <p class="card-text tdwrap" id="view_log_entry_json"></p>
50 </div>
51 </div>
52 </div>
53
54 <div class="modal-footer">
55 <!-- do we want a button at all? -->
56 </div>
57 </div>
58 </form>
59 </div>
60 </div>
61
62
63<script src="../js/json-formatter.umd.js"></script>
0ba71cfd
BM
64<script>
65let data_list_table = null;
66
67function level2color(level)
68{
69 if (level == 'info')
70 return 'green';
71 if (level == 'warn')
72 return 'orange';
73 if ((level == 'error') || (level == 'fatal'))
74 return 'red';
75}
76
77function log_colorizer(data, type, row)
78{
79 if (type == 'display')
80 {
81 var color = level2color(row['Level']);
82 data = '<span style="color: '+color+'">' + data + '</span>';
83 }
84 return data;
85}
86
87function log_timestamp(data, type, row)
88{
89 if (type == 'display')
90 {
91 return moment.utc(data).local().format('HH:mm:ss');
92 }
93 return data;
94}
95
96function resize_check()
97{
98 if (window.innerWidth < 900)
99 {
100 data_list_table.column(1).visible(false); // level
101 data_list_table.column(2).visible(false); // subsystem
102 data_list_table.column(3).visible(false); // event
103 } else
104 if (window.innerWidth < 1250)
105 {
106 data_list_table.column(1).visible(true); // level
107 data_list_table.column(2).visible(false); // subsystem
108 data_list_table.column(3).visible(false); // event
109 } else
110 if (window.innerWidth < 1450)
111 {
112 data_list_table.column(1).visible(true); // level
113 data_list_table.column(2).visible(true); // subsystem
114 data_list_table.column(3).visible(false); // event
115 } else
116 {
117 data_list_table.column(1).visible(true); // level
118 data_list_table.column(2).visible(true); // subsystem
119 data_list_table.column(3).visible(true); // event
120 }
121 data_list_table.rows().invalidate('data').draw(false);
122}
123
124function log_text(data, type, row)
125{
126 var esc = function (t) {
127 return ('' + t)
128 .replace(/&/g, '&amp;')
129 .replace(/</g, '&lt;')
130 .replace(/>/g, '&gt;')
131 .replace(/"/g, '&quot;');
132 };
133
134 if (type != 'display')
135 return data;
136
137 var color = level2color(row['Level']);
138 var cutoff;
139 if (window.innerWidth < 500)
140 cutoff = 35;
141 else if (window.innerWidth < 1000)
142 cutoff = 75;
143 else if (window.innerWidth < 1750)
144 cutoff = 100
145 else
146 cutoff = 125;
147
148 if (data.length > cutoff)
149 {
150 // stolen from ellipsis
151 var shortened = data.substr(0, cutoff - 1);
152 data = '<span class="ellipsis" style="color: '+color+'" title="' +
153 esc(data) +
154 '">' +
155 shortened +
156 '&#8230;</span>';
157 } else {
158 // otherwise just like log_colorizer...
159 data = '<span style="color: '+color+'">' + data + '</span>';
160 }
161 return data;
162}
163
164$(document).ready( function () {
165 args = {
166 //'responsive': true,
167 'fixedHeader': {
168 header: true,
169 headerOffset: 53
170 },
171 'columns': [
ff6f464f
BM
172 { 'data': 'Time', 'responsivePriority': 1, 'render': log_timestamp, 'className':'virtuallink' },
173 { 'data': 'Level', 'responsivePriority': 3, 'render': log_colorizer },
0ba71cfd
BM
174 { 'data': 'Subsystem', 'responsivePriority': 4, 'render': log_colorizer },
175 { 'data': 'Event', 'responsivePriority': 5, 'render': log_colorizer },
176 //{ 'data': 'Message', 'responsivePriority': 2, 'render': DataTable.render.ellipsis(100, false) },
177 { 'data': 'Message', 'responsivePriority': 2, 'render': log_text },
0e8dc61e 178 { 'data': 'Raw', 'visible': false, 'searchable': true },
0ba71cfd
BM
179 ],
180 'pageLength':100,
181 'order':[[0,'desc']],
eec5c0f9
BM
182 'language':{
183 searchPlaceholder: "Nick, IP, anything...",
184 }
0ba71cfd
BM
185 };
186
187 /* Only show filter pane on desktop */
99eb79c4 188 if (window.innerWidth > 800)
0ba71cfd
BM
189 {
190 args['dom'] = 'Pfrtip';
191 args['searchPanes'] = {
192 'initCollapsed': 'true',
193 'columns': [1,2,3],
194 'dtOpts': {
195 select: { style: 'multi'},
196 order: [[ 1, "desc" ]]
197 },
198 }
199 }
200
201 data_list_table = $('#data_list').DataTable(args);
202
203 resize_check();
204 window.addEventListener('resize', resize_check);
205
206 StartLogStream('<?php echo get_config('base_url'); ?>api/log.php');
ff6f464f
BM
207
208 $('#data_list').on( 'click', 'td', function () {
209 view_log_entry(this);
210 } );
0ba71cfd 211} );
ff6f464f
BM
212
213function view_log_entry(e)
214{
215 var data = data_list_table.row(e).data();
216 $('#view_log_entry_time').html('<code>' + data['Time'] + '</code>')
217 $('#view_log_entry_level').html('<code>' + data['Level'] + '</code>')
218 $('#view_log_entry_subsystem').html('<code>' + data['Subsystem'] + '</code>')
219 $('#view_log_entry_event').html('<code>' + data['Event'] + '</code>')
220 $('#view_log_entry_message').html('<pre class="tdwrap">' + data['Message'] + '</pre>')
0e8dc61e
BM
221 j = JSON.parse(data['Raw']);
222 j = new JSONFormatter(j, 99);
ff6f464f
BM
223 $('#view_log_entry_json').html(j.render());
224 $('#view_log_entry').modal('show');
225}
0ba71cfd
BM
226</script>
227
228<?php require_once '../inc/footer.php'; ?>