Skip to content

@firebase/logger #473

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

Merged
merged 24 commits into from
Feb 28, 2018
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
1eaa3fc
Start work on @firebase/logger package
jshcrowthe Jan 17, 2018
26a9fd0
Refactor to remove debug dep
jshcrowthe Jan 25, 2018
07ff3ff
[AUTOMATED]: Prettier Code Styling
jshcrowthe Jan 25, 2018
0895b3d
[AUTOMATED]: License Headers
jshcrowthe Jan 25, 2018
12118c0
Expose a LogHandler type
jshcrowthe Jan 25, 2018
d3a4b6b
Allow users to "silence" our logging
jshcrowthe Jan 29, 2018
e0e2ecb
Adding some comments
jshcrowthe Jan 29, 2018
3d497db
Do @firebase/firestore integration
jshcrowthe Jan 29, 2018
1add931
Do @firebase/database integration
jshcrowthe Jan 29, 2018
c7b8557
[AUTOMATED]: Prettier Code Styling
jshcrowthe Jan 29, 2018
51d519b
Refactor to propagate the default level if changed
jshcrowthe Jan 29, 2018
67e8f35
Add some basic tests
jshcrowthe Jan 30, 2018
6128011
[AUTOMATED]: Prettier Code Styling
jshcrowthe Jan 30, 2018
f369890
Feedback from @mikelehen and @schmidt-sebastian
jshcrowthe Feb 20, 2018
d90daab
[AUTOMATED]: Prettier Code Styling
jshcrowthe Feb 21, 2018
36105b9
Fixing an error message
jshcrowthe Feb 21, 2018
2ba4043
Updating yarn.lock
jshcrowthe Feb 26, 2018
1d027ed
Address @mikelehen feedback
jshcrowthe Feb 26, 2018
9c766dc
[AUTOMATED]: Prettier Code Styling
jshcrowthe Feb 26, 2018
53a96fe
Refactor logClient.log -> logClient.debug
jshcrowthe Feb 26, 2018
056610b
Update deps
jshcrowthe Feb 26, 2018
4c01a1b
More @mikelehen feedback
jshcrowthe Feb 28, 2018
3ec3d8a
Fixing comment
jshcrowthe Feb 28, 2018
8b0c7e4
Feedback from @schmidt-sebastian
jshcrowthe Feb 28, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 18 additions & 10 deletions packages/firestore/src/util/log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,28 +41,36 @@ export function getLogLevel(): LogLevel {
}
export function setLogLevel(newLevel: LogLevel): void {
/**
* Since Firestore's LogLevel enum is a pure subset of Firebase's LogLevel, we
* can return it directly.
* Map the new log level to the associated Firebase Log Level
*/
logClient.logLevel = newLevel;
switch (newLevel) {
case LogLevel.DEBUG:
logClient.logLevel = FirebaseLogLevel.DEBUG;
break;
case LogLevel.ERROR:
logClient.logLevel = FirebaseLogLevel.ERROR;
break;
case LogLevel.SILENT:
logClient.logLevel = FirebaseLogLevel.SILENT;
break;
default:
logClient.error(
`Firestore (${SDK_VERSION}): Invalid value passed to \`setLogLevel\``
);
}
}

export function debug(tag: string, msg: string, ...obj: AnyJs[]): void {
if (logClient.logLevel <= FirebaseLogLevel.DEBUG) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Are you intentionally comparing to DEBUG and then using .log() below [as opposed to .debug]? I'm guessing this should be .LOG here, but then we also need to change the setLogLevel() code above to map Firestore's DEBUG LogLevel to Firebase's LOG LogLevel...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Great catch here, refactored the logging call to logClient.debug

const time = new Date().toISOString();
const args = obj.map(argToString);
logClient.log(
`Firestore (${SDK_VERSION}) ${time} [${tag}]: ${msg}`,
...args
);
logClient.debug(`Firestore (${SDK_VERSION}) [${tag}]: ${msg}`, ...args);
}
}

