Skip to content
This repository was archived by the owner on Apr 3, 2024. It is now read-only.

Commit a131faf

Browse files
Add the start() Method and the Ability to Specify the Service Name/Version in the Debug Config (#167)
* Now the cloud debugger is started by explicitly calling the new `start()` method. If the `start()` method is not called within 1 second, it is automatically called and a message is issued detailing that the `start()` method will need to be explicitly called in future releases. * The start method now also accepts an optional configuration object. Further, any configuration option specified via an environment variable takes priority over configuration options specified in the configuration object given to the `start()` method, which take priority over configuration options specified in the config file specified by the `GCLOUD_DIAGNOSTICS_CONFIG` environment variable. * The service name and configuration can now be specified in the configuration by specifying the new `serviceContext` attribute as illustrated below: ``` { ... serviceContext: { service: 'service-name', version: '1' }, ... } ```
1 parent f8bb4dc commit a131faf

File tree

10 files changed

+150
-30
lines changed

10 files changed

+150
-30
lines changed

index.js

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ var Debuglet = require('./lib/debuglet.js');
2424
var path = require('path');
2525
var _ = require('lodash');
2626

27-
var initConfig = function() {
28-
var config = {};
27+
var initConfig = function(config_) {
28+
var config = config_ || {};
29+
2930
if (process.env.hasOwnProperty('GCLOUD_DIAGNOSTICS_CONFIG')) {
3031
var c = require(path.resolve(process.env.GCLOUD_DIAGNOSTICS_CONFIG));
3132
if (c && c.debug) {
@@ -44,17 +45,43 @@ var initConfig = function() {
4445
config.appPathRelativeToRepository =
4546
process.env.GCLOUD_DEBUG_REPO_APP_PATH;
4647
}
48+
if (process.env.hasOwnProperty('GAE_MODULE_NAME')) {
49+
config.serviceContext = config.serviceContext || {};
50+
config.serviceContext.service = process.env.GAE_MODULE_NAME;
51+
}
52+
if (process.env.hasOwnProperty('GAE_MODULE_VERSION')) {
53+
config.serviceContext = config.serviceContext || {};
54+
config.serviceContext.version = process.env.GAE_MODULE_VERSION;
55+
}
4756
return config;
4857
};
4958

50-
// exports is populated by the agent
51-
module.exports = {};
52-
var config = initConfig();
59+
module.exports = {
60+
start: start
61+
};
5362

54-
var log = logger.create(config.logLevel, '@google/cloud-debug');
63+
var log_;
64+
function start(config_) {
65+
if (start.wasSuccessful_) {
66+
return log_.error('The cloud-debug agent has already been started.');
67+
}
5568

56-
if (config.enabled) {
57-
var debuglet = new Debuglet(config, log);
58-
debuglet.start();
59-
module.exports.private_ = debuglet;
69+
var config = initConfig(config_);
70+
log_ = logger.create(config.logLevel, '@google/cloud-debug');
71+
if (config.enabled) {
72+
var debuglet = new Debuglet(config, log_);
73+
debuglet.start();
74+
module.exports.private_ = debuglet;
75+
start.wasSuccessful_ = true;
76+
}
6077
}
78+
79+
setTimeout(function() {
80+
if (!start.wasSuccessful_){
81+
start();
82+
log_.error('The @google/cloud-debug agent now needs the start() ' +
83+
'function to be called in ordered to start operating. To ease ' +
84+
'migration we start the agent automatically after a 1 second delay, '+
85+
'but this behaviour will be dropped in a future semver major release.');
86+
}
87+
}, 1000);

lib/debuglet.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ function Debuglet(config, logger) {
6969
this.logger_ = logger;
7070

7171
/** @private {DebugletApi} */
72-
this.debugletApi_ = new DebugletApi(config.description);
72+
this.debugletApi_ = new DebugletApi(config);
7373

7474
/** @private {Object.<string, Breakpoint>} */
7575
this.activeBreakpointMap_ = {};

lib/debugletapi.js

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ var SCOPES = [
4141
/**
4242
* @constructor
4343
*/
44-
function DebugletApi(descriptor) {
44+
function DebugletApi(config) {
45+
var config_ = config || {};
46+
4547
/** @private {Object} request style request object */
4648
this.request_ = utils.authorizedRequestFactory(SCOPES);
4749

@@ -52,7 +54,13 @@ function DebugletApi(descriptor) {
5254
this.debuggeeId_ = null;
5355

5456
/** @private {string} a descriptor of the current code version */
55-
this.descriptor_ = descriptor;
57+
this.descriptor_ = config_.description;
58+
59+
/** @private {string} the service name of the current code */
60+
this.serviceName_ = config_.serviceContext && config_.serviceContext.service;
61+
62+
/** @private {string} the version of the current code */
63+
this.serviceVersion_ = config_.serviceContext && config_.serviceContext.version;
5664
}
5765

5866
/**
@@ -142,20 +150,23 @@ DebugletApi.prototype.register_ = function(errorMessage, callback) {
142150
'projectid': that.project_
143151
};
144152

145-
if (process.env.GAE_MODULE_NAME) {
146-
desc += ' module:' + process.env.GAE_MODULE_NAME;
147-
labels[DEBUGGEE_MODULE_LABEL] = process.env.GAE_MODULE_NAME;
153+
var serviceName = that.serviceName_;
154+
if (serviceName) {
155+
desc += ' module:' + serviceName;
156+
labels[DEBUGGEE_MODULE_LABEL] = serviceName;
148157
}
149158

150-
if (process.env.GAE_MODULE_VERSION) {
151-
desc += ' version:' + process.env.GAE_MODULE_VERSION;
152-
if (process.env.GAE_MODULE_VERSION !== 'default') {
153-
labels[DEBUGGEE_MAJOR_VERSION_LABEL] = process.env.GAE_MODULE_VERSION;
159+
var serviceVersion = that.serviceVersion_;
160+
if (serviceVersion) {
161+
desc += ' version:' + serviceVersion;
162+
if (serviceVersion !== 'default') {
163+
labels[DEBUGGEE_MAJOR_VERSION_LABEL] = serviceVersion;
154164
}
155165
}
156166

157-
if (that.descriptor_) {
158-
desc += ' description:' + that.descriptor_;
167+
var descriptor = that.descriptor_;
168+
if (descriptor) {
169+
desc += ' description:' + descriptor;
159170
}
160171

161172
if (process.env.GAE_MINOR_VERSION) {

test/fixtures/test-config.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ module.exports = {
2323
// An identifier for the current code deployment.
2424
description: 'test config',
2525

26+
serviceContext: {
27+
// An identifier for the current code's service name
28+
service: 'test service name',
29+
30+
// An identifier for the current code's version
31+
version: 'test version'
32+
},
33+
2634
// Log levels: 0-disabled,1-error,2-warn,3-info,4-debug.
2735
logLevel: 4,
2836

@@ -31,6 +39,9 @@ module.exports = {
3139
includeNodeModules: true,
3240
},
3341

42+
// This is only for testing the config priority
43+
testPriority: 'from the config file',
44+
3445
// These configuration options are for internal experimentation only.
3546
internal: {
3647
registerDelayOnFetcherErrorSec: 300 // 5 minutes.

test/standalone/test-env-config.js

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,32 @@
1717
'use strict';
1818

1919
process.env.GCLOUD_DIAGNOSTICS_CONFIG = 'test/fixtures/test-config.js';
20-
process.env.GCLOUD_DEBUG_LOGLEVEL = 4;
20+
process.env.GCLOUD_DEBUG_LOGLEVEL = 1;
21+
process.env.GAE_MODULE_NAME = 'a new name';
22+
process.env.GAE_MODULE_VERSION = 'a new version';
2123

2224
var assert = require('assert');
2325

2426
describe('should respect environment variables', function() {
2527
it('should respect GCLOUD_DIAGNOSTICS_CONFIG', function() {
2628
var agent = require('../..');
29+
agent.start({
30+
testPriority: 'from the supplied config',
31+
logLevel: 2 // this value is intentionally different from the value
32+
// specified in the config file specified by
33+
// GCLOUD_DIAGNOSTICS_CONFIG and the value of the
34+
// environment value GCLOUD_DEBUG_LOGLEVEL
35+
});
2736
var config = agent.private_.config_;
37+
// This assert tests that the value set by an environment variable
38+
// takes priority over the value in the config file and priority over
39+
// the value given to the config supplied to the start() method.
2840
// Set by env var
29-
assert.equal(config.logLevel, 4);
41+
assert.equal(config.logLevel, 1);
42+
// Set by env var
43+
assert.equal(config.serviceContext.service, 'a new name');
44+
// Set by env var
45+
assert.equal(config.serviceContext.version, 'a new version');
3046
// Set default + user config
3147
assert.equal(config.internal.registerDelayOnFetcherErrorSec, 300);
3248
// Set by user
@@ -37,6 +53,11 @@ describe('should respect environment variables', function() {
3753
assert.equal(config.description, 'test config');
3854
// In top level config not set by user
3955
assert.equal(config.breakpointUpdateIntervalSec, 10);
56+
// This assert verifies that the value specified in the config given
57+
// to the start() method takes priority over the value specified in
58+
// the config file.
59+
// In the config passed to the start() method
60+
assert.equal(config.testPriority, 'from the supplied config');
4061
});
4162

4263
});

test/standalone/test-env-log-level.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ var assert = require('assert');
2323
describe('should respect environment variables', function() {
2424
it('should respect GCLOUD_DEBUG_LOGLEVEL', function() {
2525
var agent = require('../../');
26+
agent.start();
2627
var logger = agent.private_.logger_;
2728
var STRING1 = 'jjjjjjjjjjjjjjjjjfjfjfjf';
2829
var STRING2 = 'kkkkkkkfkfkfkfkfkkffkkkk';

test/standalone/test-env-relative-repository-path.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ var h = require('../fixtures/a/hello.js');
2929
describe('repository relative paths', function() {
3030

3131
before(function(done) {
32+
agent.start();
3233
setTimeout(function() {
3334
// Wait for v8debug api to initialize.
3435
api = agent.private_.v8debug_;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* Copyright 2016 Google Inc. All Rights Reserved.
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+
'use strict';
18+
19+
var assert = require('assert');
20+
21+
describe('module', function() {
22+
it('should autostart', function(done) {
23+
var agent = require('../..');
24+
setTimeout(function() {
25+
assert.strictEqual(agent.start.wasSuccessful_, true);
26+
done();
27+
}, 2500);
28+
});
29+
});

test/standalone/test-module.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,23 @@
1919
var assert = require('assert');
2020
var Debuglet = require('../../lib/debuglet.js');
2121

22-
2322
describe('module', function() {
23+
var agent;
24+
25+
before(function() {
26+
agent = require('../..');
27+
agent.start();
28+
assert.strictEqual(agent.start.wasSuccessful_, true);
29+
});
2430

2531
it('should return the same agent on a second require', function() {
26-
var obj1 = require('../..');
27-
var obj2 = require('../..');
28-
assert(obj1 === obj2);
32+
var obj = require('../..');
33+
obj.start();
34+
assert(agent === obj);
2935
});
3036

3137
// Some tests depend on this private property.
3238
it('should have a debuglet as the private property', function() {
33-
var agent = require('../..');
3439
assert(agent.private_);
3540

3641
// The private_ property needs to be a debuglet.

test/test-debugletapi.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,13 @@ nock.disableNetConnect();
4646

4747
describe('Debuglet API', function() {
4848

49-
var debugletapi = new DebugletApi('Test debuglet');
49+
var debugletapi = new DebugletApi({
50+
description: 'Test debuglet',
51+
serviceContext: {
52+
service: 'TestDebugletName',
53+
version: 'TestDebugletVersion'
54+
}
55+
});
5056

5157
it('should return an instance when constructed', function() {
5258
assert.ok(debugletapi);
@@ -56,6 +62,14 @@ describe('Debuglet API', function() {
5662
assert.equal(debugletapi.descriptor_, 'Test debuglet');
5763
});
5864

65+
it('should have correct service name', function() {
66+
assert.equal(debugletapi.serviceName_, 'TestDebugletName');
67+
});
68+
69+
it('should have correct service version', function() {
70+
assert.equal(debugletapi.serviceVersion_, 'TestDebugletVersion');
71+
});
72+
5973
it('should acquire the project number during init', function(done) {
6074
debugletapi.init('uid123', { warn: function() {} }, function(err, project) {
6175
assert(!err);

0 commit comments

Comments
 (0)