Skip to content

Commit

Permalink
refactor: ts conversion of tracing-policy
Browse files Browse the repository at this point in the history
  • Loading branch information
kjin committed Sep 19, 2017
1 parent ce34e55 commit 9ab0775
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 61 deletions.
4 changes: 3 additions & 1 deletion src/trace-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
*/

'use strict';

import * as TracingPolicy from './tracing-policy';

var cls = require('./cls'/*.js*/);
var constants = require('./constants'/*.js*/);
var is = require('is');
Expand All @@ -23,7 +26,6 @@ var util = require('./util'/*.js*/);
var Trace = require('./trace'/*.js*/);
var SpanData = require('./span-data'/*.js*/);
var uuid = require('uuid');
var TracingPolicy = require('./tracing-policy'/*.js*/);
var semver = require('semver');

var ROOT_SPAN_STACK_OFFSET = semver.satisfies(process.version, '>=8') ? 0 : 2;
Expand Down
113 changes: 64 additions & 49 deletions src/tracing-policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,65 +14,80 @@
* limitations under the License.
*/

'use strict';

function RateLimiterPolicy(samplesPerSecond) {
if (samplesPerSecond > 1000) {
samplesPerSecond = 1000;
}
this.traceWindow = 1000 / samplesPerSecond;
this.nextTraceStart = Date.now();
/**
* An object that determines whether a request should be traced.
*/
export interface Policy {
shouldTrace(dateMillis: number, url: string): boolean;
}

RateLimiterPolicy.prototype.shouldTrace = function(dateMillis) {
if (dateMillis < this.nextTraceStart) {
return false;
export class RateLimiterPolicy implements Policy {
private traceWindow: number;
private nextTraceStart: number;

constructor(samplesPerSecond: number) {
if (samplesPerSecond > 1000) {
samplesPerSecond = 1000;
}
this.traceWindow = 1000 / samplesPerSecond;
this.nextTraceStart = Date.now();
}
this.nextTraceStart = dateMillis + this.traceWindow;
return true;
};

function FilterPolicy(basePolicy, filterUrls) {
this.basePolicy = basePolicy;
this.filterUrls = filterUrls;
shouldTrace(dateMillis: number): boolean {
if (dateMillis < this.nextTraceStart) {
return false;
}
this.nextTraceStart = dateMillis + this.traceWindow;
return true;
}
}

FilterPolicy.prototype.matches = function(url) {
return this.filterUrls.some(function(candidate) {
return (typeof candidate === 'string' && candidate === url) ||
url.match(candidate);
});
};
export class FilterPolicy implements Policy {
constructor(
private basePolicy: Policy,
private filterUrls: (string | RegExp)[]
) {}

FilterPolicy.prototype.shouldTrace = function(dataMillis, url) {
return !this.matches(url) && this.basePolicy.shouldTrace(dataMillis, url);
};
private matches(url: string) {
return this.filterUrls.some((candidate) => {
return (typeof candidate === 'string' && candidate === url) ||
!!url.match(candidate);
});
}

function TraceAllPolicy() {}
shouldTrace(dateMillis: number, url: string) {
return !this.matches(url) && this.basePolicy.shouldTrace(dateMillis, url);
}
}

TraceAllPolicy.prototype.shouldTrace = function() { return true; };
export class TraceAllPolicy implements Policy {
shouldTrace() {
return true;
}
}

function TraceNonePolicy() {}
export class TraceNonePolicy implements Policy {
shouldTrace() {
return false;
}
}

TraceNonePolicy.prototype.shouldTrace = function() { return false; };
export interface TracePolicyOptions {
samplingRate: number;
ignoreUrls?: (string | RegExp)[];
}

module.exports = {
TraceAllPolicy: TraceAllPolicy,
TraceNonePolicy: TraceNonePolicy,
FilterPolicy: FilterPolicy,
createTracePolicy: function(config) {
var basePolicy;
if (config.samplingRate < 1) {
basePolicy = new TraceAllPolicy();
} else {
basePolicy = new RateLimiterPolicy(config.samplingRate);
}
if (config.ignoreUrls && config.ignoreUrls.length > 0) {
return new FilterPolicy(basePolicy, config.ignoreUrls);
} else {
return basePolicy;
}
// TODO(kjin): This could be a class as well.
export function createTracePolicy(config: TracePolicyOptions): Policy {
let basePolicy;
if (config.samplingRate < 1) {
basePolicy = new TraceAllPolicy();
} else {
basePolicy = new RateLimiterPolicy(config.samplingRate);
}
};

export default {};
if (config.ignoreUrls && config.ignoreUrls.length > 0) {
return new FilterPolicy(basePolicy, config.ignoreUrls);
} else {
return basePolicy;
}
}
6 changes: 4 additions & 2 deletions test/plugins/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ declare global {
}
}

import * as TracingPolicy from '../../src/tracing-policy';

var proxyquire = require('proxyquire');
// Monkeypatch gcp-metadata to not ask for retries at all.
proxyquire('gcp-metadata', {
Expand All @@ -42,7 +44,7 @@ if (semver.satisfies(process.version, '>=8') && process.env.GCLOUD_TRACE_NEW_CON
return oldIt.call(this, title, cls.createNamespace().bind(fn));
}, oldIt);
}
var tracePolicy = require('../../src/tracing-policy'/*.js*/);

var TraceWriter = require('../../src/trace-writer'/*.js*/);

var assert = require('assert');
Expand All @@ -62,7 +64,7 @@ shimmer.wrap(trace, 'start', function(original) {
enhancedDatabaseReporting: false,
ignoreTraceContext: false
});
testTraceAgent.policy_ = new tracePolicy.TraceAllPolicy();
testTraceAgent.policy_ = new TracingPolicy.TraceAllPolicy();
return result;
};
});
Expand Down
3 changes: 2 additions & 1 deletion test/plugins/test-trace-grpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@
*/
'use strict';

