Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(logging): Allow log to a file #954

Merged
merged 38 commits into from
Jul 17, 2018
Merged

feat(logging): Allow log to a file #954

merged 38 commits into from
Jul 17, 2018

Conversation

nicojs
Copy link
Member

@nicojs nicojs commented Jul 6, 2018

This feature adds the ability to log to a "stryker.log" file using a separate log level.

You can configure it like this:

// stryker.conf.js
module.exports = function(config) {
  config.set({
    fileLogLevel: 'trace' // defaults to 'off'
  });
}

Note: The console logger can still be configured as expected using logLevel: 'info'.

This also adds logging to the stryker api. Plugin creators can now opt into stryker logging using the new logging api:

import { getLogger, Logger } from 'stryker-api/logging';
const logger: Logger = getLogger('myLoggerCategory');

They no longer have to 'role their own config'. Stryker will take care of the logging appearing in the expected places (console and file).

Fixes #748

@ghost ghost assigned nicojs Jul 6, 2018
@ghost ghost added the 🔎 Needs review label Jul 6, 2018
@nicojs nicojs requested a review from sanderkoenders July 6, 2018 15:38
@nicojs nicojs force-pushed the 748-logging-api branch from f0204c1 to 701b36a Compare July 7, 2018 00:25
@nicojs nicojs force-pushed the 748-logging-api branch from 701b36a to ee1efda Compare July 7, 2018 00:27
@nicojs
Copy link
Member Author

nicojs commented Jul 7, 2018

Finally got a green build! I even ran into a race condition with the log4js logging service. I still want to make the code in the LogConfigurator a bit cleaner though. Otherwise it can be reviewed.

@nicojs
Copy link
Member Author

nicojs commented Jul 7, 2018

I've removed the retrying mechanism for getting a free port to log to as it was not working properly. Instead, removed the preference for port 5000 to decrease the likelihood of hitting an EADDRINUSE error.

simondel pushed a commit that referenced this pull request Jul 12, 2018
This PR pins all _dependencies_ and _devDependencies_ on minor versions. I also consolidated all commonly used dependencies to most recent (supported) versions. Namely:

* log4js@~1.1.0 (we're upgrading to 2.x with #954)
* semver@~5.5.0
* tslib@~1.9.3

Fixes #967
Copy link
Member

@simondel simondel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you take a look at my comments? We need to make sure that we update the peer dependencies of packages ourselves to we drop support for older api versions with this change.

const strykerLog = await fs.readFile('./stryker.log', 'utf8');
expect(strykerLog).contains('INFO InputFileResolver Found 2 of 10 file(s) to be mutated');
expect(strykerLog).matches(/Stryker Done in \d+ seconds/);
// expect(strykerLog).not.contains('ERROR'); TODO
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this in a todo?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We get an error after 10 test runs because of this issue: jasmine/jasmine-npm#134. I'll add it as a comment.

* @returns {Logger} instance of logger for the category
* @static
*/
export default interface LoggerFactoryMethod {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why this exists and what it does

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the description to:

* Represents a factory to get loggers by category name.
 * This interface is used to describe the shape of a logger factory method.

Is this better?

export { default as LoggerFactory } from './src/logging/LoggerFactory';
export { default as Logger } from './src/logging/Logger';
export { default as LoggerFactoryMethod } from './src/logging/LoggerFactoryMethod';
export { default as getLogger } from './src/logging/getLogger';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need getLogger in a separate file or can we also just place the content here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is how our entire API is build up right now. Everything in separate files. getLogger is also used from LoggerFactoryMethod and others. You want me to move the entire logging API to this file?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's leave it like this for now.

@@ -1,4 +1,4 @@
import * as log4js from 'log4js';
import * as logging from 'stryker-api/logging';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what else do we use from the logging here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, changing it to a named import.

@@ -1,4 +1,4 @@
import * as log4js from 'log4js';
import * as log4js from 'stryker-api/logging';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a log4jsMock file

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I'll change it.

/**
* Configure the logging for the server. Includes the master configuration.
* This method can only be called ONCE, as it starts the log4js server to listen for log events.
* It returns the logging client context that should be used to doe the `forWorker` calls.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean? There seem to be some errors in the last part of this sentence.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rephrased it as: It returns the logging client context that should be used to configure the child processes.. I've also renamed the forWorker method to configureChildProcess. Is it clearer now?


/**
* Configure the logging for the server. Includes the master configuration.
* This method can only be called ONCE, as it starts the log4js server to listen for log events.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can it only be called once or should it only be called once?

}

function getLevel(level: LogLevel): log4js.Level {
// Needs an any cast here, wrongly typed, see https://github.com/log4js-node/log4js-node/pull/745
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this fixed now?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! My PR got merged. I've removed this entire method 👍


private static createMasterAppenders(consoleLogLevel: LogLevel, fileLogLevel: LogLevel): AppendersConfiguration {

const multiAppender = { type: require.resolve('./MultiAppender'), appenders: ['filteredConsole'] };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why require the type like this? What are you trying to do?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's the log4js way of loading custom appenders. See https://log4js-node.github.io/log4js-node/appenders.html#other-appenders. I'll add the link to the code as well so it's less magical.

}
}

export function configure(config: { appenders: string[] }, _: any, findAppender: (name: string) => RuntimeAppender ): RuntimeAppender {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this used?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is used by log4js. See https://log4js-node.github.io/log4js-node/writing-appenders.html. I'll add a jsdoc explaining it.

@nicojs
Copy link
Member Author

nicojs commented Jul 12, 2018

Thanks for the great review @simondel . I've implemented the changes, could you take a look?

@nicojs
Copy link
Member Author

nicojs commented Jul 14, 2018

Just one question left @simondel. I'll try to update the peer dependency version later today as well. (But might be tomorrow)

@simondel
Copy link
Member

Looks good to me! Just one question, do we want to upgrade to log4js 3.0 in this PR or separately?

nicojs added 4 commits July 17, 2018 08:00
Refactor code so additional arguments are passed as constructor parameters.
Also refactor the integration tests to be more flat and consice.
@nicojs
Copy link
Member Author

nicojs commented Jul 17, 2018

@simondel I've refactored the code to remove the IsolatedRunnerOptions interface. I also add the dependency to log4js 3.0.0. Could you merge this PR before merging others today? (don't want to keep resolving package.json merge conflicts)

@simondel simondel merged commit c2f6b82 into master Jul 17, 2018
@ghost ghost removed the 🔎 Needs review label Jul 17, 2018
@simondel
Copy link
Member

Merged 🎉

@simondel simondel deleted the 748-logging-api branch July 17, 2018 07:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants