mirror of https://github.com/nocodb/nocodb
Pranav C
3 years ago
5 changed files with 142 additions and 20 deletions
@ -0,0 +1,115 @@
|
||||
import {XKnex} from "../../dataMapper"; |
||||
import {Request} from 'express'; |
||||
|
||||
export default class MetaAPILogger { |
||||
|
||||
static _instance: MetaAPILogger; |
||||
knex: XKnex; |
||||
|
||||
constructor() { |
||||
this.knex = XKnex({ |
||||
client: 'sqlite3', |
||||
connection: { |
||||
filename: 'noco_log.db' |
||||
}, |
||||
useNullAsDefault: true |
||||
}) |
||||
} |
||||
|
||||
async init() { |
||||
await this.knex.migrate.latest({ |
||||
migrationSource: new XcLoggerMigrationSource(), |
||||
tableName: 'xc_knex_migrations' |
||||
}); |
||||
} |
||||
|
||||
|
||||
static async mw(req, res, next) { |
||||
|
||||
if (process.env.NC_LOGGER) { |
||||
const oldWrite = res.write, |
||||
oldEnd = res.end; |
||||
|
||||
const chunks = []; |
||||
|
||||
res.write = function (chunk) { |
||||
chunks.push(chunk); |
||||
|
||||
// eslint-disable-next-line prefer-rest-params
|
||||
oldWrite.apply(res, arguments); |
||||
}; |
||||
|
||||
res.end = function (chunk) { |
||||
if (chunk) |
||||
chunks.push(chunk); |
||||
|
||||
const body = Buffer.concat(chunks).toString('utf8'); |
||||
|
||||
MetaAPILogger.log(req, body) |
||||
// eslint-disable-next-line prefer-rest-params
|
||||
oldEnd.apply(res, arguments); |
||||
}; |
||||
} |
||||
next(); |
||||
} |
||||
|
||||
private static async log(req: Request, res: any) { |
||||
if (!process.env.NC_LOGGER) { |
||||
return; |
||||
} |
||||
if (!this._instance) { |
||||
this._instance = new MetaAPILogger(); |
||||
await this._instance.init() |
||||
} |
||||
await this._instance.knex('nc_log').insert({ |
||||
path: req.url, |
||||
params: JSON.stringify(req.query), |
||||
body: JSON.stringify(req.body), |
||||
headers: JSON.stringify(req.headers), |
||||
method: req.method, |
||||
operation: req.body?.api, |
||||
response: typeof res === 'string' ? res : JSON.stringify(res) |
||||
}) |
||||
} |
||||
|
||||
|
||||
} |
||||
|
||||
class XcLoggerMigrationSource { |
||||
// Must return a Promise containing a list of migrations.
|
||||
// Migrations can be whatever you want, they will be passed as
|
||||
// arguments to getMigrationName and getMigration
|
||||
public getMigrations(): Promise<any> { |
||||
// In this example we are just returning migration names
|
||||
return Promise.resolve(['logger']) |
||||
} |
||||
|
||||
public getMigrationName(migration): string { |
||||
return migration; |
||||
} |
||||
|
||||
public getMigration(migration): any { |
||||
switch (migration) { |
||||
case 'logger': |
||||
return { |
||||
async up(knex: XKnex) { |
||||
await knex.schema.createTable('nc_log', table => { |
||||
table.increments(); |
||||
table.string('path'); |
||||
table.string('method'); |
||||
table.string('operation'); |
||||
table.string('params'); |
||||
table.text('headers'); |
||||
table.text('body'); |
||||
table.text('response'); |
||||
table.text('comments'); |
||||
table.timestamps(true, true); |
||||
}) |
||||
}, |
||||
async down(knex) { |
||||
await knex.schema.dropTable('nc_log') |
||||
} |
||||
}; |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue