Added log viewer to Tools

This commit is contained in:
Andy Miller
2019-01-31 18:39:38 -07:00
parent 2dbc031366
commit 6e47578769
13 changed files with 186 additions and 7 deletions

View File

@@ -1,6 +1,8 @@
# v1.9.0-rc.2
## mm/dd/2019
1. [](#new)
* Added new `Logs` section to tools to allow quick view of Grav log files
1. [](#improved)
* Better logic for delete action to support Ajax. Fixes Flex lists

View File

@@ -3,6 +3,7 @@ namespace Grav\Plugin;
use Grav\Common\File\CompiledYamlFile;
use Grav\Common\Grav;
use Grav\Common\Helpers\LogViewer;
use Grav\Common\Inflector;
use Grav\Common\Language\Language;
use Grav\Common\Page\Page;
@@ -498,6 +499,7 @@ class AdminPlugin extends Plugin
$twig->twig_vars['base_path'] = GRAV_ROOT;
$twig->twig_vars['admin'] = $this->admin;
$twig->twig_vars['admin_version'] = $this->version;
$twig->twig_vars['logviewer'] = new LogViewer();
$fa_icons_file = CompiledYamlFile::instance($this->grav['locator']->findResource('plugin://admin/themes/grav/templates/forms/fields/iconpicker/icons' . YAML_EXT));
$fa_icons = $fa_icons_file->content();
@@ -848,6 +850,7 @@ class AdminPlugin extends Plugin
$event['tools'] = array_merge($event['tools'], [
$this->grav['language']->translate('PLUGIN_ADMIN.BACKUPS'),
$this->grav['language']->translate('PLUGIN_ADMIN.SCHEDULER'),
$this->grav['language']->translate('PLUGIN_ADMIN.LOGS'),
$this->grav['language']->translate('PLUGIN_ADMIN.REPORTS'),
$this->grav['language']->translate('PLUGIN_ADMIN.DIRECT_INSTALL'),
]);

View File

@@ -781,5 +781,6 @@ PLUGIN_ADMIN:
UPLOADS_DANGEROUS_EXTENSIONS: "Dangerous Extensions"
UPLOADS_DANGEROUS_EXTENSIONS_HELP: "Block these extensions from being uploaded no matter the accepted MIME types"
REPORTS: "Reports"
LOGS: "Logs"

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,3 +1,3 @@
body,h5,h6,.badge,.note,.grav-mdeditor-preview,input,select,textarea,button,.selectize-input,h1,h2,h3,h4,#admin-menu li,.form-tabs>label,.label,body .CodeMirror pre{font-family:"Helvetica Neue", "Helvetica", "Tahoma", "Geneva", "Arial", sans-serif}code,kbd,pre,samp{font-family:"Monaco", "Consolas", "Lucida Console", monospace}
body,h5,h6,.badge,.note,.grav-mdeditor-preview,input,select,textarea,button,.selectize-input,h1,h2,h3,h4,#admin-menu li,.form-tabs>label,.label,body .CodeMirror pre{font-family:"Helvetica Neue", "Helvetica", "Tahoma", "Geneva", "Arial", sans-serif}code,kbd,pre,samp,.mono{font-family:"Monaco", "Consolas", "Lucida Console", monospace}
/*# sourceMappingURL=simple-fonts.css.map */

View File

@@ -1 +1 @@
{"version":3,"file":"simple-fonts.css","sources":["simple-fonts.scss"],"sourcesContent":["body, h5, h6,\n.badge, .note, .grav-mdeditor-preview,\ninput, select, textarea, button, .selectize-input,\nh1, h2, h3, h4,\n#admin-menu li, .form-tabs > label, .label,\nbody .CodeMirror pre {\n font-family: \"Helvetica Neue\", \"Helvetica\", \"Tahoma\", \"Geneva\", \"Arial\", sans-serif;\n}\ncode, kbd, pre, samp {\n font-family: \"Monaco\", \"Consolas\", \"Lucida Console\", monospace;\n}\n\n"],"names":[],"mappings":"AAAA,AAAA,IAAI,CAAE,EAAE,CAAE,EAAE,CACZ,MAAM,CAAE,KAAK,CAAE,sBAAsB,CACrC,KAAK,CAAE,MAAM,CAAE,QAAQ,CAAE,MAAM,CAAE,gBAAgB,CACjD,EAAE,CAAE,EAAE,CAAE,EAAE,CAAE,EAAE,CACd,WAAW,CAAC,EAAE,CAAE,UAAU,CAAG,KAAK,CAAE,MAAM,CAC1C,IAAI,CAAC,WAAW,CAAC,GAAG,AAAC,CACjB,WAAW,CAAE,sEAAsE,CACtF,AACD,AAAA,IAAI,CAAE,GAAG,CAAE,GAAG,CAAE,IAAI,AAAE,CAClB,WAAW,CAAE,iDAAiD,CACjE"}
{"version":3,"file":"simple-fonts.css","sources":["simple-fonts.scss"],"sourcesContent":["body, h5, h6,\n.badge, .note, .grav-mdeditor-preview,\ninput, select, textarea, button, .selectize-input,\nh1, h2, h3, h4,\n#admin-menu li, .form-tabs > label, .label,\nbody .CodeMirror pre {\n font-family: \"Helvetica Neue\", \"Helvetica\", \"Tahoma\", \"Geneva\", \"Arial\", sans-serif;\n}\ncode, kbd, pre, samp, .mono {\n font-family: \"Monaco\", \"Consolas\", \"Lucida Console\", monospace;\n}\n\n"],"names":[],"mappings":"AAAA,AAAA,IAAI,CAAE,EAAE,CAAE,EAAE,CACZ,MAAM,CAAE,KAAK,CAAE,sBAAsB,CACrC,KAAK,CAAE,MAAM,CAAE,QAAQ,CAAE,MAAM,CAAE,gBAAgB,CACjD,EAAE,CAAE,EAAE,CAAE,EAAE,CAAE,EAAE,CACd,WAAW,CAAC,EAAE,CAAE,UAAU,CAAG,KAAK,CAAE,MAAM,CAC1C,IAAI,CAAC,WAAW,CAAC,GAAG,AAAC,CACjB,WAAW,CAAE,sEAAsE,CACtF,AACD,AAAA,IAAI,CAAE,GAAG,CAAE,GAAG,CAAE,IAAI,CAAE,KAAK,AAAE,CACzB,WAAW,CAAE,iDAAiD,CACjE"}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1701,6 +1701,35 @@ body .bootstrap-datetimepicker-widget {
}
}
// Log Viewer
.logs-output {
table.noflex {
td.level .badge {
&.error, &.critical, &.alert {
background-color: #DC3023;
color: #fff;
}
&.notice, &.warning {
background-color: #E08A1E;
color: #fff;
}
&.debug {
background-color: #26A65B;
color: #fff;
}
&.info {
background-color: #22A7F0;
color: #fff;
}
&.emergency {
background-color: #8E44AD;
color: #fff;
}
}
}
}
.permission-container {
overflow: hidden;
}

View File

@@ -6,7 +6,7 @@ h1, h2, h3, h4,
body .CodeMirror pre {
font-family: "Helvetica Neue", "Helvetica", "Tahoma", "Geneva", "Arial", sans-serif;
}
code, kbd, pre, samp {
code, kbd, pre, samp, .mono {
font-family: "Monaco", "Consolas", "Lucida Console", monospace;
}

View File

@@ -1239,4 +1239,69 @@ body.sidebar-quickopen #admin-main {
}
}
// Log Viewer
.logs-output {
form {
float: right;
.form-select {
display: inline-block;
width: auto;
}
}
h1 {
margin-top: 2rem !important;
}
h3 {
padding: 0.5rem 1.5rem;
font-size: 1.1rem;
}
table.noflex {
td {
vertical-align: top;
}
td.date, td.level {
white-space: nowrap;
}
td.date {
opacity: 0.7;
}
th.level, td.level {
padding: 0.375rem 30px;
}
td.level {
font-weight: bold;
span.badge {
font-size: 0.7rem;
}
}
td.message {
width: 100%;
}
.trace {
ol {
margin: 10px 0;
padding: 0;
font-size: 0.7rem;
code {
font-size: 0.7rem;
}
}
}
}
}

