Start work on showing the logs in the administrator panel

pull/9666/head
Bradley Hilton 8 years ago
parent 76b05748aa
commit aec714b56e
No known key found for this signature in database
GPG Key ID: 0666B2C24C43C358
  1. 17
      packages/rocketchat-api/package.js
  2. 8
      packages/rocketchat-api/server/api.js
  3. 12
      packages/rocketchat-api/server/default/helpers/getLoggedInUser.js
  4. 2
      packages/rocketchat-api/server/helpers/getLoggedInUser.js
  5. 2
      packages/rocketchat-api/server/helpers/getPaginationItems.js
  6. 2
      packages/rocketchat-api/server/helpers/getUserFromParams.js
  7. 2
      packages/rocketchat-api/server/helpers/isUserFromParams.js
  8. 2
      packages/rocketchat-api/server/helpers/parseJsonQuery.js
  9. 2
      packages/rocketchat-api/server/helpers/requestParams.js
  10. 39
      packages/rocketchat-apps/client/admin/appLogs.html
  11. 58
      packages/rocketchat-apps/client/admin/appLogs.js
  12. 1
      packages/rocketchat-apps/client/admin/appManage.html
  13. 4
      packages/rocketchat-apps/client/admin/appManage.js
  14. 7
      packages/rocketchat-apps/client/orchestrator.js
  15. 4
      packages/rocketchat-apps/package.js
  16. 30
      packages/rocketchat-apps/server/communication/rest.js
  17. 2
      packages/rocketchat-apps/server/orchestrator.js
  18. 14
      packages/rocketchat-apps/server/storage/logs-storage.js

