9 changed files with 182 additions and 6 deletions
@ -0,0 +1,57 @@ |
|||||
|
// admin/log.js
|
||||
|
// Copyright (C) 2021 Digital Telepresence, LLC
|
||||
|
// License: Apache-2.0
|
||||
|
|
||||
|
'use strict'; |
||||
|
|
||||
|
const DTP_COMPONENT_NAME = 'admin:log'; |
||||
|
const express = require('express'); |
||||
|
|
||||
|
const { SiteController } = require('../../../lib/site-lib'); |
||||
|
|
||||
|
class LogController extends SiteController { |
||||
|
|
||||
|
constructor (dtp) { |
||||
|
super(dtp, DTP_COMPONENT_NAME); |
||||
|
} |
||||
|
|
||||
|
async start ( ) { |
||||
|
const router = express.Router(); |
||||
|
router.use(async (req, res, next) => { |
||||
|
res.locals.currentView = 'admin'; |
||||
|
res.locals.adminView = 'log'; |
||||
|
return next(); |
||||
|
}); |
||||
|
|
||||
|
router.get('/', this.getIndex.bind(this)); |
||||
|
|
||||
|
return router; |
||||
|
} |
||||
|
|
||||
|
async getIndex (req, res, next) { |
||||
|
const { log: logService } = this.dtp.services; |
||||
|
try { |
||||
|
res.locals.query = req.query; |
||||
|
|
||||
|
res.locals.components = await logService.getComponentNames(); |
||||
|
res.locals.pagination = this.getPaginationParameters(req, 25); |
||||
|
|
||||
|
const search = { }; |
||||
|
if (req.query.component) { |
||||
|
search.componentName = req.query.component; |
||||
|
} |
||||
|
res.locals.logs = await logService.getRecords(search, res.locals.pagination); |
||||
|
|
||||
|
res.locals.totalLogCount = await logService.getTotalCount(); |
||||
|
|
||||
|
res.render('admin/log/index'); |
||||
|
} catch (error) { |
||||
|
return next(error); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
module.exports = async (dtp) => { |
||||
|
let controller = new LogController(dtp); |
||||
|
return controller; |
||||
|
}; |
@ -0,0 +1,17 @@ |
|||||
|
// link-category.js
|
||||
|
// Copyright (C) 2021 Digital Telepresence, LLC
|
||||
|
// License: Apache-2.0
|
||||
|
|
||||
|
'use strict'; |
||||
|
|
||||
|
const mongoose = require('mongoose'); |
||||
|
|
||||
|
const Schema = mongoose.Schema; |
||||
|
|
||||
|
const LinkCategorySchema = new Schema({ |
||||
|
user: { type: Schema.ObjectId, required: true, index: 1, ref: 'User' }, |
||||
|
name: { type: String, required: true }, |
||||
|
order: { type: Number, default: 0, required: true }, |
||||
|
}); |
||||
|
|
||||
|
module.exports = mongoose.model('LinkCategory', LinkCategorySchema); |
@ -0,0 +1,44 @@ |
|||||
|
// log.js
|
||||
|
// Copyright (C) 2021 Digital Telepresence, LLC
|
||||
|
// License: Apache-2.0
|
||||
|
|
||||
|
'use strict'; |
||||
|
|
||||
|
const mongoose = require('mongoose'); |
||||
|
|
||||
|
const Log = mongoose.model('Log'); |
||||
|
|
||||
|
const { SiteService } = require('../../lib/site-lib'); |
||||
|
|
||||
|
class SystemLogService extends SiteService { |
||||
|
|
||||
|
constructor (dtp) { |
||||
|
super(dtp, module.exports); |
||||
|
} |
||||
|
|
||||
|
async getRecords (search, pagination) { |
||||
|
const logs = await Log |
||||
|
.find(search) |
||||
|
.sort({ created: -1 }) |
||||
|
.skip(pagination.skip) |
||||
|
.limit(pagination.cpp) |
||||
|
.lean(); |
||||
|
return logs; |
||||
|
} |
||||
|
|
||||
|
async getComponentNames ( ) { |
||||
|
return await Log.distinct('componentName'); |
||||
|
} |
||||
|
|
||||
|
async getTotalCount ( ) { |
||||
|
const count = await Log.estimatedDocumentCount(); |
||||
|
this.log.debug('log message total count', { count }); |
||||
|
return count; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
module.exports = { |
||||
|
slug: 'log', |
||||
|
name: 'log', |
||||
|
create: (dtp) => { return new SystemLogService(dtp); }, |
||||
|
}; |
@ -0,0 +1,46 @@ |
|||||
|
extends ../layouts/main |
||||
|
block content |
||||
|
|
||||
|
include ../../components/pagination-bar |
||||
|
|
||||
|
.uk-margin |
||||
|
form(method="GET", action="/admin/log").uk-form |
||||
|
div(uk-grid).uk-grid-small.uk-flex-middle |
||||
|
.uk-width-expand |
||||
|
h1 Log #[span.uk-text-small.uk-text-muted #{numeral(totalLogCount).format('0,0')} records] |
||||
|
|
||||
|
.uk-width-auto |
||||
|
- |
||||
|
var urlParams = ''; |
||||
|
if (query.component) { |
||||
|
urlParams += `&component=${query.component}`; |
||||
|
} |
||||
|
+renderPaginationBar(`/admin/log`, totalLogCount, urlParams) |
||||
|
|
||||
|
.uk-width-auto |
||||
|
select(id="component", name="component").uk-select |
||||
|
each componentName in components |
||||
|
option(value= componentName, selected= (query.component === componentName))= componentName |
||||
|
.uk-width-auto |
||||
|
button(type="submit").uk-button.dtp-button-primary Filter |
||||
|
|
||||
|
if Array.isArray(logs) && (logs.length > 0) |
||||
|
table.uk-table.uk-table-small.uk-table-divider |
||||
|
thead |
||||
|
tr |
||||
|
th Timestamp |
||||
|
th Level |
||||
|
th Component |
||||
|
th Message |
||||
|
tbody |
||||
|
each log in logs |
||||
|
tr |
||||
|
td= moment(log.created).format('YYYY-MM-DD hh:mm:ss.SSS') |
||||
|
td= log.level |
||||
|
td= log.componentName |
||||
|
td |
||||
|
div= log.message |
||||
|
if log.metadata |
||||
|
.uk-text-small(style="font-family: Courier New;")!= hljs.highlightAuto(JSON.stringify(log.metadata, null, 1)).value |
||||
|
else |
||||
|
div There are no logs. |
Loading…
Reference in new issue