export function error(msg: string, ...obj: AnyJs[]): void {
if (logClient.logLevel <= FirebaseLogLevel.ERROR) {
const time = new Date().toISOString();
const args = obj.map(argToString);
logClient.error(`Firestore (${SDK_VERSION}) ${time}: ${msg}`, ...args);
logClient.error(`Firestore (${SDK_VERSION}): ${msg}`, ...args);
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/logger/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@ instance:
Each log will be formatted in the following manner:

```typescript
`[${new Date()}] ${this.name}: ${...args}`
`[${new Date()}] ${COMPONENT_NAME}: ${...args}`
```

7 changes: 0 additions & 7 deletions packages/logger/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,6 @@
* limitations under the License.
*/

/**
* This is the file that people using Node.js will actually import. You should
* only include this file if you have something specific about your
* implementation that mandates having a separate entrypoint. Otherwise you can
* just use index.ts
*/

import { instances, LogLevel } from './src/logger';

export function setLogLevel(level: LogLevel) {
Expand Down
26 changes: 13 additions & 13 deletions packages/logger/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,25 @@
},
"license": "Apache-2.0",
"devDependencies": {
"@types/chai": "^4.0.4",
"@types/mocha": "^2.2.44",
"@types/sinon": "^2.3.7",
"@types/chai": "^4.1.2",
"@types/mocha": "^2.2.48",
"@types/sinon": "^4.1.3",
"chai": "^4.1.1",
"gulp": "gulpjs/gulp#4.0",
"karma": "^1.7.0",
"gulp": "^4.0.0",
"karma": "^2.0.0",
"karma-chrome-launcher": "^2.2.0",
"karma-cli": "^1.0.1",
"karma-mocha": "^1.3.0",
"karma-sauce-launcher": "^1.2.0",
"karma-spec-reporter": "^0.0.31",
"karma-webpack": "^2.0.4",
"mocha": "^4.0.1",
"karma-spec-reporter": "^0.0.32",
"karma-webpack": "^2.0.9",
"mocha": "^5.0.1",
"npm-run-all": "^4.1.1",
"nyc": "^11.2.1",
"ts-loader": "^3.1.0",
"ts-node": "^3.3.0",
"typescript": "^2.4.2",
"webpack": "^3.8.1"
"nyc": "^11.4.1",
"ts-loader": "^3.5.0",
"ts-node": "^5.0.0",
"typescript": "^2.7.2",
"webpack": "^3.11.0"
},
"repository": {
"type": "git",
Expand Down
23 changes: 20 additions & 3 deletions packages/logger/src/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export enum LogLevel {
}

/**
* A container for the default log level
* The sefault log level
Copy link
Contributor

Choose a reason for hiding this comment

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

sefault => default

*/
const defaultLogLevel: LogLevel = LogLevel.WARN;

Expand All @@ -62,10 +62,25 @@ export type LogHandler = (
*/
const defaultLogHandler: LogHandler = (instance, logType, ...args) => {
if (logType < instance.logLevel) return;
const now = new Date();
const now = new Date().toISOString();
switch (logType) {
/**
* The default log handler doesn't do anything with LogLevel silent, so we
* are early returning here. To allow custom log handlers to handle this
* behavior differently, we are still going to pass through logging calls
* to their handlers when the log level is set to `SILENT`.
*/
Copy link
Contributor

Choose a reason for hiding this comment

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

I still don't understand this. AFAICT, there's currently no way for logType to be SILENT since there's no Logger.silent(...) method and it would never make sense to have one. So I think we should not have a case for SILENT and it should fall through to default: and throw.

case LogLevel.SILENT:
Copy link
Contributor

Choose a reason for hiding this comment

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

We should never generate log messages with level SILENT, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added a comment here to explain the rationale. There is value for allowing custom log handlers to handle SILENT logs in their own way which is why this is included.

return;
/**
* By default, `console.debug` is not displayed in the developer console (in
* chrome). To avoid forcing users to have to opt-in to these logs twice
* (i.e. once for firebase, and once in the console), we are sending `DEBUG`
* logs to the `console.log` function.
*/
case LogLevel.DEBUG:
console.log(`[${now}] ${instance.name}:`, ...args);
break;
case LogLevel.LOG:
console.log(`[${now}] ${instance.name}:`, ...args);
break;
Expand All @@ -79,7 +94,9 @@ const defaultLogHandler: LogHandler = (instance, logType, ...args) => {
console.error(`[${now}] ${instance.name}:`, ...args);
break;
default:
Copy link
Contributor

Choose a reason for hiding this comment

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

  1. You left out DEBUG
  2. Rather than default to console.log(), I'd throw an exception. That way you'll notice if you leave out a log level. If for some reason you were intentionally handling DEBUG via the default: case, then a comment is warranted to explain your intent.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

console.log(`[${now}] ${instance.name}:`, ...args);
throw new Error(
`Attempted to log a message with an invalid logType (value: ${logType})`
);
}
};

Expand Down
15 changes: 6 additions & 9 deletions packages/logger/test/logger.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ describe('@firebase/logger', () => {
const message = 'Hello there!';
let client: Logger;
const spies = {
debugSpy: null,
logSpy: null,
infoSpy: null,
warnSpy: null,
Expand Down Expand Up @@ -52,13 +51,14 @@ describe('@firebase/logger', () => {

function testLog(message, channel, shouldLog) {
/**
* `debug` logs also go through log channel
* Ensure that `debug` logs assert against the `console.log` function. The
Copy link
Contributor

Choose a reason for hiding this comment

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

"assert against" doesn't seem like the right wording here. Perhaps just "via"?

* rationale here is explained in `logger.ts`.
*/
channel = channel === 'debug' ? 'log' : channel;

it(`Should ${shouldLog ? '' : 'not'} call \`console.${channel}\` if \`.${
channel
}\` is called`, () => {
it(`Should ${
shouldLog ? '' : 'not'
} call \`console.${channel}\` if \`.${channel}\` is called`, () => {
client[channel](message);
expect(
spies[`${channel}Spy`] && spies[`${channel}Spy`].called,
Expand All @@ -81,10 +81,7 @@ describe('@firebase/logger', () => {
testLog(message, 'error', true);
});

describe('Defaults', () => {
beforeEach(() => {
setLogLevel(LogLevel.WARN);
});
describe('Defaults to LogLevel.WARN', () => {
testLog(message, 'debug', false);
testLog(message, 'log', false);
testLog(message, 'info', false);
Expand Down
7 changes: 0 additions & 7 deletions packages/template/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,6 @@
* limitations under the License.
*/

/**
* This is the file that people using Node.js will actually import. You should
* only include this file if you have something specific about your
* implementation that mandates having a separate entrypoint. Otherwise you can
* just use index.ts
*/

import { testFxn } from './src';

testFxn();