@ -15,16 +15,13 @@ Package.onUse(function(api) {
api.addFiles('server/api.js', 'server');
api.addFiles('server/settings.js', 'server');
//Register v1 helpers
api.addFiles('server/v1/helpers/requestParams.js', 'server');
api.addFiles('server/v1/helpers/getPaginationItems.js', 'server');
api.addFiles('server/v1/helpers/getUserFromParams.js', 'server');
api.addFiles('server/v1/helpers/isUserFromParams.js', 'server');
api.addFiles('server/v1/helpers/parseJsonQuery.js', 'server');
api.addFiles('server/v1/helpers/getLoggedInUser.js', 'server');
//Register default helpers
api.addFiles('server/default/helpers/getLoggedInUser.js', 'server');
//Register helpers
api.addFiles('server/helpers/requestParams.js', 'server');
api.addFiles('server/helpers/getPaginationItems.js', 'server');
api.addFiles('server/helpers/getUserFromParams.js', 'server');
api.addFiles('server/helpers/isUserFromParams.js', 'server');
api.addFiles('server/helpers/parseJsonQuery.js', 'server');
api.addFiles('server/helpers/getLoggedInUser.js', 'server');
//Add default routes
api.addFiles('server/default/info.js', 'server');

@ -6,7 +6,6 @@ class API extends Restivus {
super(properties);
this.logger = new Logger(`API ${ properties.version ? properties.version : 'default' } Logger`, {});
this.authMethods = [];
this.helperMethods = new Map();
this.fieldSeparator = '.';
this.defaultFieldsToExclude = {
joinCode: 0,
@ -120,7 +119,7 @@ class API extends Restivus {
routes.forEach((route) => {
//Note: This is required due to Restivus calling `addRoute` in the constructor of itself
if (this.helperMethods) {
if (RocketChat.API.helperMethods) {
Object.keys(endpoints).forEach((method) => {
if (typeof endpoints[method] === 'function') {
endpoints[method] = {action: endpoints[method]};
@ -128,7 +127,7 @@ class API extends Restivus {
//Add a try/catch for each endpoint
const originalAction = endpoints[method].action;
endpoints[method].action = function() {
endpoints[method].action = function _internalRouteActionHandler() {
this.logger.debug(`${ this.request.method.toUpperCase() }: ${ this.request.url }`);
let result;
try {
@ -154,7 +153,7 @@ class API extends Restivus {
return result;
};
for (const [name, helperMethod] of this.helperMethods) {
for (const [name, helperMethod] of RocketChat.API.helperMethods) {
endpoints[method][name] = helperMethod;
}
@ -371,6 +370,7 @@ const getUserAuth = function _getUserAuth() {
};
RocketChat.API = {
helperMethods: new Map(),
getUserAuth,
ApiClass: API
};

@ -1,12 +0,0 @@
RocketChat.API.default.helperMethods.set('getLoggedInUser', function _getLoggedInUser() {
let user;
if (this.request.headers['x-auth-token'] && this.request.headers['x-user-id']) {
user = RocketChat.models.Users.findOne({
'_id': this.request.headers['x-user-id'],
'services.resume.loginTokens.hashedToken': Accounts._hashLoginToken(this.request.headers['x-auth-token'])
});
}
return user;
});

@ -1,4 +1,4 @@
RocketChat.API.v1.helperMethods.set('getLoggedInUser', function _getLoggedInUser() {
RocketChat.API.helperMethods.set('getLoggedInUser', function _getLoggedInUser() {
let user;
if (this.request.headers['x-auth-token'] && this.request.headers['x-user-id']) {

@ -2,7 +2,7 @@
// If the count query param isn't defined, then we set it to the "API_Default_Count" setting
// If the count is zero, then that means unlimited and is only allowed if the setting "API_Allow_Infinite_Count" is true
RocketChat.API.v1.helperMethods.set('getPaginationItems', function _getPaginationItems() {
RocketChat.API.helperMethods.set('getPaginationItems', function _getPaginationItems() {
const hardUpperLimit = RocketChat.settings.get('API_Upper_Count_Limit') <= 0 ? 100 : RocketChat.settings.get('API_Upper_Count_Limit');
const defaultCount = RocketChat.settings.get('API_Default_Count') <= 0 ? 50 : RocketChat.settings.get('API_Default_Count');
const offset = this.queryParams.offset ? parseInt(this.queryParams.offset) : 0;

@ -1,5 +1,5 @@
//Convenience method, almost need to turn it into a middleware of sorts
RocketChat.API.v1.helperMethods.set('getUserFromParams', function _getUserFromParams() {
RocketChat.API.helperMethods.set('getUserFromParams', function _getUserFromParams() {
const doesntExist = { _doesntExist: true };
let user;
const params = this.requestParams();

@ -1,4 +1,4 @@
RocketChat.API.v1.helperMethods.set('isUserFromParams', function _isUserFromParams() {
RocketChat.API.helperMethods.set('isUserFromParams', function _isUserFromParams() {
const params = this.requestParams();
return (!params.userId && !params.username && !params.user) ||

@ -1,4 +1,4 @@
RocketChat.API.v1.helperMethods.set('parseJsonQuery', function _parseJsonQuery() {
RocketChat.API.helperMethods.set('parseJsonQuery', function _parseJsonQuery() {
let sort;
if (this.queryParams.sort) {
try {

@ -1,3 +1,3 @@
RocketChat.API.v1.helperMethods.set('requestParams', function _requestParams() {
RocketChat.API.helperMethods.set('requestParams', function _requestParams() {
return ['POST', 'PUT'].includes(this.request.method) ? this.bodyParams : this.queryParams;
});

@ -0,0 +1,39 @@
<template name="appLogs">
{{#with app}}
<section class="page-container page-list page-settings flex-tab-main-content">
<header class="fixed-title">
{{> burger}}
<a href="{{pathFor "app-manage" appId=id}}" title="{{_ "Back_to_Manage_Apps"}}">
<i class="icon-left-open"></i>
</a> &nbsp;
<h2>
<span class="room-title">{{_ "View_the_Logs_for"}}: "{{name}}"</span>
</h2>
</header>
<div class="content background-transparent-dark">
{{#if isReady}}
<div class="rocket-form">
{{#each logs}}
<div class="section section-collapsed">
<div class="section-title">
<div class="section-title-text">
Logs for "{{method}}" ({{entries.length}}) {{totalTime}}ms
</div>
<div class="section-title-right">
<button class="button primary expand">
<span>{{_ "Expand"}}</span>
</button>
</div>
</div>
<div class="section-content">
Content
</div>
</div>
{{/each}}
</div>
{{/if}}
</div>
</section>
{{/with}}
</template>

@ -0,0 +1,58 @@
Template.appLogs.onCreated(function() {
const instance = this;
this.id = new ReactiveVar(FlowRouter.getParam('appId'));
this.ready = new ReactiveVar(false);
this.app = new ReactiveVar({});
this.logs = new ReactiveVar([]);
const id = this.id.get();
const got = { info: false, logs: false };
RocketChat.API.get(`apps/${ id }`).then((result) => {
instance.app.set(result.app);
got.info = true;
if (got.info && got.logs) {
this.ready.set(true);
}
});
RocketChat.API.get(`apps/${ id }/logs`).then((result) => {
console.log('logs result:', result);
instance.logs.set(result.logs);
got.logs = true;
if (got.info && got.logs) {
this.ready.set(true);
}
});
});
Template.appLogs.helpers({
isReady() {
if (Template.instance().ready != null) {
return Template.instance().ready.get();
}
return false;
},
app() {
return Template.instance().app.get();
},
logs() {
return Template.instance().logs.get();
}
});
Template.appLogs.events({
'click .expand': (e) => {
$(e.currentTarget).closest('.section').removeClass('section-collapsed');
$(e.currentTarget).closest('button').removeClass('expand').addClass('collapse').find('span').text(TAPi18n.__('Collapse'));
},
'click .collapse': (e) => {
$(e.currentTarget).closest('.section').addClass('section-collapsed');
$(e.currentTarget).closest('button').addClass('expand').removeClass('collapse').find('span').text(TAPi18n.__('Expand'));
}
});

@ -12,6 +12,7 @@
</h2>
<div class="submit">
<button class="button logs">{{_ "Logs"}}</button>
<button class="button danger uninstall">{{_ "Uninstall"}}</button>
</div>
</header>

@ -124,6 +124,10 @@ Template.appManage.events({
});
},
'click .logs': (e, t) => {
FlowRouter.go(`/admin/apps/${ t.id.get() }/logs`);
},
'click .save': (e, t) => {
const toSave = [];

@ -74,3 +74,10 @@ FlowRouter.route('/admin/apps/:appId', {
BlazeLayout.render('main', { center: 'appManage' });
}
});
FlowRouter.route('/admin/apps/:appId/logs', {
name: 'app-logs',
action() {
BlazeLayout.render('main', { center: 'appLogs' });
}
});

@ -71,7 +71,9 @@ Package.onUse(function(api) {
'client/admin/appManage.html',
'client/admin/appManage.js',
'client/admin/appInstall.html',
'client/admin/appInstall.js'
'client/admin/appInstall.js',
'client/admin/appLogs.html',
'client/admin/appLogs.js'
], 'client');
api.addFiles('assets/stylesheets/apps.css', 'client');

@ -1,5 +1,6 @@
export class AppsRestApi {
constructor(manager) {
constructor(orch, manager) {
this._orch = orch;
this._manager = manager;
this.api = new RocketChat.API.ApiClass({
version: 'apps',
@ -35,6 +36,7 @@ export class AppsRestApi {
}
addManagementRoutes() {
const orchestrator = this._orch;
const manager = this._manager;
const fileHandler = this._handleFile;
@ -165,6 +167,32 @@ export class AppsRestApi {
}
});
this.api.addRoute(':id/logs', { authRequired: true }, {
get() {
console.log(`Getting ${ this.urlParams.id }'s logs..`);
const prl = manager.getOneById(this.urlParams.id);
if (prl) {
const { offset, count } = this.getPaginationItems();
const { sort, fields, query } = this.parseJsonQuery();
const ourQuery = Object.assign({}, query, { appId: prl.getID() });
const options = {
sort: sort ? sort : { _updatedAt: -1 },
skip: offset,
limit: count,
fields
};
const logs = Promise.await(orchestrator.getLogStorage().find(ourQuery, options));
return RocketChat.API.v1.success({ logs });
} else {
return RocketChat.API.v1.notFound(`No App found by the id of: ${ this.urlParams.id }`);
}
}
});
this.api.addRoute(':id/settings', { authRequired: true }, {
get() {
console.log(`Getting ${ this.urlParams.id }'s settings..`);

@ -30,7 +30,7 @@ class AppServerOrchestrator {
this._communicators = new Map();
this._communicators.set('methods', new AppMethods(this._manager));
this._communicators.set('notifier', new AppWebsocketNotifier());
this._communicators.set('restapi', new AppsRestApi(this._manager));
this._communicators.set('restapi', new AppsRestApi(this, this._manager));
}
getModel() {

@ -7,6 +7,20 @@ export class AppRealLogsStorage extends AppLogStorage {
this.db = model;
}
find() {
return new Promise((resolve, reject) => {
let docs;
try {
docs = this.db.find(...arguments).fetch();
} catch (e) {
return reject(e);
}
resolve(docs);
});
}
storeEntries(appId, logger) {
console.log(appId);
return new Promise((resolve, reject) => {

Loading…
Cancel
Save