View File

@@ -0,0 +1,79 @@
<div class="logs-content">
{% if authorize(['admin.super']) %}
{% set file = grav.uri.param('log') ?: 'grav' %}
{% set verbose = grav.uri.param('verbose') == 'true' ? true : false %}
{% set lines = grav.uri.param('lines') ?: 20 %}
{% set logfile = grav.locator.findResource("log://" ~ file ~ '.log') %}
{% set logs = logviewer.objectTail(logfile, lines|int, false) %}
<div class="logs-output">
{# example: /admin/tools/logs/file:email/verbose:true/lines:50 #}
{# This could be changed to use query string rather than params.. just code above... #}
<form>
<div class="block block-select">
<div class="form-field">
<div class="form-data">
<select class="form-select selectized" name="log">
<option value="grav">Grav</option>
<option value="email">Email</option>
</select>
<select class="form-select selectized" name="verbose">
<option value="false">Essential Details</option>
<option value="true">Verbose Output</option>
</select>
<select class="form-select selectized" name="lines">
<option value="10">10 entries</option>
<option value="25">25 entries</option>
<option value="50">50 entries</option>
<option value="100">100 entries</option>
<option value="200">200 entries</option>
<option value="500">500 entries</option>
</select>
</div>
</div>
</div>
</form>
<h1>{{ file|titleize }} Log File</h1>
<h3>Display the {{ lines }} most recent entries...</h3>
<table class="noflex">
<thead>
<tr>
<th class="date">Date</th>
<th class="level">Level</th>
<th class="message">Message</th>
</tr>
</thead>
<tbody>
{% for log in logs %}
<tr>
<td class="date">{{ log.date|date }}</td>
<td class="level"><span class="badge {{ log.level|lower }}">{{ log.level }}</span></td>
<td class="message">{{ log.message }}</td>
{% if verbose %}
</tr>
<tr class="trace">
<td colspan="2">&nbsp;</td>
<td>
<div class="overflow">
<ol>
{% for tracerow in log.trace %}
<li><code>{{ tracerow }}</code></li>
{% endfor %}
</ol>
</div>
</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
</div>