Merge pull request #991 from balena-io/990-mixpanel-switch

Add a controlling variable for mixpanel reporting
This commit is contained in:
CameronDiver 2019-05-29 04:58:36 -07:00 committed by GitHub
commit 2ae71ab007
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 54 additions and 17 deletions

View File

@ -166,6 +166,10 @@ export const schemaTypes = {
type: PermissiveBoolean, type: PermissiveBoolean,
default: false, default: false,
}, },
mixpanelReport: {
type: PermissiveBoolean,
default: true,
},
// Function schema types // Function schema types
// The type should be the value that the promise resolves // The type should be the value that the promise resolves

View File

@ -190,6 +190,11 @@ export const schema = {
mutable: true, mutable: true,
removeIfNull: false, removeIfNull: false,
}, },
mixpanelReport: {
source: 'db',
mutable: true,
removeIfNull: false,
},
}; };
export type Schema = typeof schema; export type Schema = typeof schema;

View File

@ -129,6 +129,11 @@ export class DeviceConfig {
defaultValue: 'false', defaultValue: 'false',
rebootRequired: true, rebootRequired: true,
}, },
mixpanelReport: {
envVarName: 'SUPERVISOR_MIXPANEL_REPORT',
varType: 'bool',
defaultValue: 'true',
},
}; };
public static validKeys = [ public static validKeys = [

View File

@ -1,10 +1,10 @@
import * as Bluebird from 'bluebird';
import mask = require('json-mask'); import mask = require('json-mask');
import * as _ from 'lodash'; import * as _ from 'lodash';
import * as memoizee from 'memoizee'; import * as memoizee from 'memoizee';
import Mixpanel = require('mixpanel'); import Mixpanel = require('mixpanel');
import Config from './config';
import supervisorVersion = require('./lib/supervisor-version'); import supervisorVersion = require('./lib/supervisor-version');
export type EventTrackProperties = Dictionary<any>; export type EventTrackProperties = Dictionary<any>;
@ -14,6 +14,7 @@ interface InitArgs {
unmanaged: boolean; unmanaged: boolean;
mixpanelHost: { host: string; path: string } | null; mixpanelHost: { host: string; path: string } | null;
mixpanelToken: string; mixpanelToken: string;
config: Config;
} }
// The minimum amount of time to wait between sending // The minimum amount of time to wait between sending
@ -34,31 +35,45 @@ const mixpanelMask = [
export class EventTracker { export class EventTracker {
private defaultProperties: EventTrackProperties | null; private defaultProperties: EventTrackProperties | null;
private client: any; private client: any;
private isEnabled: boolean = true;
public constructor() { public constructor() {
this.client = null; this.client = null;
this.defaultProperties = null; this.defaultProperties = null;
} }
public init({ public async init({
unmanaged, unmanaged,
mixpanelHost, mixpanelHost,
mixpanelToken, mixpanelToken,
uuid, uuid,
}: InitArgs): Bluebird<void> { config,
return Bluebird.try(() => { }: InitArgs): Promise<void> {
this.defaultProperties = { this.defaultProperties = {
distinct_id: uuid, distinct_id: uuid,
uuid, uuid,
supervisorVersion, supervisorVersion,
}; };
if (unmanaged || mixpanelHost == null) { if (unmanaged || mixpanelHost == null) {
return; return;
}
this.client = Mixpanel.init(mixpanelToken, {
host: mixpanelHost.host,
path: mixpanelHost.path,
});
this.isEnabled = await config.get('mixpanelReport');
console.log(
`Mixpanel reporting is ${this.isEnabled ? 'enabled' : 'disabled'}`,
);
config.on('change', conf => {
const mixpanelReport = conf.mixpanelReport;
if (mixpanelReport != null && mixpanelReport !== this.isEnabled) {
this.isEnabled = mixpanelReport;
console.log(
`${mixpanelReport ? 'A' : 'Dea'}ctivating mixpanel reporting`,
);
} }
this.client = Mixpanel.init(mixpanelToken, {
host: mixpanelHost.host,
path: mixpanelHost.path,
});
}); });
} }
@ -79,7 +94,7 @@ export class EventTracker {
// Don't send potentially sensitive information, by using a whitelist // Don't send potentially sensitive information, by using a whitelist
properties = mask(properties, mixpanelMask); properties = mask(properties, mixpanelMask);
this.logEvent('Event:', event, JSON.stringify(properties)); this.logEvent('Event:', event, JSON.stringify(properties));
if (this.client == null) { if (this.client == null || !this.isEnabled) {
return; return;
} }

View File

@ -1,3 +1,5 @@
_ = require 'lodash'
EventEmitter = require 'events' EventEmitter = require 'events'
{ EventTracker } = require './event-tracker' { EventTracker } = require './event-tracker'
@ -64,7 +66,7 @@ module.exports = class Supervisor extends EventEmitter
# so we leave a trail of breadcrumbs in the logs in case runtime # so we leave a trail of breadcrumbs in the logs in case runtime
# fails to get to the first dashboard logs # fails to get to the first dashboard logs
console.log('Starting event tracker') console.log('Starting event tracker')
@eventTracker.init(conf) @eventTracker.init(_.assign({}, conf, { @config }))
.then => .then =>
console.log('Starting up api binder') console.log('Starting up api binder')
@apiBinder.initClient() @apiBinder.initClient()

View File

@ -45,6 +45,7 @@ testTarget1 = {
'SUPERVISOR_LOCAL_MODE': 'false' 'SUPERVISOR_LOCAL_MODE': 'false'
'SUPERVISOR_LOG_CONTROL': 'true' 'SUPERVISOR_LOG_CONTROL': 'true'
'SUPERVISOR_OVERRIDE_LOCK': 'false' 'SUPERVISOR_OVERRIDE_LOCK': 'false'
'SUPERVISOR_MIXPANEL_REPORT': 'true'
'SUPERVISOR_POLL_INTERVAL': '60000' 'SUPERVISOR_POLL_INTERVAL': '60000'
'SUPERVISOR_VPN_CONTROL': 'true' 'SUPERVISOR_VPN_CONTROL': 'true'
'SUPERVISOR_PERSISTENT_LOGGING': 'false' 'SUPERVISOR_PERSISTENT_LOGGING': 'false'
@ -130,6 +131,7 @@ testTargetWithDefaults2 = {
'SUPERVISOR_OVERRIDE_LOCK': 'false' 'SUPERVISOR_OVERRIDE_LOCK': 'false'
'SUPERVISOR_POLL_INTERVAL': '60000' 'SUPERVISOR_POLL_INTERVAL': '60000'
'SUPERVISOR_VPN_CONTROL': 'true' 'SUPERVISOR_VPN_CONTROL': 'true'
'SUPERVISOR_MIXPANEL_REPORT': 'true'
'SUPERVISOR_PERSISTENT_LOGGING': 'false' 'SUPERVISOR_PERSISTENT_LOGGING': 'false'
} }
apps: { apps: {

View File

@ -42,6 +42,9 @@ describe 'EventTracker', ->
mixpanelToken: 'someToken' mixpanelToken: 'someToken'
uuid: 'barbaz' uuid: 'barbaz'
mixpanelHost: { host: '', path: '' } mixpanelHost: { host: '', path: '' }
config:
get: -> Promise.resolve(true)
on: ->
}) })
expect(promise).to.be.fulfilled expect(promise).to.be.fulfilled
.then => .then =>

View File

@ -177,6 +177,7 @@ describe 'DeviceConfig', ->
SUPERVISOR_DELTA_APPLY_TIMEOUT: '0', SUPERVISOR_DELTA_APPLY_TIMEOUT: '0',
SUPERVISOR_DELTA_RETRY_COUNT: '30', SUPERVISOR_DELTA_RETRY_COUNT: '30',
SUPERVISOR_DELTA_RETRY_INTERVAL: '10000', SUPERVISOR_DELTA_RETRY_INTERVAL: '10000',
SUPERVISOR_MIXPANEL_REPORT: 'true'
SUPERVISOR_DELTA_VERSION: '2', SUPERVISOR_DELTA_VERSION: '2',
SUPERVISOR_INSTANT_UPDATE_TRIGGER: 'true', SUPERVISOR_INSTANT_UPDATE_TRIGGER: 'true',
SUPERVISOR_OVERRIDE_LOCK: 'false', SUPERVISOR_OVERRIDE_LOCK: 'false',