@google-cloud/profiler 5.0.0 → 5.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,80 @@
1
+ import { GoogleAuthOptions } from '@google-cloud/common';
2
+ export interface Config extends GoogleAuthOptions {
3
+ /**
4
+ * The API endpoint of the service used to make requests.
5
+ * Defaults to `cloudprofiler.googleapis.com`.
6
+ */
7
+ apiEndpoint?: string;
8
+ projectId?: string;
9
+ logLevel?: number;
10
+ serviceContext?: {
11
+ service?: string;
12
+ version?: string;
13
+ };
14
+ instance?: string;
15
+ zone?: string;
16
+ disableTime?: boolean;
17
+ disableHeap?: boolean;
18
+ timeIntervalMicros?: number;
19
+ heapIntervalBytes?: number;
20
+ heapMaxStackDepth?: number;
21
+ ignoreHeapSamplesPath?: string;
22
+ backoffMultiplier?: number;
23
+ initialBackoffMillis?: number;
24
+ backoffCapMillis?: number;
25
+ serverBackoffCapMillis?: number;
26
+ localProfilingPeriodMillis?: number;
27
+ localLogPeriodMillis?: number;
28
+ localTimeDurationMillis?: number;
29
+ sourceMapSearchPath?: string[];
30
+ disableSourceMaps?: boolean;
31
+ }
32
+ export interface LocalConfig extends GoogleAuthOptions {
33
+ apiEndpoint: string;
34
+ projectId?: string;
35
+ logLevel: number;
36
+ serviceContext: {
37
+ service: string;
38
+ version?: string;
39
+ };
40
+ instance?: string;
41
+ zone?: string;
42
+ disableTime: boolean;
43
+ disableHeap: boolean;
44
+ timeIntervalMicros: number;
45
+ heapIntervalBytes: number;
46
+ heapMaxStackDepth: number;
47
+ ignoreHeapSamplesPath: string;
48
+ initialBackoffMillis: number;
49
+ backoffCapMillis: number;
50
+ backoffMultiplier: number;
51
+ serverBackoffCapMillis: number;
52
+ localProfilingPeriodMillis: number;
53
+ localLogPeriodMillis: number;
54
+ localTimeDurationMillis: number;
55
+ sourceMapSearchPath: string[];
56
+ disableSourceMaps: boolean;
57
+ }
58
+ export interface ProfilerConfig extends LocalConfig {
59
+ projectId: string;
60
+ }
61
+ export declare const defaultConfig: {
62
+ logLevel: number;
63
+ serviceContext: {};
64
+ disableHeap: boolean;
65
+ disableTime: boolean;
66
+ timeIntervalMicros: number;
67
+ heapIntervalBytes: number;
68
+ heapMaxStackDepth: number;
69
+ ignoreHeapSamplesPath: string;
70
+ initialBackoffMillis: number;
71
+ backoffCapMillis: number;
72
+ backoffMultiplier: number;
73
+ apiEndpoint: string;
74
+ serverBackoffCapMillis: number;
75
+ localProfilingPeriodMillis: number;
76
+ localLogPeriodMillis: number;
77
+ localTimeDurationMillis: number;
78
+ sourceMapSearchPath: string[];
79
+ disableSourceMaps: boolean;
80
+ };
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ // Copyright 2017 Google LLC
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
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.defaultConfig = void 0;
17
+ const parse_duration_1 = require("parse-duration");
18
+ // Default values for configuration for a profiler.
19
+ exports.defaultConfig = {
20
+ logLevel: 2,
21
+ serviceContext: {},
22
+ disableHeap: false,
23
+ disableTime: false,
24
+ timeIntervalMicros: 1000,
25
+ heapIntervalBytes: 512 * 1024,
26
+ heapMaxStackDepth: 64,
27
+ ignoreHeapSamplesPath: '@google-cloud/profiler',
28
+ initialBackoffMillis: 60 * 1000,
29
+ backoffCapMillis: (0, parse_duration_1.default)('1h'),
30
+ backoffMultiplier: 1.3,
31
+ apiEndpoint: 'cloudprofiler.googleapis.com',
32
+ // This is the largest duration for setTimeout which does not cause it to
33
+ // run immediately.
34
+ // https://nodejs.org/dist/latest-v9.x/docs/api/timers.html#timers_settimeout_callback_delay_args.
35
+ serverBackoffCapMillis: 2147483647,
36
+ localProfilingPeriodMillis: 1000,
37
+ localLogPeriodMillis: 10000,
38
+ localTimeDurationMillis: 1000,
39
+ sourceMapSearchPath: [process.cwd()],
40
+ disableSourceMaps: false,
41
+ };
42
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":";AAAA,4BAA4B;AAC5B,EAAE;AACF,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,kDAAkD;AAClD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;;AAGjC,mDAA2C;AAiK3C,mDAAmD;AACtC,QAAA,aAAa,GAAG;IAC3B,QAAQ,EAAE,CAAC;IACX,cAAc,EAAE,EAAE;IAClB,WAAW,EAAE,KAAK;IAClB,WAAW,EAAE,KAAK;IAClB,kBAAkB,EAAE,IAAI;IACxB,iBAAiB,EAAE,GAAG,GAAG,IAAI;IAC7B,iBAAiB,EAAE,EAAE;IACrB,qBAAqB,EAAE,wBAAwB;IAC/C,oBAAoB,EAAE,EAAE,GAAG,IAAI;IAC/B,gBAAgB,EAAE,IAAA,wBAAa,EAAC,IAAI,CAAC;IACrC,iBAAiB,EAAE,GAAG;IACtB,WAAW,EAAE,8BAA8B;IAE3C,yEAAyE;IACzE,mBAAmB;IACnB,kGAAkG;IAClG,sBAAsB,EAAE,UAAU;IAElC,0BAA0B,EAAE,IAAI;IAChC,oBAAoB,EAAE,KAAK;IAC3B,uBAAuB,EAAE,IAAI;IAC7B,mBAAmB,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;IACpC,iBAAiB,EAAE,KAAK;CACzB,CAAC"}
@@ -0,0 +1,36 @@
1
+ import * as semver from 'semver';
2
+ import { Config } from './config';
3
+ import { Profiler } from './profiler';
4
+ /**
5
+ * Returns true if the version passed in satifised version requirements
6
+ * specified in the profiler's package.json.
7
+ *
8
+ * Exported for testing.
9
+ */
10
+ export declare function nodeVersionOkay(version: string | semver.SemVer): boolean;
11
+ /**
12
+ * Initializes the config, and starts heap profiler if the heap profiler is
13
+ * needed. Returns a profiler if creation is successful. Otherwise, returns
14
+ * rejected promise.
15
+ */
16
+ export declare function createProfiler(config?: Config): Promise<Profiler>;
17
+ /**
18
+ * Starts the profiling agent and returns a promise.
19
+ * If any error is encountered when configuring the profiler the promise will
20
+ * be rejected. Resolves when profiling is started.
21
+ *
22
+ * config - Config describing configuration for profiling.
23
+ *
24
+ * @example
25
+ * profiler.start();
26
+ *
27
+ * @example
28
+ * profiler.start(config);
29
+ *
30
+ */
31
+ export declare function start(config?: Config): Promise<void>;
32
+ /**
33
+ * For debugging purposes. Collects profiles and discards the collected
34
+ * profiles.
35
+ */
36
+ export declare function startLocal(config?: Config): Promise<void>;
@@ -0,0 +1,248 @@
1
+ "use strict";
2
+ // Copyright 2017 Google LLC
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
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.startLocal = exports.start = exports.createProfiler = exports.nodeVersionOkay = void 0;
17
+ const delay_1 = require("delay");
18
+ const extend = require("extend");
19
+ const fs = require("fs");
20
+ const gcpMetadata = require("gcp-metadata");
21
+ const pprof_1 = require("pprof");
22
+ const semver = require("semver");
23
+ const config_1 = require("./config");
24
+ const logger_1 = require("./logger");
25
+ const profiler_1 = require("./profiler");
26
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
27
+ const pjson = require('../../package.json');
28
+ const serviceRegex = /^[a-z0-9]([-a-z0-9_.]{0,253}[a-z0-9])?$/;
29
+ function hasService(config) {
30
+ return (config.serviceContext !== undefined &&
31
+ typeof config.serviceContext.service === 'string');
32
+ }
33
+ function hasProjectId(config) {
34
+ return typeof config.projectId === 'string';
35
+ }
36
+ /**
37
+ * Sets unset values in the configuration to the value retrieved from
38
+ * environment variables or specified in defaultConfig.
39
+ * Throws error if value that must be set cannot be initialized.
40
+ */
41
+ function initConfigLocal(config) {
42
+ const envConfig = {
43
+ projectId: process.env.GCLOUD_PROJECT,
44
+ serviceContext: {
45
+ service: process.env.GAE_SERVICE || process.env.K_SERVICE,
46
+ version: process.env.GAE_VERSION || process.env.K_REVISION,
47
+ },
48
+ };
49
+ if (process.env.GCLOUD_PROFILER_LOGLEVEL !== undefined) {
50
+ const envLogLevel = Number(process.env.GCLOUD_PROFILER_LOGLEVEL);
51
+ if (!isNaN(envLogLevel)) {
52
+ envConfig.logLevel = envLogLevel;
53
+ }
54
+ }
55
+ let envSetConfig = {};
56
+ const configPath = process.env.GCLOUD_PROFILER_CONFIG;
57
+ if (configPath) {
58
+ let envSetConfigBuf;
59
+ try {
60
+ envSetConfigBuf = fs.readFileSync(configPath);
61
+ }
62
+ catch (e) {
63
+ throw Error(`Could not read GCLOUD_PROFILER_CONFIG ${configPath}: ${e}`);
64
+ }
65
+ try {
66
+ envSetConfig = JSON.parse(envSetConfigBuf.toString());
67
+ }
68
+ catch (e) {
69
+ throw Error(`Could not parse GCLOUD_PROFILER_CONFIG ${configPath}: ${e}`);
70
+ }
71
+ }
72
+ const mergedUserConfigs = extend(true, {}, envSetConfig, envConfig, config);
73
+ if (Array.isArray(mergedUserConfigs.sourceMapSearchPath) &&
74
+ mergedUserConfigs.sourceMapSearchPath.length === 0 &&
75
+ !mergedUserConfigs.disableSourceMaps) {
76
+ throw new Error('serviceMapSearchPath is an empty array. Use disableSourceMaps to' +
77
+ ' disable source map support instead.');
78
+ }
79
+ const mergedConfig = extend(true, {}, config_1.defaultConfig, mergedUserConfigs);
80
+ if (!hasService(mergedConfig)) {
81
+ throw new Error('Service must be specified in the configuration');
82
+ }
83
+ if (!serviceRegex.test(mergedConfig.serviceContext.service)) {
84
+ throw new Error(`Service ${mergedConfig.serviceContext.service} does not match regular expression "${serviceRegex.toString()}"`);
85
+ }
86
+ return mergedConfig;
87
+ }
88
+ /**
89
+ * Sets unset values in the configuration which can be retrieved from GCP
90
+ * metadata.
91
+ */
92
+ async function initConfigMetadata(config) {
93
+ const logger = (0, logger_1.createLogger)(config.logLevel);
94
+ const getMetadataProperty = async (f, field) => {
95
+ try {
96
+ return await f(field);
97
+ }
98
+ catch (e) {
99
+ logger.debug(`Failed to fetch ${field} from metadata: ${e}`);
100
+ }
101
+ return undefined;
102
+ };
103
+ if (!config.projectId || !config.zone || !config.instance) {
104
+ const [projectId, instance, zone] = await Promise.all([
105
+ getMetadataProperty(gcpMetadata.project, 'project-id'),
106
+ getMetadataProperty(gcpMetadata.instance, 'name'),
107
+ getMetadataProperty(gcpMetadata.instance, 'zone'),
108
+ ]);
109
+ if (!config.zone && zone) {
110
+ config.zone = zone.substring(zone.lastIndexOf('/') + 1);
111
+ }
112
+ if (!config.instance && instance) {
113
+ config.instance = instance;
114
+ }
115
+ if (!config.projectId && projectId) {
116
+ config.projectId = projectId;
117
+ }
118
+ }
119
+ if (!hasProjectId(config)) {
120
+ throw new Error('Project ID must be specified in the configuration');
121
+ }
122
+ return config;
123
+ }
124
+ /**
125
+ * Returns true if the version passed in satifised version requirements
126
+ * specified in the profiler's package.json.
127
+ *
128
+ * Exported for testing.
129
+ */
130
+ function nodeVersionOkay(version) {
131
+ // Coerce version if possible, to remove any pre-release, alpha, beta, etc
132
+ // tags.
133
+ version = semver.coerce(version) || version;
134
+ return semver.satisfies(version, pjson.engines.node);
135
+ }
136
+ exports.nodeVersionOkay = nodeVersionOkay;
137
+ /**
138
+ * Initializes the config, and starts heap profiler if the heap profiler is
139
+ * needed. Returns a profiler if creation is successful. Otherwise, returns
140
+ * rejected promise.
141
+ */
142
+ async function createProfiler(config = {}) {
143
+ if (!nodeVersionOkay(process.version)) {
144
+ throw new Error(`Could not start profiler: node version ${process.version}` +
145
+ ` does not satisfies "${pjson.engines.node}"` +
146
+ '\nSee https://github.com/googleapis/cloud-profiler-nodejs#prerequisites' +
147
+ ' for details.');
148
+ }
149
+ const localConfig = initConfigLocal(config);
150
+ // Start the heap profiler if profiler config does not indicate heap profiling
151
+ // is disabled. This must be done before any asynchronous calls are made so
152
+ // all memory allocations made after start() is called can be captured.
153
+ if (!localConfig.disableHeap) {
154
+ pprof_1.heap.start(localConfig.heapIntervalBytes, localConfig.heapMaxStackDepth);
155
+ }
156
+ let profilerConfig;
157
+ try {
158
+ profilerConfig = await initConfigMetadata(localConfig);
159
+ }
160
+ catch (err) {
161
+ pprof_1.heap.stop();
162
+ throw err;
163
+ }
164
+ return new profiler_1.Profiler(profilerConfig);
165
+ }
166
+ exports.createProfiler = createProfiler;
167
+ /**
168
+ * Starts the profiling agent and returns a promise.
169
+ * If any error is encountered when configuring the profiler the promise will
170
+ * be rejected. Resolves when profiling is started.
171
+ *
172
+ * config - Config describing configuration for profiling.
173
+ *
174
+ * @example
175
+ * profiler.start();
176
+ *
177
+ * @example
178
+ * profiler.start(config);
179
+ *
180
+ */
181
+ async function start(config = {}) {
182
+ const profiler = await createProfiler(config);
183
+ profiler.start();
184
+ }
185
+ exports.start = start;
186
+ /**
187
+ * For debugging purposes. Collects profiles and discards the collected
188
+ * profiles.
189
+ */
190
+ async function startLocal(config = {}) {
191
+ const profiler = await createProfiler(config);
192
+ // Set up periodic logging.
193
+ const logger = (0, logger_1.createLogger)(config.logLevel);
194
+ let heapProfileCount = 0;
195
+ let timeProfileCount = 0;
196
+ let prevLogTime = Date.now();
197
+ setInterval(() => {
198
+ const curTime = Date.now();
199
+ const { rss, heapTotal, heapUsed } = process.memoryUsage();
200
+ const debugInfo = [
201
+ new Date().toISOString(),
202
+ 'rss',
203
+ (rss / (1024 * 1024)).toFixed(3),
204
+ 'MiB,',
205
+ 'heap total',
206
+ (heapTotal / (1024 * 1024)).toFixed(3),
207
+ 'MiB,',
208
+ 'heap used',
209
+ (heapUsed / (1024 * 1024)).toFixed(3),
210
+ 'MiB,',
211
+ 'heap profile collection rate',
212
+ ((heapProfileCount * 1000) / (curTime - prevLogTime)).toFixed(3),
213
+ 'profiles/s,',
214
+ 'time profile collection rate',
215
+ ((timeProfileCount * 1000) / (curTime - prevLogTime)).toFixed(3),
216
+ 'profiles/s',
217
+ ].map(v => v + '');
218
+ logger.debug(debugInfo.join(' '));
219
+ heapProfileCount = 0;
220
+ timeProfileCount = 0;
221
+ prevLogTime = curTime;
222
+ }, profiler.config.localLogPeriodMillis);
223
+ // Periodic profiling
224
+ setInterval(async () => {
225
+ if (!config.disableHeap) {
226
+ await profiler.profile({
227
+ name: 'Heap-Profile' + new Date(),
228
+ profileType: 'HEAP',
229
+ });
230
+ heapProfileCount++;
231
+ }
232
+ await (0, delay_1.default)(profiler.config.localProfilingPeriodMillis / 2);
233
+ if (!config.disableTime) {
234
+ await profiler.profile({
235
+ name: 'Time-Profile' + new Date(),
236
+ profileType: 'WALL',
237
+ duration: profiler.config.localTimeDurationMillis.toString() + 'ms',
238
+ });
239
+ timeProfileCount++;
240
+ }
241
+ }, profiler.config.localProfilingPeriodMillis);
242
+ }
243
+ exports.startLocal = startLocal;
244
+ // If the module was --require'd from the command line, start the agent.
245
+ if (module.parent && module.parent.id === 'internal/preload') {
246
+ start();
247
+ }
248
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export declare class Logger {
2
+ readonly level?: number | undefined;
3
+ private log;
4
+ private severityThreshold;
5
+ constructor(level?: number | undefined);
6
+ debug(msg: string): void;
7
+ info(msg: string): void;
8
+ warn(msg: string): void;
9
+ error(msg: string): void;
10
+ private toOneLine;
11
+ }
12
+ export declare function createLogger(level?: number): Logger;
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ // Copyright 2017 Google LLC
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
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.createLogger = exports.Logger = void 0;
17
+ /* eslint-disable @typescript-eslint/no-explicit-any */
18
+ const config_1 = require("./config");
19
+ const logging_min_1 = require("@google-cloud/logging-min");
20
+ const logging = new logging_min_1.Logging();
21
+ // migrating from 'console-log-level' package we keep
22
+ // min and max log levels numeric interface used there
23
+ const [MIN_LEVEL, MAX_LEVEL] = [0, 4];
24
+ logging.setProjectId().catch(err => {
25
+ console.error(`failed to set logging project id ${err}`);
26
+ });
27
+ logging.setDetectedResource().catch(err => {
28
+ console.error(`failed to discover resource metadata ${err}`);
29
+ });
30
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
31
+ const pjson = require('../../package.json');
32
+ class Logger {
33
+ constructor(level) {
34
+ this.level = level;
35
+ if (level === undefined) {
36
+ level = config_1.defaultConfig.logLevel;
37
+ }
38
+ if (level < MIN_LEVEL) {
39
+ level = MIN_LEVEL;
40
+ }
41
+ else if (level > MAX_LEVEL) {
42
+ level = MAX_LEVEL;
43
+ }
44
+ this.severityThreshold = level;
45
+ this.log = logging.logSync(pjson.name);
46
+ }
47
+ debug(msg) {
48
+ if (this.severityThreshold > 3) {
49
+ this.log.debug(this.log.entry(this.toOneLine(msg)));
50
+ }
51
+ }
52
+ info(msg) {
53
+ if (this.severityThreshold > 2) {
54
+ this.log.info(this.log.entry(this.toOneLine(msg)));
55
+ }
56
+ }
57
+ warn(msg) {
58
+ if (this.severityThreshold > 1) {
59
+ this.log.warning(this.log.entry(this.toOneLine(msg)));
60
+ }
61
+ }
62
+ error(msg) {
63
+ if (this.severityThreshold > 0) {
64
+ this.log.error(this.log.entry(this.toOneLine(msg)));
65
+ }
66
+ }
67
+ toOneLine(msg) {
68
+ const temp = msg.replace('\r\n', '\\r\\n');
69
+ return temp.replace('\n', '\\n');
70
+ }
71
+ }
72
+ exports.Logger = Logger;
73
+ function createLogger(level) {
74
+ return new Logger(level);
75
+ }
76
+ exports.createLogger = createLogger;
77
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,155 @@
1
+ import { ServiceObject } from '@google-cloud/common';
2
+ import { ProfilerConfig } from './config';
3
+ /**
4
+ * Interface for deployment field of RequestProfile. Profiles with matching
5
+ * deployments will be grouped together.
6
+ * Used as body of request when creating profile using the profiler API.
7
+ *
8
+ * Public for testing.
9
+ */
10
+ export interface Deployment {
11
+ projectId?: string;
12
+ target?: string;
13
+ labels?: {
14
+ zone?: string;
15
+ version?: string;
16
+ language: string;
17
+ };
18
+ }
19
+ /**
20
+ * Interface for body of response from profiler API when creating
21
+ * profile and used as body of request to profiler API when
22
+ * uploading a profile.
23
+ *
24
+ * Public for testing.
25
+ */
26
+ export interface RequestProfile {
27
+ name: string;
28
+ profileType?: string;
29
+ duration?: string;
30
+ profileBytes?: string;
31
+ deployment?: Deployment;
32
+ labels?: {
33
+ instance?: string;
34
+ };
35
+ }
36
+ /**
37
+ * @return if the backoff duration can be parsed, then the backoff duration in
38
+ * ms, otherwise undefined.
39
+ *
40
+ * Public for testing.
41
+ */
42
+ export declare function parseBackoffDuration(backoffMessage: string): number | undefined;
43
+ /**
44
+ * Error constructed from HTTP server response which indicates backoff.
45
+ */
46
+ export declare class BackoffResponseError extends Error {
47
+ readonly backoffMillis: number;
48
+ constructor(message: string | undefined, backoffMillis: number);
49
+ }
50
+ /**
51
+ * Class which tracks how long to wait before the next retry and can be
52
+ * used to get this backoff.
53
+ */
54
+ export declare class Retryer {
55
+ readonly initialBackoffMillis: number;
56
+ readonly backoffCapMillis: number;
57
+ readonly backoffMultiplier: number;
58
+ private nextBackoffMillis;
59
+ private random;
60
+ constructor(initialBackoffMillis: number, backoffCapMillis: number, backoffMultiplier: number, random?: () => number);
61
+ getBackoff(): number;
62
+ reset(): void;
63
+ }
64
+ /**
65
+ * Polls profiler server for instructions on behalf of a task and
66
+ * collects and uploads profiles as requested.
67
+ *
68
+ * If heap profiling is enabled, the heap profiler must be enabled before heap
69
+ * profiles can be collected.
70
+ */
71
+ export declare class Profiler extends ServiceObject {
72
+ private logger;
73
+ private profileLabels;
74
+ private deployment;
75
+ private profileTypes;
76
+ private retryer;
77
+ private sourceMapper;
78
+ private baseApiUrl;
79
+ config: ProfilerConfig;
80
+ constructor(config: ProfilerConfig);
81
+ /**
82
+ * Starts an endless loop to poll profiler server for instructions, and
83
+ * collects and uploads profiles as requested.
84
+ * If there is a problem when collecting a profile or uploading a profile to
85
+ * profiler server, this problem will be logged at the error level and
86
+ * otherwise ignored.
87
+ * If there is a problem polling profiler server for instructions
88
+ * on the type of profile to be collected, this problem will be logged at the
89
+ * error level and getting profile type will be retried.
90
+ */
91
+ start(): Promise<void>;
92
+ /**
93
+ * Endlessly polls the profiler server for instructions, and collects and
94
+ * uploads profiles as requested.
95
+ */
96
+ runLoop(): Promise<void>;
97
+ /**
98
+ * Waits for profiler server to tell it to collect a profile, then collects
99
+ * a profile and uploads it.
100
+ *
101
+ * @return time, in ms, to wait before asking profiler server again about
102
+ * collecting another profile.
103
+ */
104
+ collectProfile(): Promise<number>;
105
+ /**
106
+ * Talks to profiler server, which hangs until server indicates
107
+ * job should be profiled and then indicates what type of profile should
108
+ * be collected.
109
+ *
110
+ * If any problem is encountered, an error will be thrown.
111
+ *
112
+ * @return a RequestProfile specifying which type of profile should be
113
+ * collected and other information needed to collect and upload a profile of
114
+ * the specified type.
115
+ *
116
+ * TODO (issue #28): right now, this call could hang for up to an hour when
117
+ * this method is the only thing on the event loop, keeping the program open
118
+ * even when all work is done. Should expose the ability to cancel the http
119
+ * request made here, and then determine when to cancel this request.
120
+ *
121
+ * Public to allow for testing.
122
+ */
123
+ createProfile(): Promise<RequestProfile>;
124
+ /**
125
+ * Collects a profile of the type specified by the profileType field of prof.
126
+ * If any problem is encountered, like a problem collecting or uploading the
127
+ * profile, a message will be logged, and the error will otherwise be ignored.
128
+ *
129
+ * Public to allow for testing.
130
+ */
131
+ profileAndUpload(prof: RequestProfile): Promise<void>;
132
+ /**
133
+ * Collects a profile of the type specified by profileType field of prof.
134
+ * If any problem is encountered, for example the profileType is not
135
+ * recognized or profiling is disabled for the specified profileType, an
136
+ * error will be thrown.
137
+ *
138
+ * Public to allow for testing.
139
+ */
140
+ profile(prof: RequestProfile): Promise<RequestProfile>;
141
+ /**
142
+ * Collects a time profile, converts profile to compressed, base64 encoded
143
+ * string, and puts this string in profileBytes field of prof.
144
+ *
145
+ * Public to allow for testing.
146
+ */
147
+ writeTimeProfile(prof: RequestProfile): Promise<RequestProfile>;
148
+ /**
149
+ * Collects a heap profile, converts profile to compressed, base64 encoded
150
+ * string, and adds profileBytes field to prof with this string.
151
+ *
152
+ * Public to allow for testing.
153
+ */
154
+ writeHeapProfile(prof: RequestProfile): Promise<RequestProfile>;
155
+ }