Skip to content

Commit

Permalink
feat(core): improve logging - add namespaces, colors and highlighting
Browse files Browse the repository at this point in the history
Logger now defaults to `console.log()`, and users can specify what namespaces are they interested in via `debug` option. `true/false` will enable/disable all namespaces.

Closes #108
  • Loading branch information
B4nan committed Sep 6, 2019
1 parent 46ae83a commit a998768
Show file tree
Hide file tree
Showing 28 changed files with 331 additions and 229 deletions.
4 changes: 3 additions & 1 deletion lib/MikroORM.ts
@@ -1,3 +1,5 @@
import chalk from 'chalk';

import { EntityManager } from './EntityManager';
import { AbstractSqlDriver, IDatabaseDriver } from './drivers';
import { MetadataDiscovery, MetadataStorage } from './metadata';
Expand Down Expand Up @@ -47,7 +49,7 @@ export class MikroORM {
await connection.connect();
const clientUrl = connection.getClientUrl();
const dbName = this.config.get('dbName');
this.logger.info(`MikroORM: successfully connected to database ${dbName}${clientUrl ? ' on ' + clientUrl : ''}`);
this.logger.log('info', `MikroORM successfully connected to database ${chalk.green(dbName)}${clientUrl ? ' on ' + chalk.green(clientUrl) : ''}`);

return this.driver;
}
Expand Down
37 changes: 13 additions & 24 deletions lib/cli/CLIHelper.ts
@@ -1,13 +1,12 @@
import yargs, { Argv } from 'yargs';
import { pathExists } from 'fs-extra';
import highlight from 'cli-highlight';

import { MikroORM } from '../MikroORM';
import { Configuration, Utils } from '../utils';
import { ClearCacheCommand } from './ClearCacheCommand';
import { GenerateEntitiesCommand } from './GenerateEntitiesCommand';
import { CreateSchemaCommand } from './CreateSchemaCommand';
import { UpdateSchemaCommand } from './UpdateSchemaCommand';
import { DropSchemaCommand } from './DropSchemaCommand';
import { SchemaCommandFactory } from './SchemaCommandFactory';

