diff --git a/packages/common/package.json b/packages/common/package.json index c05d9bff1b9..f92f6c006c8 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -50,6 +50,7 @@ "google-proto-files": "^0.8.0", "grpc": "^1.0.0", "is": "^3.0.1", + "log-driver": "^1.2.5", "methmeth": "^1.0.0", "modelo": "^4.2.0", "request": "^2.70.0", diff --git a/packages/common/src/index.js b/packages/common/src/index.js index a56915b435c..53f0875ed7d 100644 --- a/packages/common/src/index.js +++ b/packages/common/src/index.js @@ -32,6 +32,12 @@ exports.GrpcService = require('./grpc-service.js'); */ exports.GrpcServiceObject = require('./grpc-service-object.js'); +/** + * @type {module:common/logger} + * @private + */ +exports.logger = require('./logger.js'); + /** * @type {module:common/operation} * @private diff --git a/packages/common/src/logger.js b/packages/common/src/logger.js new file mode 100644 index 00000000000..1e5621afdcb --- /dev/null +++ b/packages/common/src/logger.js @@ -0,0 +1,68 @@ +/*! + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + 'use strict'; + +/*! + * @module common/logger + */ + +var format = require('string-format-obj'); +var is = require('is'); +var logDriver = require('log-driver'); + +/** + * Create a logger to print output to the console. + * + * @param {string=|object=} options - Configuration object. If a string, it is + * treated as `options.level`. + * @param {string=} options.level - The minimum log level that will print to the + * console. (Default: `error`) + * @param {string=} options.tag - A tag to use in log messages. + */ +function logger(options) { + if (is.string(options)) { + options = { + level: options + }; + } + + options = options || {}; + + return logDriver({ + levels: [ + 'error', + 'warn', + 'info', + 'debug', + 'silly' + ], + + level: options.level || 'error', + + format: function() { + var args = [].slice.call(arguments); + + return format('{level}{tag} {message}', { + level: args.shift().toUpperCase(), + tag: options.tag ? ':' + options.tag + ':' : '', + message: args.join(' ') + }); + } + }); +} + +module.exports = logger; diff --git a/packages/common/test/index.js b/packages/common/test/index.js index 076f6bc88d6..24097fd3fe2 100644 --- a/packages/common/test/index.js +++ b/packages/common/test/index.js @@ -22,6 +22,7 @@ var proxyquire = require('proxyquire'); var fakeGrpcOperation = {}; var fakeGrpcService = {}; var fakeGrpcServiceObject = {}; +var fakeLogger = {}; var fakeOperation = {}; var fakePaginator = {}; var fakeService = {}; @@ -36,6 +37,7 @@ describe('common', function() { './grpc-operation.js': fakeGrpcOperation, './grpc-service.js': fakeGrpcService, './grpc-service-object.js': fakeGrpcServiceObject, + './logger.js': fakeLogger, './operation.js': fakeOperation, './paginator.js': fakePaginator, './service.js': fakeService, @@ -49,10 +51,11 @@ describe('common', function() { GrpcOperation: fakeGrpcOperation, GrpcService: fakeGrpcService, GrpcServiceObject: fakeGrpcServiceObject, + logger: fakeLogger, Operation: fakeOperation, + paginator: fakePaginator, Service: fakeService, ServiceObject: fakeServiceObject, - paginator: fakePaginator, util: fakeUtil }); }); diff --git a/packages/common/test/logger.js b/packages/common/test/logger.js new file mode 100644 index 00000000000..b4be2efc765 --- /dev/null +++ b/packages/common/test/logger.js @@ -0,0 +1,81 @@ +/*! + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +var assert = require('assert'); +var proxyquire = require('proxyquire'); + +function fakeLogDriver(config) { + return config; +} + +describe('logger base-functionality', function() { + var logger; + + before(function() { + logger = proxyquire('../src/logger.js', { + 'log-driver': fakeLogDriver + }); + }); + + it('should create a logger with the correct levels', function() { + assert.deepEqual(logger().levels, [ + 'error', + 'warn', + 'info', + 'debug', + 'silly' + ]); + }); + + it('should use a specified level', function() { + var level = 'level'; + assert.strictEqual(logger({ level: level }).level, level); + }); + + it('should treat a single arguments as the level', function() { + var level = 'level'; + assert.strictEqual(logger(level).level, level); + }); + + it('should default level to error', function() { + assert.strictEqual(logger().level, 'error'); + }); + + describe('formatting', function() { + var LEVEL = 'level-name'; + var TAG = 'tag-name'; + var MESSAGES = [ + 'message-1', + 'message-2' + ]; + + it('should correctly format without a tag', function() { + var formatted = logger().format(LEVEL, MESSAGES[0], MESSAGES[1]); + + assert.strictEqual(formatted, 'LEVEL-NAME message-1 message-2'); + }); + + it('should correctly format with a tag', function() { + var formatted = logger({ + tag: TAG + }).format(LEVEL, MESSAGES[0], MESSAGES[1]); + + assert.strictEqual(formatted, 'LEVEL-NAME:tag-name: message-1 message-2'); + }); + }); +});