import * as TracingPolicy from '../../src/tracing-policy';

var assert = require('assert');
var cls = require('../../src/cls'/*.js*/);
var util = require('../../src/util'/*.js*/);
var constants = require('../../src/constants'/*.js*/);
var shimmer = require('shimmer');
var traceLabels = require('../../src/trace-labels'/*.js*/);
var TracingPolicy = require('../../src/tracing-policy'/*.js*/);
var common = require('./common'/*.js*/);

var versions = {
Expand Down
3 changes: 2 additions & 1 deletion test/test-trace-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@

'use strict';

import * as TracingPolicy from '../src/tracing-policy';

var assert = require('assert');
var cls = require('../src/cls'/*.js*/);
var common = require('./plugins/common'/*.js*/);
var EventEmitter = require('events');
var request = require('request');
var TraceAgent = require('../src/trace-api'/*.js*/);
var TracingPolicy = require('../src/tracing-policy'/*.js*/);
var TraceWriter = require('../src/trace-writer'/*.js*/);

var logger = require('@google-cloud/common').logger();
Expand Down
15 changes: 8 additions & 7 deletions test/test-trace-policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,33 +16,34 @@

'use strict';

import * as TracingPolicy from '../src/tracing-policy';

var assert = require('assert');
var tracingPolicy = require('../src/tracing-policy'/*.js*/);

describe('FilterPolicy', function() {
it('should not allow filtered urls', function() {
var policy = tracingPolicy.createTracePolicy({
var policy = TracingPolicy.createTracePolicy({
samplingRate: 0,
ignoreUrls: ['/_ah/health', /\/book*/]
});
assert(!policy.shouldTrace(null, '/_ah/health'));
assert(!policy.shouldTrace(null, '/book/test'));
assert(!policy.shouldTrace(0, '/_ah/health'));
assert(!policy.shouldTrace(0, '/book/test'));
});

it('should allow non-filtered urls', function() {
var policy = tracingPolicy.createTracePolicy({
var policy = TracingPolicy.createTracePolicy({
samplingRate: 0,
ignoreUrls: ['/_ah/health']
});
assert(policy.shouldTrace(null, '/_ah/background'));
assert(policy.shouldTrace(0, '/_ah/background'));
});
});

describe('RateLimiterPolicy', function() {
var tracesPerSecond = [10, 50, 150, 200, 500, 1000];
tracesPerSecond.forEach(function(traceCount) {
it('should throttle traces, ' + traceCount, function() {
var policy = tracingPolicy.createTracePolicy({samplingRate: traceCount});
var policy = TracingPolicy.createTracePolicy({samplingRate: traceCount});
testAllowedTraces(policy, traceCount);
});
});
Expand Down

0 comments on commit 9ab0775

Please sign in to comment.