Skip to content

Commit

Permalink
enhance(logging): ability to filter debug messages
Browse files Browse the repository at this point in the history
  • Loading branch information
ardatan committed Aug 25, 2021
1 parent c0ce8b4 commit 9eff8a3
Show file tree
Hide file tree
Showing 12 changed files with 111 additions and 35 deletions.
11 changes: 11 additions & 0 deletions .changeset/smooth-scissors-film.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
'@graphql-mesh/cli': minor
'@graphql-mesh/config': minor
'@graphql-mesh/neo4j': minor
'@graphql-mesh/postgraphile': minor
'@graphql-mesh/runtime': minor
'@graphql-mesh/types': minor
'@graphql-mesh/utils': minor
---

enhance(logging): ability to filter debug messages
4 changes: 3 additions & 1 deletion examples/openapi-subscriptions/.meshrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ sources:
source: ./openapi.yml
baseUrl: http://localhost:4001

documents:
- ./example-queries/**/*.graphql

serve:
port: 4000
handlers:
- path: /callback
pubsubTopic: http://localhost:4000/callback
exampleQuery: ./example-queries/**/*.graphql
2 changes: 1 addition & 1 deletion packages/cli/src/bin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ import { handleFatalError } from './handleFatalError';

graphqlMesh()
.then(() => {})
.catch(e => handleFatalError(e, new DefaultLogger('Mesh')));
.catch(e => handleFatalError(e, new DefaultLogger('🕸️')));
78 changes: 63 additions & 15 deletions packages/cli/src/commands/serve/serve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { MeshInstance } from '@graphql-mesh/runtime';
import { handleFatalError } from '../../handleFatalError';
import open from 'open';
import { useServer } from 'graphql-ws/lib/use/ws';
import { env } from 'process';
import { env, on as processOn } from 'process';
import { YamlConfig, Logger } from '@graphql-mesh/types';
import { Source } from '@graphql-tools/utils';
import { inspect } from 'util';
Expand All @@ -37,19 +37,15 @@ export interface ServeMeshOptions {
argsPort?: number;
}

const terminateEvents = ['SIGINT', 'SIGTERM'];

function registerTerminateHandler(callback: (eventName: string) => void) {
for (const eventName of terminateEvents) {
processOn(eventName, () => callback(eventName));
}
}

