Files
logview/app/resources/views/logs/show.blade.php
2023-05-19 12:46:24 -04:00

238 lines
9.4 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;}
</style>
@endpush
@push('page_scripts')
<script type="text/javascript">
const colors = {
debug: {
color: '#000',
background: '#fff'
},
info: {
color: '#fff',
background: '#2727e8'
},
notice: {
color: '#fff',
background: '#55f'
},
warning: {
color: '#000',
background: '#f5f580'
},
error: {
color: '#fff',
background: '#464646'
},
critical: {
color: '#fff',
background: '#cb0000'
},
alert: {
color: '#fff',
background: '#ec6060'
},
emergency: {
color: '#fff',
background: '#b95757'
},
deprecated: {
color: '#fff',
background: '#ce4000'
}
}
const icons = {
debug: 'bug',
info: 'search',
notice: 'exclamation',
warning: 'exclamation triangle',
error: 'times',
critical: 'bug',
alert: 'bell',
emergency: 'ambulance',
deprecated: 'virus slash'
}
const logs = {
id: '',
start: 0,
amount: {{$max_log_amount}},
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
}
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
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)
})
this.draw().markLast(parent)
},
title: () => {
return $('<div></div>').addClass('title')
.append($('<i></i>').addClass('dropdown icon'))
},
unparsed: (parent, log) => {
const title = this.draw().title()
const content = $('<div></div>').addClass('content')
content.addClass(log.severity.toLowerCase())
title.append(log.original)
content.html(log.original)
parent.append(title).append(content)
},
parsed: (parent, log) => {
const title = this.draw().title()
const content = $('<div></div>').addClass('content')
content.addClass(log.severity.toLowerCase())
title.append(
$('<span></span>')
.addClass(log.severity.toLowerCase()).css('padding', '.5ex 1ex')//.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(icons[(log.severity.toLowerCase())] + ' 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)
},
markLast: parent => {
const children = parent.children('.title')
children.removeClass('watch')
$(children[children.length - 1]).addClass('watch')
}
}
},
watch: function() {
return {
rewatch: observer => {
const watch = document.querySelector('.watch')
observer.observe(watch)
},
more: (entries, observer) => {
entries.forEach(payload => {
if (!$(payload.target).hasClass('watch')) {
return
}
if (payload.intersectionRatio > 0) {
if (payload.rootBounds.bottom !== this.watch_pos) {
try {
this.get().more(this.start, this.amount).then(response => {
this.watch().rewatch(observer)
})
} catch (e) {
observer.disconnect()
}
}
}
})
}
}
},
setup: function(id) {
this.id = id
$(this.get().id()).accordion()
this.get().more(this.start, this.amount).then(response => {
const ob = new IntersectionObserver(this.watch().more)
this.watch().rewatch(ob)
})
}
}
function buildColors() {
const styleDOM = document.createElement('style')
const styles = []
Object.keys(colors).forEach(level => {
styles.push('.' + level + ' {color: ' + colors[level].color + '; background-color: ' + colors[level].background + '}')
})
styleDOM.innerHTML = styles.join("\n")
document.getElementsByTagName('head')[0].appendChild(styleDOM)
}
$(document).ready(() => {
buildColors()
logs.setup('logs')
})
</script>
@endpush