Files
logview/app/resources/views/logs/show.blade.php

154 lines
6.5 KiB
PHP

@extends('logs.base')
@section('page_content')
<div class="ui container">
<h3 class="ui header">Log File: {{$log->getFilename()}}</h3>
<h5 class="ui header">{{$log->getDate()->format('Y-m-d H:i:s')}}</h5>
<div class="ui accordion" id="logs"></div>
<hr id="watch" style="border: none;" />
</div>
@endsection
@push('page_styles')
<style>
body {overflow-y:scroll;}
@foreach ($levels as $level => $colors)
.{{$level}} {background-color: {{$colors->background}}; color: {{$colors->text}};}
@endforeach
</style>
@endpush
@push('page_scripts')
<script type="text/javascript">
const logs = {
id: '',
start: 0,
amount: 10,
total: 0,
remaining: 0,
watch_pos: 0,
get: function() {
return {
id: () => {
if (this.id.indexOf('#') !== -1) {
return this.id
}
return '#' + this.id
},
more: (start, amount) => {
if (this.total > 0 && this.remaining <= 0) {
return
}
$.ajax({
url: '{{$urls->base}}/log/{{urlencode($log->getFilename())}}/more/' + start + '/' + amount
}).then(response => {
if (response.logs) {
if (this.total === 0) {
this.remaining = this.total = response.total
}
this.remaining -= response.logs.length
this.start += response.logs.length
console.debug(this.total, this.remaining)
this.draw().more(response.logs)
}
})
}
}
},
draw: function() {
return {
more: logs => {
const parent = $(this.get().id())
logs.forEach(log => {
if (log.parsed) {
this.draw().parsed(parent, log)
return;
}
this.draw().unparsed(parent, log)
})
},
unparsed: (parent, log) => {
const title = $('<div></div>').addClass('title')
.append($('<i></i>').addClass('dropdown icon'))
const content = $('<div></div>').addClass('content')
title.append(log.original)
content.html(log.original)
parent.append(title).append(content)
},
parsed: (parent, log) => {
const title = $('<div></div>').addClass('title')
.append($('<i></i>').addClass('dropdown icon'))
const content = $('<div></div>').addClass('content')
title.append(
$('<span></span>')
.addClass(log.severity.toLowerCase()).css('padding-left', '1ex').css('padding-right', '1ex')
.html('[' + log.date + '] ' + log.severity)
)
const card = $('<div></div>').addClass('ui fluid basic card').append(
$('<div></div>').addClass('content').append(
$('<div></div>').addClass('header').append(
$('<span></span>').addClass(log.severity.toLowerCase()).css('padding', '1ex 1em').append(
$('<i></i>').addClass('bug icon')
).append(
((log.channel === '') ? '' : log.channel + '.') + log.severity
)
)
)
).append(
$('<div></div>').addClass('content').append(
$('<div></div>').addClass('description').html(log.message)
)
)
if (log.stack.length > 0) {
const feed = $('<div></div>').addClass('ui small feed')
log.stack.forEach(stack => {
feed.append(
$('<div></div>').addClass('event').append(
$('<div></div>').addClass('content').html(stack)
)
)
})
card.append(
$('<div></div>').addClass('content').append(feed)
)
}
if (log.context !== '') {
card.append(
$('<div></div>').addClass('extra content').append(
log.context
).append(
$('<div></div>').addClass('meta').html(log.extra)
)
)
}
content.append(card)
parent.append(title).append(content)
}
}
},
watch: function() {
return {
more: payload => {
if (payload[0].isIntersecting) {
if (payload[0].rootBounds.bottom !== this.watch_pos) {
this.get().more(this.start, this.amount)
}
}
}
}
},
setup: function(id) {
this.id = id
$(this.get().id()).accordion()
const ob = new IntersectionObserver(this.watch().more)
const watch = document.querySelector('#watch')
ob.observe(watch)
}
}
$(document).ready(() => {
logs.setup('logs')
})
</script>
@endpush