export async function serveMesh({ baseDir, argsPort, getBuiltMesh, logger, rawConfig, documents }: ServeMeshOptions) {
logger.info(`Generating Mesh schema...`);
let readyFlag = false;

const mesh$ = getBuiltMesh()
.then(mesh => {
readyFlag = true;
if (!fork) {
logger.info(`🕸️ => Serving GraphQL Mesh: ${serverUrl}`);
}
return mesh;
})
.catch(e => handleFatalError(e, logger));
const {
fork,
port: configPort,
Expand All @@ -71,10 +67,25 @@ export async function serveMesh({ baseDir, argsPort, getBuiltMesh, logger, rawCo
if (isMaster && fork) {
const forkNum = fork > 1 ? fork : cpus().length;
for (let i = 0; i < forkNum; i++) {
clusterFork();
const worker = clusterFork();
registerTerminateHandler(eventName => worker.kill(eventName));
}
logger.info(`Serving GraphQL Mesh: ${serverUrl} in ${forkNum} forks`);
} else {
logger.info(`Generating Mesh schema...`);
let readyFlag = false;
const mesh$ = getBuiltMesh()
.then(mesh => {
readyFlag = true;
logger.info(`Serving GraphQL Mesh: ${serverUrl}`);
registerTerminateHandler(eventName => {
const eventLogger = logger.child(`${eventName}💀`);
eventLogger.info(`Destroying GraphQL Mesh`);
mesh.destroy();
});
return mesh;
})
.catch(e => handleFatalError(e, logger));
const app = express();
app.set('trust proxy', 'loopback');
let httpServer: Server;
Expand All @@ -89,6 +100,18 @@ export async function serveMesh({ baseDir, argsPort, getBuiltMesh, logger, rawCo
httpServer = createHTTPServer(app);
}

registerTerminateHandler(eventName => {
const eventLogger = logger.child(`${eventName}💀`);
eventLogger.debug(`Stopping HTTP Server`);
httpServer.close(error => {
if (error) {
eventLogger.debug(`HTTP Server couldn't be stopped: ${error.message}`);
} else {
eventLogger.debug(`HTTP Server has been stopped`);
}
});
});

if (corsConfig) {
app.use(cors(corsConfig));
}
Expand All @@ -105,7 +128,19 @@ export async function serveMesh({ baseDir, argsPort, getBuiltMesh, logger, rawCo
server: httpServer,
});

useServer(
registerTerminateHandler(eventName => {
const eventLogger = logger.child(`${eventName}💀`);
eventLogger.debug(`Stopping WebSocket Server`);
wsServer.close(error => {
if (error) {
eventLogger.debug(`WebSocket Server couldn't be stopped: ${error.message}`);
} else {
eventLogger.debug(`WebSocket Server has been stopped`);
}
});
});

const { dispose: stopGraphQLWSServer } = useServer(
{
schema: () => mesh$.then(({ schema }) => schema),
execute: args =>
Expand All @@ -132,6 +167,19 @@ export async function serveMesh({ baseDir, argsPort, getBuiltMesh, logger, rawCo
wsServer
);

registerTerminateHandler(eventName => {
const eventLogger = logger.child(`${eventName}💀`);
eventLogger.debug(`Stopping GraphQL WS`);
Promise.resolve()
.then(() => stopGraphQLWSServer())
.then(() => {
eventLogger.debug(`GraphQL WS has been stopped`);
})
.catch(error => {
eventLogger.debug(`GraphQL WS couldn't be stopped: ${error.message}`);
});
});

const pubSubHandler: RequestHandler = (req, _res, next) => {
Promise.resolve().then(async () => {
const { pubsub } = await mesh$;
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/handleFatalError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { env, exit } from 'process';
import { inspect } from 'util';
import { DefaultLogger } from '@graphql-mesh/utils';

export function handleFatalError(e: Error, logger: Logger = new DefaultLogger('Mesh')): any {
export function handleFatalError(e: Error, logger: Logger = new DefaultLogger('🕸️')): any {
const errorText = e.message;
logger.error(errorText);
if (env.DEBUG) {
Expand Down
11 changes: 6 additions & 5 deletions packages/cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const SERVE_COMMAND_WARNING =

export async function graphqlMesh() {
let baseDir = cwd();
let logger = new DefaultLogger('Mesh');
let logger = new DefaultLogger('🕸️');
return yargs(hideBin(process.argv))
.help()
.option('r', {
Expand Down Expand Up @@ -79,11 +79,12 @@ export async function graphqlMesh() {
const meshConfig = await findAndParseConfig({
dir: baseDir,
});
logger = meshConfig.logger;
const serveMeshOptions: ServeMeshOptions = {
baseDir,
argsPort: args.port,
getBuiltMesh: () => getMesh(meshConfig),
logger: meshConfig.logger,
logger: meshConfig.logger.child('Server'),
rawConfig: meshConfig.config,
documents: meshConfig.documents,
};
Expand All @@ -98,8 +99,7 @@ export async function graphqlMesh() {
);
await customServerHandler(serveMeshOptions);
} else {
const result = await serveMesh(serveMeshOptions);
logger = result.logger;
await serveMesh(serveMeshOptions);
}
} catch (e) {
handleFatalError(e, logger);
Expand All @@ -126,12 +126,13 @@ export async function graphqlMesh() {
const mainModule = join(builtMeshArtifactsPath, 'index.js');
const builtMeshArtifacts = await import(mainModule).then(m => m.default || m);
const getMeshOptions: GetMeshOptions = await builtMeshArtifacts.getMeshOptions();
logger = getMeshOptions.logger;
const rawConfig: YamlConfig.Config = builtMeshArtifacts.rawConfig;
const serveMeshOptions: ServeMeshOptions = {
baseDir,
argsPort: args.port,
getBuiltMesh: () => getMesh(getMeshOptions),
logger: getMeshOptions.logger,
logger: getMeshOptions.logger.child('Server'),
rawConfig: builtMeshArtifacts.rawConfig,
documents: builtMeshArtifacts.documentsInSDL.map((documentSdl: string, i: number) => ({
rawSDL: documentSdl,
Expand Down
4 changes: 2 additions & 2 deletions packages/config/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,10 +190,10 @@ export async function resolveLogger(
code: '',
};
}
const logger = new DefaultLogger('Mesh');
const logger = new DefaultLogger('🕸️');
return {
logger,
importCode: `import { DefaultLogger } from '@graphql-mesh/utils';`,
code: `const logger = new DefaultLogger('Mesh');`,
code: `const logger = new DefaultLogger('🕸️');`,
};
}
12 changes: 11 additions & 1 deletion packages/handlers/neo4j/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,17 @@ export default class Neo4JHandler implements MeshHandler {
logger: (level, message) => this.logger[level](message),
},
});
this.pubsub.subscribe('destroy', () => this.driver.close());
this.pubsub.subscribe('destroy', () => {
this.logger.debug('Closing Neo4j');
this.driver
.close()
.then(() => {
this.logger.debug('Neo4j has been closed');
})
.catch(error => {
this.logger.debug(`Neo4j couldn't be closed: ${error.message}`);
});
});
}
return this.driver;
}
Expand Down
5 changes: 4 additions & 1 deletion packages/handlers/postgraphile/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,10 @@ export default class PostGraphileHandler implements MeshHandler {
});
}

this.pubsub.subscribe('destroy', () => pgPool.end());
this.pubsub.subscribe('destroy', () => {
this.logger.debug('Destroying PostgreSQL pool');
pgPool.end();
});

const cacheKey = this.name + '_introspection.json';

Expand Down
6 changes: 3 additions & 3 deletions packages/runtime/src/get-mesh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ export interface MeshInstance {

export async function getMesh(options: GetMeshOptions): Promise<MeshInstance> {
const rawSources: RawSourceOutput[] = [];
const { pubsub, cache, logger = new DefaultLogger('Mesh') } = options;
const { pubsub, cache, logger = new DefaultLogger('🕸️') } = options;

const getMeshLogger = logger.child('getMesh/runtime');
const getMeshLogger = logger.child('GetMesh');
getMeshLogger.debug(`Getting subschemas from source handlers`);
await Promise.all(
options.sources.map(async apiSource => {
Expand Down Expand Up @@ -285,7 +285,7 @@ export async function getMesh(options: GetMeshOptions): Promise<MeshInstance> {
return context;
}

const executionLogger = logger.child(`meshExecute`);
const executionLogger = logger.child(`Execute`);
async function meshExecute<TVariables = any, TContext = any, TRootValue = any, TData = any>(
document: GraphQLOperation<TData, TVariables>,
variableValues?: TVariables,
Expand Down
2 changes: 1 addition & 1 deletion packages/types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ export type ImportFn = <T = any>(moduleId: string) => Promise<T>;
export type SyncImportFn = <T = any>(moduleId: string) => T;

export type Logger = {
name: string;
name?: string;
log: (message: string) => void;
warn: (message: string) => void;
info: (message: string) => void;
Expand Down
9 changes: 5 additions & 4 deletions packages/utils/src/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ const debugColor = chalk.magenta;
const titleBold = chalk.bold;

export class DefaultLogger implements Logger {
constructor(public name: string) {}
constructor(public name?: string) {}
log(message: string) {
return console.log(`${titleBold(this.name)}: ${message}`);
const finalMessage = this.name ? `${titleBold(this.name)}: ${message}` : message;
return console.log(finalMessage);
}

warn(message: string) {
Expand All @@ -27,12 +28,12 @@ export class DefaultLogger implements Logger {
}

debug(message: string) {
if (env.DEBUG) {
if ((env.DEBUG && env.DEBUG === '1') || this.name.includes(env.DEBUG)) {
return this.log(debugColor(message));
}
}

child(name: string): Logger {
return new DefaultLogger(`${this.name} - ${name}`);
return new DefaultLogger(this.name ? `${this.name} - ${name}` : name);
}
}

0 comments on commit 9eff8a3

Please sign in to comment.