Regression: Fix view logs admin screen (#23194)

pull/21176/head^2
Diego Sampaio 5 years ago committed by GitHub
parent d2f70b9e41
commit 1bac896c13
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      app/api/server/v1/misc.js
  2. 7
      app/logger/server/index.js
  3. 71
      app/logger/server/streamer.js
  4. 3
      server/lib/logger/getPino.ts
  5. 61
      server/lib/logger/logQueue.ts
  6. 7
      server/lib/logger/startup.ts
  7. 1
      server/main.js
  8. 41
      server/stream/stdout.ts
  9. 1
      typings.d.ts

@ -13,7 +13,7 @@ import { settings } from '../../../settings/server';
import { API } from '../api';
import { getDefaultUserFields } from '../../../utils/server/functions/getDefaultUserFields';
import { getURL } from '../../../utils/lib/getURL';
import { StdOut } from '../../../logger/server/streamer';
import { getLogs } from '../../../../server/stream/stdout';
import { SystemLogger } from '../../../../server/lib/logger/system';
API.v1.addRoute('me', { authRequired: true }, {
@ -195,7 +195,7 @@ API.v1.addRoute('stdout.queue', { authRequired: true }, {
if (!hasPermission(this.userId, 'view-logs')) {
return API.v1.unauthorized();
}
return API.v1.success({ queue: StdOut.queue });
return API.v1.success({ queue: getLogs() });
},
});

@ -1,7 +1,2 @@
import { Logger } from '../../../server/lib/logger/Logger';
import './streamer';
// TODO there are imports pointing to this file still, ideally we should point everything to "/server/lib/logger/Logger" and remove this file
export {
Logger,
};
export { Logger } from '../../../server/lib/logger/Logger';

@ -1,71 +0,0 @@
import { EventEmitter } from 'events';
import { Meteor } from 'meteor/meteor';
import { EJSON } from 'meteor/ejson';
import { Log } from 'meteor/logging';
import { settings } from '../../settings/server';
import notifications from '../../notifications/server/lib/Notifications';
const processString = function(string, date) {
let obj;
try {
if (string[0] === '{') {
obj = EJSON.parse(string);
} else {
obj = {
message: string,
time: date,
level: 'info',
};
}
return Log.format(obj, { color: true });
} catch (error) {
return string;
}
};
export const StdOut = Object.assign(new EventEmitter(), {
queue: [],
});
const { write } = process.stdout;
const maxInt = 2147483647;
let queueSize = 0;
process.stdout.write = (...args) => {
write.apply(process.stdout, args);
const date = new Date();
const string = processString(args[0], date);
const item = {
id: `logid-${ queueSize }`,
string,
ts: date,
};
StdOut.queue.push(item);
queueSize = (queueSize + 1) & maxInt;
const limit = settings.get('Log_View_Limit') || 1000;
if (queueSize > limit) {
StdOut.queue.shift();
}
StdOut.emit('write', string, item);
};
Meteor.startup(() => {
const handler = (string, item) => {
// TODO having this as 'emitWithoutBroadcast' will not sent this data to ddp-streamer, so this data
// won't be available when using micro services.
notifications.streamStdout.emitWithoutBroadcast('stdout', {
...item,
});
};
// do not emit to StdOut if moleculer log level set to debug because it creates an infinite loop
if (String(process.env.MOLECULER_LOG_LEVEL).toLowerCase() !== 'debug') {
StdOut.on('write', handler);
}
});

@ -1,6 +1,9 @@
import { pino } from 'pino';
import type { P } from 'pino';
// make sure log queue is set up, so pino uses the overwritten process.stdout.write
import './logQueue';
// add support to multiple params on the log commands, i.e.:
// logger.info('user', Meteor.user()); // will print: {"level":30,"time":1629814080968,"msg":"user {\"username\": \"foo\"}"}
function logMethod(this: P.Logger, args: unknown[], method: any): void {

@ -0,0 +1,61 @@
import EventEmitter from 'events';
type LogQueue = {
id: string;
data: string;
ts: Date;
};
const queue: LogQueue[] = [];
const maxInt = 2147483647;
let queueLimit = 1000;
let queueSize = 0;
export function setQueueLimit(limit: number): void {
queueLimit = limit;
if (queueSize > queueLimit) {
queue.splice(0, queueSize - queueLimit);
}
}
export function getQueuedLogs(): LogQueue[] {
return queue;
}
export const logEntries = new EventEmitter();
const { write } = process.stdout;
function queueWrite(buffer: Uint8Array | string, cb?: (err?: Error) => void): boolean;
function queueWrite(str: Uint8Array | string, encoding?: string, cb?: (err?: Error) => void): boolean;
function queueWrite(...args: any): boolean {
write.apply(process.stdout, args);
const [str] = args;
if (typeof str !== 'string') {
return false;
}
const date = new Date();
const item = {
id: `logid-${ queueSize }`,
data: str,
ts: date,
};
queue.push(item);
queueSize = (queueSize + 1) & maxInt;
if (queueSize > queueLimit) {
queue.shift();
}
logEntries.emit('log', item);
return true;
}
if (String(process.env.MOLECULER_LOG_LEVEL).toLowerCase() !== 'debug') {
process.stdout.write = queueWrite;
}

@ -1,8 +1,15 @@
import { settings } from '../../../app/settings/server';
import { logLevel, LogLevelSetting } from './logLevel';
import { setQueueLimit } from './logQueue';
settings.get('Log_Level', (_key, value) => {
if (value != null) {
logLevel.emit('changed', String(value) as LogLevelSetting);
}
});
settings.get('Log_View_Limit', (_key, value) => {
if (typeof value === 'number') {
setQueueLimit(value);
}
});

@ -76,6 +76,7 @@ import './publications/settings';
import './publications/spotlight';
import './publications/subscription';
import './routes/avatar';
import './stream/stdout';
import './stream/streamBroadcast';
import './features/EmailInbox/index';

@ -0,0 +1,41 @@
import { EJSON } from 'meteor/ejson';
import { Log } from 'meteor/logging';
import notifications from '../../app/notifications/server/lib/Notifications';
import { getQueuedLogs, logEntries } from '../lib/logger/logQueue';
const processString = function(string: string, date: Date): string {
let obj;
try {
if (string[0] === '{') {
obj = EJSON.parse(string);
} else {
obj = {
message: string,
time: date,
level: 'info',
};
}
return Log.format(obj, { color: true });
} catch (error) {
return string;
}
};
const transformLog = function(item: any): { id: string; string: string; ts: Date } {
return {
id: item.id,
string: processString(item.data, item.ts),
ts: item.ts,
};
};
logEntries.on('log', (item) => {
// TODO having this as 'emitWithoutBroadcast' will not sent this data to ddp-streamer, so this data
// won't be available when using micro services.
notifications.streamStdout.emitWithoutBroadcast('stdout', transformLog(item));
});
export function getLogs(): { id: string; string: string; ts: Date }[] {
return getQueuedLogs().map(transformLog);
}

1
typings.d.ts vendored

@ -3,6 +3,7 @@ declare module 'meteor/littledata:synced-cron';
declare module 'meteor/promise';
declare module 'meteor/ddp-common';
declare module 'meteor/routepolicy';
declare module 'meteor/logging';
declare module 'xml-encryption';
declare module 'webdav';

Loading…
Cancel
Save