Skip to content
This repository has been archived by the owner on Jan 5, 2019. It is now read-only.

Commit

Permalink
Merge pull request #43 from taskcluster/config-without-auth
Browse files Browse the repository at this point in the history
Configuration without using tc credentials, so we can bootstrap auth
  • Loading branch information
imbstack authored Aug 23, 2016
2 parents e17a682 + 03d71a6 commit c1ac185
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 28 deletions.
84 changes: 61 additions & 23 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,48 +8,86 @@ let Statsum = require('statsum');
let MockMonitor = require('./mockmonitor');
let Monitor = require('./monitor');

/**
* Create a new monitor, given options:
* {
* project: '...',
* patchGlobal: true,
* reportStatsumErrors: true,
* resourceInterval: 10 * 1000,
* crashTimeout: 5 * 1000,
* mock: false,
* credentials: {
* clientId: '...',
* accessToken: '...',
* },
* // If credentials aren't given, you must supply:
* statsumToken: async (project) => {token, expires, baseUrl}
* sentryDNS: async (project) => {dsn: {secret: '...'}, expires}
* }
*/
async function monitor(options) {
assert(options.credentials, 'Must provide taskcluster credentials!');
assert(options.project, 'Must provide a project name!');
let opts = _.defaults(options, {
options = _.defaults({}, options, {
patchGlobal: true,
reportStatsumErrors: true,
resourceInterval: 10 * 1000,
crashTimeout: 5 * 1000,
mock: false,
});
assert(options.credentials || options.statsumToken && options.sentryDSN ||
options.mock,
'Must provide taskcluster credentials or sentryDSN and statsumToken');
assert(options.project, 'Must provide a project name!');

if (opts.mock) {
return new MockMonitor(opts);
// Return mock monitor, if mocking
if (options.mock) {
return new MockMonitor(options);
}

let authClient = new taskcluster.Auth({
credentials: opts.credentials,
});

let statsumClient = new Statsum(
project => authClient.statsumToken(project),
{
project: opts.project,
emitErrors: opts.reportStatsumErrors,
// Find functions for statsum and sentry
let statsumToken = options.statsumToken;
let sentryDSN = options.sentryDSN;
// Wrap statsumToken in function if it's not a function
if (statsumToken && !(statsumToken instanceof Function)) {
statsumToken = () => options.statsumToken;
}
// Wrap sentryDSN in function if it's not a function
if (sentryDSN && !(sentryDSN instanceof Function)) {
sentryDSN = () => options.sentryDSN;
}
// Use taskcluster credentials for statsumToken and sentryDSN, if given
if (options.credentials) {
let auth = new taskcluster.Auth({
credentials: options.credentials,
});
if (!statsumToken) {
statsumToken = project => auth.statsumToken(project);
}
if (!sentryDSN) {
sentryDSN = project => auth.sentryDSN(project);
}
);
}

let sentry = Promise.resolve({client: null, expires: new Date(0)});
// Create statsum client
let statsum = new Statsum(statsumToken, {
project: options.project,
emitErrors: options.reportStatsumErrors,
});

let m = new Monitor(authClient, sentry, statsumClient, opts);
let m = new Monitor(sentryDSN, null, statsum, options);

if (opts.reportStatsumErrors) {
statsumClient.on('error', err => m.reportError(err, 'warning'));
if (options.reportStatsumErrors) {
statsum.on('error', err => m.reportError(err, 'warning'));
}

if (opts.patchGlobal) {
if (options.patchGlobal) {
process.on('uncaughtException', async (err) => {
console.log('Uncaught Exception! Attempting to report to Sentry and crash.');
console.log(err.stack);
setTimeout(() => {
console.log('Failed to report error to Sentry after timeout!');
process.exit(1);
}, opts.crashTimeout);
}, options.crashTimeout);
try {
await m.reportError(err, 'fatal', {});
console.log('Succesfully reported error to Sentry.');
Expand All @@ -67,8 +105,8 @@ async function monitor(options) {
});
}

if (opts.process) {
utils.resources(m, opts.process, opts.resourceInterval);
if (options.process) {
utils.resources(m, options.process, options.resourceInterval);
}

return m;
Expand Down
11 changes: 6 additions & 5 deletions src/monitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ let utils = require('./utils');

class Monitor {

constructor(authClient, sentry, statsumClient, opts) {
constructor(sentryDSN, sentry, statsumClient, opts) {
this._opts = opts;
this._auth = authClient;
this._sentry = sentry; // This must be a Promise that resolves to {client, expires}
this._sentryDSN = sentryDSN;
// This must be a Promise that resolves to {client, expires}
this._sentry = sentry || Promise.resolve({client: null, expires: new Date(0)});
this._statsum = statsumClient;
this._resourceInterval = null;
}
Expand All @@ -21,7 +22,7 @@ class Monitor {
}
this._sentry = this._sentry.then(async (sentry) => {
if (!sentry.expires || Date.parse(sentry.expires) <= Date.now()) {
let sentryInfo = await this._auth.sentryDSN(this._opts.project);
let sentryInfo = await this._sentryDSN(this._opts.project);
return {
client: new raven.Client(sentryInfo.dsn.secret),
expires: sentryInfo.expires,
Expand Down Expand Up @@ -86,7 +87,7 @@ class Monitor {
let newopts = _.cloneDeep(this._opts);
newopts.prefix = (this._opts.prefix || '') + '.' + prefix;
return new Monitor(
this._auth,
this._sentryDSN,
this._sentry,
this._statsum.prefix(prefix),
newopts
Expand Down

0 comments on commit c1ac185

Please sign in to comment.