Skip to content

Commit 5c6d166

Browse files
authored
Merge pull request #125 from amplitude/log-levels
Add log levels
2 parents 1856f08 + 8bbc3ec commit 5c6d166

File tree

8 files changed

+245
-86
lines changed

8 files changed

+245
-86
lines changed

amplitude.js

Lines changed: 78 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2042,7 +2042,44 @@ var type = function (val) {
20422042
return typeof val === 'undefined' ? 'undefined' : _typeof(val);
20432043
};
20442044

2045-
var log = function log(s) {
2045+
var logLevel = 'WARN';
2046+
2047+
var logLevels = {
2048+
DISABLE: 0,
2049+
ERROR: 1,
2050+
WARN: 2,
2051+
INFO: 3
2052+
};
2053+
2054+
var setLogLevel = function setLogLevel(logLevelName) {
2055+
logLevel = logLevels[logLevelName] || logLevel;
2056+
};
2057+
2058+
var getLogLevel = function getLogLevel() {
2059+
return logLevel;
2060+
};
2061+
2062+
var log = {
2063+
error: function error(s) {
2064+
if (logLevel >= logLevels.ERROR) {
2065+
_log(s);
2066+
}
2067+
},
2068+
2069+
warn: function warn(s) {
2070+
if (logLevel >= logLevels.WARN) {
2071+
_log(s);
2072+
}
2073+
},
2074+
2075+
info: function info(s) {
2076+
if (logLevel >= logLevels.INFO) {
2077+
_log(s);
2078+
}
2079+
}
2080+
};
2081+
2082+
var _log = function _log(s) {
20462083
try {
20472084
console.log('[Amplitude] ' + s);
20482085
} catch (e) {
@@ -2091,7 +2128,7 @@ var _truncateValue = function _truncateValue(value) {
20912128

20922129
var validateInput = function validateInput(input, name, expectedType) {
20932130
if (type(input) !== expectedType) {
2094-
log('Invalid ' + name + ' input type. Expected ' + expectedType + ' but received ' + type(input));
2131+
log.error('Invalid ' + name + ' input type. Expected ' + expectedType + ' but received ' + type(input));
20952132
return false;
20962133
}
20972134
return true;
@@ -2101,12 +2138,12 @@ var validateInput = function validateInput(input, name, expectedType) {
21012138
var validateProperties = function validateProperties(properties) {
21022139
var propsType = type(properties);
21032140
if (propsType !== 'object') {
2104-
log('Error: invalid properties format. Expecting Javascript object, received ' + propsType + ', ignoring');
2141+
log.error('Error: invalid properties format. Expecting Javascript object, received ' + propsType + ', ignoring');
21052142
return {};
21062143
}
21072144

21082145
if (Object.keys(properties).length > constants.MAX_PROPERTY_KEYS) {
2109-
log('Error: too many properties (more than 1000), ignoring');
2146+
log.error('Error: too many properties (more than 1000), ignoring');
21102147
return {};
21112148
}
21122149

@@ -2121,7 +2158,7 @@ var validateProperties = function validateProperties(properties) {
21212158
var keyType = type(key);
21222159
if (keyType !== 'string') {
21232160
key = String(key);
2124-
log('WARNING: Non-string property key, received type ' + keyType + ', coercing to string "' + key + '"');
2161+
log.warn('WARNING: Non-string property key, received type ' + keyType + ', coercing to string "' + key + '"');
21252162
}
21262163

21272164
// validate value
@@ -2139,19 +2176,19 @@ var invalidValueTypes = ['null', 'nan', 'undefined', 'function', 'arguments', 'r
21392176
var validatePropertyValue = function validatePropertyValue(key, value) {
21402177
var valueType = type(value);
21412178
if (invalidValueTypes.indexOf(valueType) !== -1) {
2142-
log('WARNING: Property key "' + key + '" with invalid value type ' + valueType + ', ignoring');
2179+
log.warn('WARNING: Property key "' + key + '" with invalid value type ' + valueType + ', ignoring');
21432180
value = null;
21442181
} else if (valueType === 'error') {
21452182
value = String(value);
2146-
log('WARNING: Property key "' + key + '" with value type error, coercing to ' + value);
2183+
log.warn('WARNING: Property key "' + key + '" with value type error, coercing to ' + value);
21472184
} else if (valueType === 'array') {
21482185
// check for nested arrays or objects
21492186
var arrayCopy = [];
21502187
for (var i = 0; i < value.length; i++) {
21512188
var element = value[i];
21522189
var elemType = type(element);
21532190
if (elemType === 'array' || elemType === 'object') {
2154-
log('WARNING: Cannot have ' + elemType + ' nested in an array property value, skipping');
2191+
log.warn('WARNING: Cannot have ' + elemType + ' nested in an array property value, skipping');
21552192
continue;
21562193
}
21572194
arrayCopy.push(validatePropertyValue(key, element));
@@ -2166,7 +2203,7 @@ var validatePropertyValue = function validatePropertyValue(key, value) {
21662203
var validateGroups = function validateGroups(groups) {
21672204
var groupsType = type(groups);
21682205
if (groupsType !== 'object') {
2169-
log('Error: invalid groups format. Expecting Javascript object, received ' + groupsType + ', ignoring');
2206+
log.error('Error: invalid groups format. Expecting Javascript object, received ' + groupsType + ', ignoring');
21702207
return {};
21712208
}
21722209

@@ -2181,7 +2218,7 @@ var validateGroups = function validateGroups(groups) {
21812218
var keyType = type(key);
21822219
if (keyType !== 'string') {
21832220
key = String(key);
2184-
log('WARNING: Non-string groupType, received type ' + keyType + ', coercing to string "' + key + '"');
2221+
log.warn('WARNING: Non-string groupType, received type ' + keyType + ', coercing to string "' + key + '"');
21852222
}
21862223

21872224
// validate value
@@ -2201,7 +2238,7 @@ var validateGroupName = function validateGroupName(key, groupName) {
22012238
}
22022239
if (groupNameType === 'date' || groupNameType === 'number' || groupNameType === 'boolean') {
22032240
groupName = String(groupName);
2204-
log('WARNING: Non-string groupName, received type ' + groupNameType + ', coercing to string "' + groupName + '"');
2241+
log.warn('WARNING: Non-string groupName, received type ' + groupNameType + ', coercing to string "' + groupName + '"');
22052242
return groupName;
22062243
}
22072244
if (groupNameType === 'array') {
@@ -2211,19 +2248,19 @@ var validateGroupName = function validateGroupName(key, groupName) {
22112248
var element = groupName[i];
22122249
var elemType = type(element);
22132250
if (elemType === 'array' || elemType === 'object') {
2214-
log('WARNING: Skipping nested ' + elemType + ' in array groupName');
2251+
log.warn('WARNING: Skipping nested ' + elemType + ' in array groupName');
22152252
continue;
22162253
} else if (elemType === 'string') {
22172254
arrayCopy.push(element);
22182255
} else if (elemType === 'date' || elemType === 'number' || elemType === 'boolean') {
22192256
element = String(element);
2220-
log('WARNING: Non-string groupName, received type ' + elemType + ', coercing to string "' + element + '"');
2257+
log.warn('WARNING: Non-string groupName, received type ' + elemType + ', coercing to string "' + element + '"');
22212258
arrayCopy.push(element);
22222259
}
22232260
}
22242261
return arrayCopy;
22252262
}
2226-
log('WARNING: Non-string groupName, received type ' + groupNameType + '. Please use strings or array of strings for groupName');
2263+
log.warn('WARNING: Non-string groupName, received type ' + groupNameType + '. Please use strings or array of strings for groupName');
22272264
};
22282265

22292266
// parses the value of a url param (for example ?gclid=1234&...)
@@ -2235,6 +2272,8 @@ var getQueryParam = function getQueryParam(name, query) {
22352272
};
22362273

22372274
var utils = {
2275+
setLogLevel: setLogLevel,
2276+
getLogLevel: getLogLevel,
22382277
log: log,
22392278
isEmptyString: isEmptyString,
22402279
getQueryParam: getQueryParam,
@@ -2617,7 +2656,7 @@ Identify.prototype.add = function (property, value) {
26172656
if (type(value) === 'number' || type(value) === 'string') {
26182657
this._addOperation(AMP_OP_ADD, property, value);
26192658
} else {
2620-
utils.log('Unsupported type for value: ' + type(value) + ', expecting number or string');
2659+
utils.log.error('Unsupported type for value: ' + type(value) + ', expecting number or string');
26212660
}
26222661
return this;
26232662
};
@@ -2652,7 +2691,7 @@ Identify.prototype.append = function (property, value) {
26522691
Identify.prototype.clearAll = function () {
26532692
if (Object.keys(this.userPropertiesOperations).length > 0) {
26542693
if (!this.userPropertiesOperations.hasOwnProperty(AMP_OP_CLEAR_ALL)) {
2655-
utils.log('Need to send $clearAll on its own Identify object without any other operations, skipping $clearAll');
2694+
utils.log.error('Need to send $clearAll on its own Identify object without any other operations, skipping $clearAll');
26562695
}
26572696
return this;
26582697
}
@@ -2735,13 +2774,13 @@ Identify.prototype.unset = function (property) {
27352774
Identify.prototype._addOperation = function (operation, property, value) {
27362775
// check that the identify doesn't already contain a clearAll
27372776
if (this.userPropertiesOperations.hasOwnProperty(AMP_OP_CLEAR_ALL)) {
2738-
utils.log('This identify already contains a $clearAll operation, skipping operation ' + operation);
2777+
utils.log.error('This identify already contains a $clearAll operation, skipping operation ' + operation);
27392778
return;
27402779
}
27412780

27422781
// check that property wasn't already used in this Identify
27432782
if (this.properties.indexOf(property) !== -1) {
2744-
utils.log('User property "' + property + '" already used in this identify, skipping operation ' + operation);
2783+
utils.log.error('User property "' + property + '" already used in this identify, skipping operation ' + operation);
27452784
return;
27462785
}
27472786

@@ -4539,9 +4578,9 @@ var Revenue = function Revenue() {
45394578
*/
45404579
Revenue.prototype.setProductId = function setProductId(productId) {
45414580
if (type(productId) !== 'string') {
4542-
utils.log('Unsupported type for productId: ' + type(productId) + ', expecting string');
4581+
utils.log.error('Unsupported type for productId: ' + type(productId) + ', expecting string');
45434582
} else if (utils.isEmptyString(productId)) {
4544-
utils.log('Invalid empty productId');
4583+
utils.log.error('Invalid empty productId');
45454584
} else {
45464585
this._productId = productId;
45474586
}
@@ -4558,7 +4597,7 @@ Revenue.prototype.setProductId = function setProductId(productId) {
45584597
*/
45594598
Revenue.prototype.setQuantity = function setQuantity(quantity) {
45604599
if (type(quantity) !== 'number') {
4561-
utils.log('Unsupported type for quantity: ' + type(quantity) + ', expecting number');
4600+
utils.log.error('Unsupported type for quantity: ' + type(quantity) + ', expecting number');
45624601
} else {
45634602
this._quantity = parseInt(quantity);
45644603
}
@@ -4576,7 +4615,7 @@ Revenue.prototype.setQuantity = function setQuantity(quantity) {
45764615
*/
45774616
Revenue.prototype.setPrice = function setPrice(price) {
45784617
if (type(price) !== 'number') {
4579-
utils.log('Unsupported type for price: ' + type(price) + ', expecting number');
4618+
utils.log.error('Unsupported type for price: ' + type(price) + ', expecting number');
45804619
} else {
45814620
this._price = price;
45824621
}
@@ -4593,7 +4632,7 @@ Revenue.prototype.setPrice = function setPrice(price) {
45934632
*/
45944633
Revenue.prototype.setRevenueType = function setRevenueType(revenueType) {
45954634
if (type(revenueType) !== 'string') {
4596-
utils.log('Unsupported type for revenueType: ' + type(revenueType) + ', expecting string');
4635+
utils.log.error('Unsupported type for revenueType: ' + type(revenueType) + ', expecting string');
45974636
} else {
45984637
this._revenueType = revenueType;
45994638
}
@@ -4611,7 +4650,7 @@ Revenue.prototype.setRevenueType = function setRevenueType(revenueType) {
46114650
*/
46124651
Revenue.prototype.setEventProperties = function setEventProperties(eventProperties) {
46134652
if (type(eventProperties) !== 'object') {
4614-
utils.log('Unsupported type for eventProperties: ' + type(eventProperties) + ', expecting object');
4653+
utils.log.error('Unsupported type for eventProperties: ' + type(eventProperties) + ', expecting object');
46154654
} else {
46164655
this._properties = utils.validateProperties(eventProperties);
46174656
}
@@ -4623,7 +4662,7 @@ Revenue.prototype.setEventProperties = function setEventProperties(eventProperti
46234662
*/
46244663
Revenue.prototype._isValidRevenue = function _isValidRevenue() {
46254664
if (type(this._price) !== 'number') {
4626-
utils.log('Invalid revenue, need to set price field');
4665+
utils.log.error('Invalid revenue, need to set price field');
46274666
return false;
46284667
}
46294668
return true;
@@ -5607,6 +5646,7 @@ var DEFAULT_OPTIONS = {
56075646
includeReferrer: false,
56085647
includeUtm: false,
56095648
language: language.language,
5649+
logLevel: 'WARN',
56105650
optOut: false,
56115651
platform: 'Web',
56125652
savedMaxCount: 1000,
@@ -5670,7 +5710,7 @@ AmplitudeClient.prototype.Revenue = Revenue;
56705710
*/
56715711
AmplitudeClient.prototype.init = function init(apiKey, opt_userId, opt_config, opt_callback) {
56725712
if (type(apiKey) !== 'string' || utils.isEmptyString(apiKey)) {
5673-
utils.log('Invalid apiKey. Please re-initialize with a valid apiKey');
5713+
utils.log.error('Invalid apiKey. Please re-initialize with a valid apiKey');
56745714
return;
56755715
}
56765716

@@ -5734,7 +5774,7 @@ AmplitudeClient.prototype.init = function init(apiKey, opt_userId, opt_config, o
57345774

57355775
this._sendEventsIfReady(); // try sending unsent events
57365776
} catch (e) {
5737-
utils.log(e);
5777+
utils.log.error(e);
57385778
} finally {
57395779
if (type(opt_callback) === 'function') {
57405780
opt_callback(this);
@@ -5812,7 +5852,7 @@ AmplitudeClient.prototype.runQueuedFunctions = function () {
58125852
*/
58135853
AmplitudeClient.prototype._apiKeySet = function _apiKeySet(methodName) {
58145854
if (utils.isEmptyString(this.options.apiKey)) {
5815-
utils.log('Invalid apiKey. Please set a valid apiKey with init() before calling ' + methodName);
5855+
utils.log.error('Invalid apiKey. Please set a valid apiKey with init() before calling ' + methodName);
58165856
return false;
58175857
}
58185858
return true;
@@ -5837,7 +5877,7 @@ AmplitudeClient.prototype._loadSavedUnsentEvents = function _loadSavedUnsentEven
58375877
}
58385878
} catch (e) {}
58395879
}
5840-
utils.log('Unable to load ' + unsentKey + ' events. Restart with a new empty queue.');
5880+
utils.log.error('Unable to load ' + unsentKey + ' events. Restart with a new empty queue.');
58415881
return [];
58425882
};
58435883

@@ -6185,7 +6225,7 @@ AmplitudeClient.prototype.setDomain = function setDomain(domain) {
61856225
_loadCookieData(this);
61866226
_saveCookieData(this);
61876227
} catch (e) {
6188-
utils.log(e);
6228+
utils.log.error(e);
61896229
}
61906230
};
61916231

@@ -6200,7 +6240,7 @@ AmplitudeClient.prototype.setUserId = function setUserId(userId) {
62006240
this.options.userId = userId !== undefined && userId !== null && '' + userId || null;
62016241
_saveCookieData(this);
62026242
} catch (e) {
6203-
utils.log(e);
6243+
utils.log.error(e);
62046244
}
62056245
};
62066246

@@ -6243,7 +6283,7 @@ AmplitudeClient.prototype.setOptOut = function setOptOut(enable) {
62436283
this.options.optOut = enable;
62446284
_saveCookieData(this);
62456285
} catch (e) {
6246-
utils.log(e);
6286+
utils.log.error(e);
62476287
}
62486288
};
62496289

@@ -6256,7 +6296,7 @@ AmplitudeClient.prototype.setSessionId = function setSessionId(sessionId) {
62566296
this._sessionId = sessionId;
62576297
_saveCookieData(this);
62586298
} catch (e) {
6259-
utils.log(e);
6299+
utils.log.error(e);
62606300
}
62616301
};
62626302

@@ -6290,7 +6330,7 @@ AmplitudeClient.prototype.setDeviceId = function setDeviceId(deviceId) {
62906330
_saveCookieData(this);
62916331
}
62926332
} catch (e) {
6293-
utils.log(e);
6333+
utils.log.error(e);
62946334
}
62956335
};
62966336

@@ -6382,7 +6422,7 @@ AmplitudeClient.prototype.identify = function (identify_obj, opt_callback) {
63826422
return this._logEvent(constants.IDENTIFY_EVENT, null, null, identify_obj.userPropertiesOperations, null, null, opt_callback);
63836423
}
63846424
} else {
6385-
utils.log('Invalid identify input type. Expected Identify object but saw ' + type(identify_obj));
6425+
utils.log.error('Invalid identify input type. Expected Identify object but saw ' + type(identify_obj));
63866426
}
63876427

63886428
if (type(opt_callback) === 'function') {
@@ -6480,7 +6520,7 @@ AmplitudeClient.prototype._logEvent = function _logEvent(eventType, eventPropert
64806520

64816521
return eventId;
64826522
} catch (e) {
6483-
utils.log(e);
6523+
utils.log.error(e);
64846524
}
64856525
};
64866526

@@ -6594,7 +6634,7 @@ AmplitudeClient.prototype.logRevenueV2 = function logRevenueV2(revenue_obj) {
65946634
return this.logEvent(constants.REVENUE_EVENT, revenue_obj._toJSONObject());
65956635
}
65966636
} else {
6597-
utils.log('Invalid revenue input type. Expected Revenue object but saw ' + type(revenue_obj));
6637+
utils.log.error('Invalid revenue input type. Expected Revenue object but saw ' + type(revenue_obj));
65986638
}
65996639
};
66006640

@@ -6743,7 +6783,7 @@ AmplitudeClient.prototype._mergeEventsAndIdentifys = function _mergeEventsAndIde
67436783
// case 0: no events or identifys left
67446784
// note this should not happen, this means we have less events and identifys than expected
67456785
if (noEvents && noIdentifys) {
6746-
utils.log('Merging Events and Identifys, less events and identifys than expected');
6786+
utils.log.error('Merging Events and Identifys, less events and identifys than expected');
67476787
break;
67486788
}
67496789

amplitude.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)