export class CLIHelper {

Expand All @@ -28,6 +27,7 @@ export class CLIHelper {
static async getORM(): Promise<MikroORM> {
const options = await CLIHelper.getConfiguration();
const settings = await CLIHelper.getSettings();
options.getLogger().setDebugMode(false);

if (settings.useTsNode) {
options.set('tsNode', true);
Expand All @@ -52,9 +52,9 @@ export class CLIHelper {
.alias('h', 'help')
.command(new ClearCacheCommand())
.command(new GenerateEntitiesCommand())
.command(new CreateSchemaCommand())
.command(new DropSchemaCommand())
.command(new UpdateSchemaCommand())
.command(SchemaCommandFactory.create('create'))
.command(SchemaCommandFactory.create('drop'))
.command(SchemaCommandFactory.create('update'))
.recommendCommands()
.strict();
}
Expand All @@ -68,24 +68,13 @@ export class CLIHelper {
return {};
}

static configureSchemaCommand(args: Argv) {
args.option('r', {
alias: 'run',
type: 'boolean',
desc: 'Runs queries',
});
args.option('d', {
alias: 'dump',
type: 'boolean',
desc: 'Dumps all queries to console',
});
args.option('no-fk', {
type: 'boolean',
desc: 'Disable foreign key checks if possible',
default: true,
});

return args;
static dump(text: string, config?: Configuration, language?: string): void {
if (config && language && config.get('highlight')) {
text = highlight(text, { language, ignoreIllegals: true, theme: config.getHighlightTheme() });
}

// tslint:disable-next-line:no-console
console.log(text);
}

private static async getConfigPaths(): Promise<string[]> {
Expand Down
3 changes: 1 addition & 2 deletions lib/cli/ClearCacheCommand.ts
Expand Up @@ -12,8 +12,7 @@ export class ClearCacheCommand implements CommandModule {
const cache = config.getCacheAdapter();
await cache.clear();

// tslint:disable-next-line:no-console
console.log(chalk.green('Metadata cache was successfully cleared') + '\n');
CLIHelper.dump(chalk.green('Metadata cache was successfully cleared'));
}

}
38 changes: 0 additions & 38 deletions lib/cli/CreateSchemaCommand.ts

This file was deleted.

38 changes: 0 additions & 38 deletions lib/cli/DropSchemaCommand.ts

This file was deleted.

2 changes: 1 addition & 1 deletion lib/cli/GenerateEntitiesCommand.ts
Expand Up @@ -39,7 +39,7 @@ export class GenerateEntitiesCommand<U extends Options = Options> implements Com
const dump = await generator.generate({ save: args.save, baseDir: args.path });

if (args.dump) {
process.stdout.write(dump.join('\n\n'));
CLIHelper.dump(dump.join('\n\n'), orm.config, 'typescript');
}

await orm.close(true);
Expand Down
74 changes: 74 additions & 0 deletions lib/cli/SchemaCommandFactory.ts
@@ -0,0 +1,74 @@
import yargs, { Arguments, Argv, CommandModule } from 'yargs';
import chalk from 'chalk';
import { CLIHelper } from './CLIHelper';

export type Options = { dump: boolean; run: boolean; noFk: boolean };

export class SchemaCommandFactory {

static readonly DESCRIPTIONS = {
create: 'Create database schema based on current metadata',
update: 'Update database schema based on current metadata',
drop: 'Drop database schema based on current metadata',
};

static readonly SUCCESS_MESSAGES = {
create: 'Schema successfully created',
update: 'Schema successfully updated',
drop: 'Schema successfully dropped',
};

static create<U extends Options = Options>(command: 'create' | 'update' | 'drop'): CommandModule<{}, U> & { builder: (args: Argv) => Argv<U>; handler: (args: Arguments<U>) => Promise<void> } {
const successMessage = SchemaCommandFactory.SUCCESS_MESSAGES[command];

return {
command: `schema:${command}`,
describe: SchemaCommandFactory.DESCRIPTIONS[command],
builder: (args: Argv) => SchemaCommandFactory.configureSchemaCommand(args) as Argv<U>,
handler: (args: Arguments<U>) => SchemaCommandFactory.handleSchemaCommand(args, command, successMessage),
};
}

static configureSchemaCommand(args: Argv) {
args.option('r', {
alias: 'run',
type: 'boolean',
desc: 'Runs queries',
});
args.option('d', {
alias: 'dump',
type: 'boolean',
desc: 'Dumps all queries to console',
});
args.option('no-fk', {
type: 'boolean',
desc: 'Disable foreign key checks if possible',
default: true,
});

return args;
}

static async handleSchemaCommand(args: Arguments<{ dump: boolean; run: boolean; noFk: boolean }>, method: 'create' | 'update' | 'drop', successMessage: string) {
if (!args.run && !args.dump) {
yargs.showHelp();
return;
}

const orm = await CLIHelper.getORM();
const generator = orm.getSchemaGenerator();

if (args.dump) {
const m = `get${method.substr(0, 1).toUpperCase()}${method.substr(1)}SchemaSQL`;
const dump = await generator[m](args.noFk);
CLIHelper.dump(dump, orm.config, 'sql');
} else {
const m = method + 'Schema';
await generator[m](args.noFk);
CLIHelper.dump(chalk.green(successMessage));
}

await orm.close(true);
}

}
38 changes: 0 additions & 38 deletions lib/cli/UpdateSchemaCommand.ts

This file was deleted.

4 changes: 4 additions & 0 deletions lib/connections/AbstractSqlConnection.ts
Expand Up @@ -55,6 +55,10 @@ export abstract class AbstractSqlConnection extends Connection {
await this.client.raw(buf.toString());
}

protected logQuery(query: string, took?: number): void {
super.logQuery(query, took, 'sql');
}

protected createKnexClient(type: string): Knex {
return Knex(this.getKnexOptions(type))
.on('query', data => {
Expand Down
12 changes: 10 additions & 2 deletions lib/connections/Connection.ts
@@ -1,5 +1,8 @@
import { URL } from 'url';
import { Transaction as KnexTransaction } from 'knex';
import chalk from 'chalk';
import highlight from 'cli-highlight';

import { Configuration, Utils } from '../utils';
import { MetadataStorage } from '../metadata';

Expand Down Expand Up @@ -68,8 +71,13 @@ export abstract class Connection {
return res;
}

protected logQuery(query: string, took?: number): void {
this.logger.debug(`[query-logger] ${query}` + (Utils.isDefined(took) ? ` [took ${took} ms]` : ''));
protected logQuery(query: string, took?: number, language?: string): void {
if (this.config.get('highlight') && language) {
query = highlight(query, { language, ignoreIllegals: true, theme: this.config.getHighlightTheme() });
}

const msg = `${query}` + (Utils.isDefined(took) ? chalk.grey(` [took ${took} ms]`) : '');
this.config.getLogger().log('query', msg);
}

}
Expand Down
4 changes: 4 additions & 0 deletions lib/connections/MongoConnection.ts
Expand Up @@ -149,6 +149,10 @@ export class MongoConnection extends Connection {
return res;
}

protected logQuery(query: string, took?: number): void {
super.logQuery(query, took, 'javascript');
}

private convertObjectIds(payload: any): any {
if (payload instanceof ObjectId) {
return payload;
Expand Down

0 comments on commit a998768

Please sign in to comment.