realm-js/lib/submit-analytics.js

100 lines
3.6 KiB
JavaScript
Raw Normal View History

2016-11-16 14:55:59 +00:00
#!/usr/bin/env node
// Asynchronously submits install information to Realm.
//
// Why are we doing this? In short, because it helps us build a better product
// for you. None of the data personally identifies you, your employer or your
// app, but it *will* help us understand what language you use, what Node.js
// versions you target, etc. Having this info will help prioritizing our time,
// adding new features and deprecating old features. Collecting an anonymized
// application path & anonymized machine identifier is the only way for us to
// count actual usage of the other metrics accurately. If we dont have a way to
// deduplicate the info reported, it will be useless, as a single developer
// `npm install`-ing the same app 10 times would report 10 times more than another
// developer that only installs once, making the data all but useless.
// No one likes sharing data unless its necessary, we get it, and weve
// debated adding this for a long long time. If you truly, absolutely
// feel compelled to not send this data back to Realm, then you can set an env
// variable named REALM_DISABLE_ANALYTICS.
//
// Currently the following information is reported:
// - What version of Realm is being installed.
// - The OS platform and version which is being used.
// - Node.js, v8, libuv, OpenSSL version numbers.
// - An anonymous machine identifier and hashed application path to aggregate the other information on.
'use strict';
if ('REALM_DISABLE_ANALYTICS' in process.env) {
module.exports = function(){};
} else {
const os = require('os');
const crypto = require('crypto');
const fs = require('fs');
const request = require('request');
2016-11-16 14:55:59 +00:00
function sha256(data) {
let hash = crypto.createHash('sha256');
hash.update(data);
return hash.digest('hex');
}
2016-11-16 14:55:59 +00:00
function getDarwinIdentifier() {
const interfaces = os.networkInterfaces();
const iface = interfaces["en0"] || interfaces["en1"];
if (!iface) {
2016-11-16 14:55:59 +00:00
return Buffer.from('unknown', 'utf8');
}
2016-11-16 14:55:59 +00:00
const mac = iface[0].mac.replace(/:/g, '');
return new Buffer(mac, 'hex');
}
2016-11-16 14:55:59 +00:00
function getLinuxIdentifier() {
if (fs.existsSync('/var/lib/dbus/machine-id')) {
2016-11-16 14:55:59 +00:00
return fs.readFileSync('/var/lib/dbus/machine-id');
} else if (fs.existsSync('/etc/machine-id')) {
2016-11-16 14:55:59 +00:00
return fs.readFileSync('/etc/machine-id');
} else {
2016-11-16 14:55:59 +00:00
return Buffer.from('unknown', 'utf8');
}
2016-11-16 14:55:59 +00:00
}
function getAnonymizedMachineIdentifier() {
switch (os.platform()) {
2016-11-16 14:55:59 +00:00
case 'darwin':
return sha256(getDarwinIdentifier());
case 'linux':
return sha256(getLinuxIdentifier());
default:
return null;
}
2016-11-16 14:55:59 +00:00
}
module.exports = function(eventName) {
const identifier = getAnonymizedMachineIdentifier();
const payload = {
2016-11-16 14:55:59 +00:00
'event': eventName,
'properties': {
'token': 'aab85907a13e1ff44a95be539d9942a9',
'distinct_id': identifier,
'Anonymized Machine Identifier': identifier,
'Anonymized Application ID': sha256(__dirname),
'Binding': 'node.js',
'Version': require('../package.json').version,
'Language': 'javascript',
'OS Type': os.platform(),
'OS Version': os.release(),
'Node.js versions': process.versions
}
};
2016-11-16 14:55:59 +00:00
request(`https://api.mixpanel.com/track/?data=${new Buffer(JSON.stringify(payload), 'utf8').toString('base64')}&ip=1`,
2017-01-03 14:16:46 +00:00
() => { /* Analytics failed. Do nothing. */ });
}
2016-11-16 14:55:59 +00:00
if (require.main === module) {
module.exports('Install');
}
2016-11-16 14:55:59 +00:00
}