Skip to content

Commit 3d6289d

Browse files
authored
@firebase/logger (#473)
* Start work on @firebase/logger package * Refactor to remove debug dep * [AUTOMATED]: Prettier Code Styling * [AUTOMATED]: License Headers * Expose a LogHandler type * Allow users to "silence" our logging * Adding some comments * Do @firebase/firestore integration * Do @firebase/database integration * [AUTOMATED]: Prettier Code Styling * Refactor to propagate the default level if changed * Add some basic tests * [AUTOMATED]: Prettier Code Styling * Feedback from @mikelehen and @schmidt-sebastian Refactor to also log fatal issues Refactor to not attempt to log if the level is invalid Adding docs and more feedback * [AUTOMATED]: Prettier Code Styling * Fixing an error message * Updating yarn.lock * Address @mikelehen feedback * [AUTOMATED]: Prettier Code Styling * Refactor logClient.log -> logClient.debug * Update deps * More @mikelehen feedback * Fixing comment * Feedback from @schmidt-sebastian
1 parent 9cda9c9 commit 3d6289d

File tree

15 files changed

+492
-46
lines changed

15 files changed

+492
-46
lines changed

packages/database/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
},
2121
"dependencies": {
2222
"@firebase/database-types": "0.1.2",
23+
"@firebase/logger": "0.1.0",
2324
"@firebase/util": "0.1.10",
2425
"faye-websocket": "0.11.1",
2526
"tslib": "^1.9.0"

packages/database/src/core/PersistentConnection.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -935,7 +935,7 @@ export class PersistentConnection extends ServerActions {
935935
if (this.securityDebugCallback_) {
936936
this.securityDebugCallback_(body);
937937
} else {
938-
if ('msg' in body && typeof console !== 'undefined') {
938+
if ('msg' in body) {
939939
console.log('FIREBASE: ' + body['msg'].replace('\n', '\nFIREBASE: '));
940940
}
941941
}

packages/database/src/core/util/util.ts

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ import { stringToByteArray } from '@firebase/util';
2727
import { stringify } from '@firebase/util';
2828
import { SessionStorage } from '../storage/storage';
2929
import { isNodeSdk } from '@firebase/util';
30+
import { Logger } from '@firebase/logger';
31+
32+
const logClient = new Logger('@firebase/database');
3033

3134
/**
3235
* Returns a locally-unique ID (generated by just incrementing up from 0 each time its called).
@@ -105,16 +108,7 @@ export const enableLogging = function(
105108
"Can't turn on custom loggers persistently."
106109
);
107110
if (logger_ === true) {
108-
if (typeof console !== 'undefined') {
109-
if (typeof console.log === 'function') {
110-
logger = console.log.bind(console);
111-
} else if (typeof console.log === 'object') {
112-
// IE does this.
113-
logger = function(message) {
114-
console.log(message);
115-
};
116-
}
117-
}
111+
logger = logClient.log.bind(logClient);
118112
if (persistent) SessionStorage.set('logging_enabled', true);
119113
} else if (typeof logger_ === 'function') {
120114
logger = logger_;
@@ -157,36 +151,25 @@ export const logWrapper = function(
157151
* @param {...string} var_args
158152
*/
159153
export const error = function(...var_args: string[]) {
160-
if (typeof console !== 'undefined') {
161-
const message = 'FIREBASE INTERNAL ERROR: ' + buildLogMessage_(...var_args);
162-
if (typeof console.error !== 'undefined') {
163-
console.error(message);
164-
} else {
165-
console.log(message);
166-
}
167-
}
154+
const message = 'FIREBASE INTERNAL ERROR: ' + buildLogMessage_(...var_args);
155+
logClient.error(message);
168156
};
169157

170158
/**
171159
* @param {...string} var_args
172160
*/
173161
export const fatal = function(...var_args: string[]) {
174-
const message = buildLogMessage_(...var_args);
175-
throw new Error('FIREBASE FATAL ERROR: ' + message);
162+
const message = `FIREBASE FATAL ERROR: ${buildLogMessage_(...var_args)}`;
163+
logClient.error(message);
164+
throw new Error(message);
176165
};
177166

178167
/**
179168
* @param {...*} var_args
180169
*/
181170
export const warn = function(...var_args: any[]) {
182-
if (typeof console !== 'undefined') {
183-
const message = 'FIREBASE WARNING: ' + buildLogMessage_(...var_args);
184-
if (typeof console.warn !== 'undefined') {
185-
console.warn(message);
186-
} else {
187-
console.log(message);
188-
}
189-
}
171+
const message = 'FIREBASE WARNING: ' + buildLogMessage_(...var_args);
172+
logClient.warn(message);
190173
};
191174

192175
/**

packages/firestore/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"license": "Apache-2.0",
2424
"dependencies": {
2525
"@firebase/firestore-types": "0.2.2",
26+
"@firebase/logger": "0.1.0",
2627
"@firebase/webchannel-wrapper": "0.2.6",
2728
"grpc": "^1.9.1",
2829
"tslib": "^1.9.0"

packages/firestore/src/util/log.ts

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,36 +19,58 @@
1919
import { SDK_VERSION } from '../core/version';
2020
import { AnyJs } from './misc';
2121
import { PlatformSupport } from '../platform/platform';
22+
import { Logger, LogLevel as FirebaseLogLevel } from '@firebase/logger';
23+
24+
const logClient = new Logger('@firebase/firestore');
2225

2326
export enum LogLevel {
2427
DEBUG,
2528
ERROR,
2629
SILENT
2730
}
2831

29-
let logLevel = LogLevel.ERROR;
30-
3132
// Helper methods are needed because variables can't be exported as read/write
3233
export function getLogLevel(): LogLevel {
33-
return logLevel;
34+
if (logClient.logLevel === FirebaseLogLevel.DEBUG) {
35+
return LogLevel.DEBUG;
36+
} else if (logClient.logLevel === FirebaseLogLevel.SILENT) {
37+
return LogLevel.SILENT;
38+
} else {
39+
return LogLevel.ERROR;
40+
}
3441
}
3542
export function setLogLevel(newLevel: LogLevel): void {
36-
logLevel = newLevel;
43+
/**
44+
* Map the new log level to the associated Firebase Log Level
45+
*/
46+
switch (newLevel) {
47+
case LogLevel.DEBUG:
48+
logClient.logLevel = FirebaseLogLevel.DEBUG;
49+
break;
50+
case LogLevel.ERROR:
51+
logClient.logLevel = FirebaseLogLevel.ERROR;
52+
break;
53+
case LogLevel.SILENT:
54+
logClient.logLevel = FirebaseLogLevel.SILENT;
55+
break;
56+
default:
57+
logClient.error(
58+
`Firestore (${SDK_VERSION}): Invalid value passed to \`setLogLevel\``
59+
);
60+
}
3761
}
3862

3963
export function debug(tag: string, msg: string, ...obj: AnyJs[]): void {
40-
if (logLevel <= LogLevel.DEBUG) {
41-
const time = new Date().toISOString();
64+
if (logClient.logLevel <= FirebaseLogLevel.DEBUG) {
4265
const args = obj.map(argToString);
43-
console.log(`Firestore (${SDK_VERSION}) ${time} [${tag}]: ${msg}`, ...args);
66+
logClient.debug(`Firestore (${SDK_VERSION}) [${tag}]: ${msg}`, ...args);
4467
}
4568
}
4669

4770
export function error(msg: string, ...obj: AnyJs[]): void {
48-
if (logLevel <= LogLevel.ERROR) {
49-
const time = new Date().toISOString();
71+
if (logClient.logLevel <= FirebaseLogLevel.ERROR) {
5072
const args = obj.map(argToString);
51-
console.error(`Firestore (${SDK_VERSION}) ${time}: ${msg}`, ...args);
73+
logClient.error(`Firestore (${SDK_VERSION}): ${msg}`, ...args);
5274
}
5375
}
5476

packages/logger/.npmignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# This file is left intentionally blank

packages/logger/README.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# @firebase/logger
2+
3+
This package serves as the base of all logging in the JS SDK. Any logging that
4+
is intended to be visible to Firebase end developers should go through this
5+
module.
6+
7+
## Basic Usage
8+
9+
Firebase components should import the `Logger` class and instantiate a new
10+
instance by passing a component name (e.g. `@firebase/<COMPONENT>`) to the
11+
constructor.
12+
13+
_e.g._
14+
15+
```typescript
16+
import { Logger } from '@firebase/logger';
17+
18+
const logClient = new Logger(`@firebase/<COMPONENT>`);
19+
```
20+
21+
Each `Logger` instance supports 5 log functions each to be used in a specific
22+
instance:
23+
24+
- `debug`: Internal logs; use this to allow developers to send us their debug
25+
logs for us to be able to diagnose an issue.
26+
- `log`: Use to inform your user about things they may need to know.
27+
- `info`: Use if you have to inform the user about something that they need to
28+
take a concrete action on. Once they take that action, the log should go away.
29+
- `warn`: Use when a product feature may stop functioning correctly; unexpected
30+
scenario.
31+
- `error`: Only use when user App would stop functioning correctly - super rare!
32+
33+
## Log Format
34+
35+
Each log will be formatted in the following manner:
36+
37+
```typescript
38+
`[${new Date()}] ${COMPONENT_NAME}: ${...args}`
39+
```
40+

packages/logger/gulpfile.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* Copyright 2017 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
const gulp = require('gulp');
18+
const tools = require('../../tools/build');
19+
20+
const buildModule = gulp.parallel([
21+
tools.buildCjs(__dirname),
22+
tools.buildEsm(__dirname)
23+
]);
24+
25+
const setupWatcher = () => {
26+
gulp.watch(['index.ts', 'src/**/*'], buildModule);
27+
};
28+
29+
gulp.task('build', buildModule);
30+
31+
gulp.task('dev', gulp.parallel([setupWatcher]));

packages/logger/index.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* Copyright 2017 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { instances, LogLevel } from './src/logger';
18+
19+
export function setLogLevel(level: LogLevel) {
20+
instances.forEach(inst => {
21+
inst.logLevel = level;
22+
});
23+
}
24+
25+
export { Logger, LogLevel, LogHandler } from './src/logger';

packages/logger/karma.conf.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* Copyright 2017 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
const karma = require('karma');
18+
const path = require('path');
19+
const karmaBase = require('../../config/karma.base');
20+
21+
module.exports = function(config) {
22+
const karmaConfig = Object.assign({}, karmaBase, {
23+
// files to load into karma
24+
files: [{ pattern: `test/**/*` }],
25+
// frameworks to use
26+
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
27+
frameworks: ['mocha']
28+
});
29+
30+
config.set(karmaConfig);
31+
};

packages/logger/package.json

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
{
2+
"name": "@firebase/logger",
3+
"version": "0.1.0",
4+
"private": true,
5+
"description": "A logger package for use in the Firebase JS SDK",
6+
"author": "Firebase <[email protected]> (https://firebase.google.com/)",
7+
"main": "dist/cjs/index.js",
8+
"module": "dist/esm/index.js",
9+
"scripts": {
10+
"dev": "gulp dev",
11+
"test": "run-p test:browser test:node",
12+
"test:browser": "karma start --single-run",
13+
"test:browser:debug": "karma start --browsers Chrome --auto-watch",
14+
"test:node": "nyc --reporter lcovonly -- mocha test/**/*.test.* --compilers ts:ts-node/register --exit",
15+
"prepare": "gulp build"
16+
},
17+
"license": "Apache-2.0",
18+
"devDependencies": {
19+
"@types/chai": "^4.1.2",
20+
"@types/mocha": "^2.2.48",
21+
"@types/sinon": "^4.1.3",
22+
"chai": "^4.1.1",
23+
"gulp": "^4.0.0",
24+
"karma": "^2.0.0",
25+
"karma-chrome-launcher": "^2.2.0",
26+
"karma-cli": "^1.0.1",
27+
"karma-mocha": "^1.3.0",
28+
"karma-sauce-launcher": "^1.2.0",
29+
"karma-spec-reporter": "^0.0.32",
30+
"karma-webpack": "^2.0.9",
31+
"mocha": "^5.0.1",
32+
"npm-run-all": "^4.1.1",
33+
"nyc": "^11.4.1",
34+
"ts-loader": "^3.5.0",
35+
"ts-node": "^5.0.0",
36+
"typescript": "^2.7.2",
37+
"webpack": "^3.11.0"
38+
},
39+
"repository": {
40+
"type": "git",
41+
"url": "https://github.com/firebase/firebase-js-sdk/tree/master/packages/logger"
42+
},
43+
"bugs": {
44+
"url": "https://github.com/firebase/firebase-js-sdk/issues"
45+
},
46+
"typings": "dist/esm/index.d.ts",
47+
"nyc": {
48+
"extension": [
49+
".ts"
50+
],
51+
"reportDir": "./coverage/node"
52+
},
53+
"dependencies": {}
54+
}

0 commit comments

Comments
 (0)