Added logging to n8n (#1381)

* Added logging to n8n

This commit adds logging to n8n using the Winston library.

For now, this commit only allows logging to console (default behavior)
or file (need to pass in config via environment variables).

Other logging methods can be further implemented using hooks. These were
skipped for now as it would require adding more dependencies.

Logging level is notice by default, meaning no additional messages would
be displayed at the moment. Logging level can be set to info or debug as
well to enrich the generated logs.

The ILogger interface was added to the workflow project as it would make
it available for all other projects but the implementation was done on
the cli project.

* Lint fixes and logging level naming. Also fixed the way we use the logger as it was not working previously

* Improvements to logging framework

Using appropriate single quotes
Improving the way the logger is declared

* Improved naming for Log Types

* Removed logger global variable, replacing it by a proxy

* Add logging to CLI commands

* Remove unused GenericHelpers

* Changed back some messages to console instead of logger and added npm
shortcuts for worker and webhook

* Fix typos

* Adding basic file rotation to logs as suggested by @mutdmour

* Fixed linting issues

* Correcting comment to correctly reflect space usage

* Added settings for log files rotation

* Correcting config type from String to Number

* Changed default file settings to number

To reflect previous changes to the type

* Changed the way log messages are added to be called statically. Also minor naming improvements

* Applying latest corrections sent by @ivov

*  Some logging improvements

* Saving logs to a folder inside n8n home instead of root

* Fixed broken tests and linting

* Changed some log messages to improve formatting

* Adding quotes to names  on log messages

* Added execution and session IDs to logs. Also removed unnecessary line breaks

*  Added file caller to log messages (#1657)

This is done using callsites library which already existed
in the project as another library's dependency. So in fact
it does not add any new dependency.

* Adding logs to help debug Salesforce node

*  Add function name to logs and add more logs

*  Improve some error messages

*  Improve some more log messages

*  Rename logging env variables to match others

Co-authored-by: dali <servfrdali@yahoo.fr>
Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
This commit is contained in:
Omar Ajoue
2021-05-02 05:43:01 +02:00
committed by GitHub
parent 0b69310bed
commit c972f3dd50
29 changed files with 548 additions and 129 deletions

View File

@@ -13,7 +13,6 @@ import {
CredentialTypes,
Db,
ExternalHooks,
GenericHelpers,
IWorkflowBase,
IWorkflowExecutionDataProcess,
LoadNodesAndCredentials,
@@ -23,6 +22,13 @@ import {
WorkflowRunner,
} from '../src';
import {
getLogger,
} from '../src/Logger';
import {
LoggerProxy,
} from 'n8n-workflow';
export class Execute extends Command {
static description = '\nExecutes a given workflow';
@@ -44,6 +50,9 @@ export class Execute extends Command {
async run() {
const logger = getLogger();
LoggerProxy.init(logger);
const { flags } = this.parse(Execute);
// Start directly with the init of the database to improve startup time
@@ -54,12 +63,12 @@ export class Execute extends Command {
const loadNodesAndCredentialsPromise = loadNodesAndCredentials.init();
if (!flags.id && !flags.file) {
GenericHelpers.logOutput(`Either option "--id" or "--file" have to be set!`);
console.info(`Either option "--id" or "--file" have to be set!`);
return;
}
if (flags.id && flags.file) {
GenericHelpers.logOutput(`Either "id" or "file" can be set never both!`);
console.info(`Either "id" or "file" can be set never both!`);
return;
}
@@ -71,7 +80,7 @@ export class Execute extends Command {
workflowData = JSON.parse(await fs.readFile(flags.file, 'utf8'));
} catch (error) {
if (error.code === 'ENOENT') {
GenericHelpers.logOutput(`The file "${flags.file}" could not be found.`);
console.info(`The file "${flags.file}" could not be found.`);
return;
}
@@ -81,7 +90,7 @@ export class Execute extends Command {
// Do a basic check if the data in the file looks right
// TODO: Later check with the help of TypeScript data if it is valid or not
if (workflowData === undefined || workflowData.nodes === undefined || workflowData.connections === undefined) {
GenericHelpers.logOutput(`The file "${flags.file}" does not contain valid workflow data.`);
console.info(`The file "${flags.file}" does not contain valid workflow data.`);
return;
}
workflowId = workflowData.id!.toString();
@@ -95,8 +104,8 @@ export class Execute extends Command {
workflowId = flags.id;
workflowData = await Db.collections!.Workflow!.findOne(workflowId);
if (workflowData === undefined) {
GenericHelpers.logOutput(`The workflow with the id "${workflowId}" does not exist.`);
return;
console.info(`The workflow with the id "${workflowId}" does not exist.`);
process.exit(1);
}
}
@@ -138,7 +147,7 @@ export class Execute extends Command {
if (startNode === undefined) {
// If the workflow does not contain a start-node we can not know what
// should be executed and with which data to start.
GenericHelpers.logOutput(`The workflow does not contain a "Start" node. So it can not be executed.`);
console.info(`The workflow does not contain a "Start" node. So it can not be executed.`);
return Promise.resolve();
}
@@ -163,9 +172,10 @@ export class Execute extends Command {
}
if (data.data.resultData.error) {
this.log('Execution was NOT successfull:');
this.log('====================================');
this.log(JSON.stringify(data, null, 2));
console.info('Execution was NOT successful. See log message for details.');
logger.info('Execution error:');
logger.info('====================================');
logger.info(JSON.stringify(data, null, 2));
const { error } = data.data.resultData;
throw {
@@ -174,14 +184,15 @@ export class Execute extends Command {
};
}
this.log('Execution was successfull:');
this.log('====================================');
this.log(JSON.stringify(data, null, 2));
console.info('Execution was successful:');
console.info('====================================');
console.info(JSON.stringify(data, null, 2));
} catch (e) {
console.error('\nGOT ERROR');
console.log('====================================');
console.error(e.message);
console.error(e.stack);
console.error('Error executing workflow. See log messages for details.');
logger.error('\nExecution error:');
logger.info('====================================');
logger.error(e.message);
logger.error(e.stack);
this.exit(1);
}