Skip to content

Commit 9f0cbc5

Browse files
committed
Add basic performance trace reporting
1 parent f1f065a commit 9f0cbc5

File tree

3 files changed

+129
-1
lines changed

3 files changed

+129
-1
lines changed

examples/apm_example.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//since we need to test crashing the app
2+
/*global app*/
3+
var Countly = require("../lib/countly.js");
4+
5+
Countly.init({
6+
app_key: "YOUR_APP_KEY",
7+
url: "https://try.count.ly", //your server goes here
8+
debug: true
9+
});
10+
11+
//report app start trace
12+
Countly.report_app_start();
13+
14+
//example express middleware
15+
function expressMiddleware(req, res, next) {
16+
var trace = {
17+
type: "network",
18+
name: req.baseUrl + req.path,
19+
stz: Date.now(),
20+
};
21+
22+
var processed = false;
23+
24+
function processRequest() {
25+
if (!processed) {
26+
processed = true;
27+
trace.etz = Date.now();
28+
trace.apm_metrics = {
29+
response_time: trace.etz - trace.stz,
30+
response_code: res.statusCode
31+
};
32+
Countly.report_trace(trace);
33+
}
34+
}
35+
36+
res.on('finish', processRequest);
37+
38+
res.on('close', processRequest);
39+
40+
next();
41+
}
42+
43+
app.use(expressMiddleware);

lib/countly-bulk-user.js

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ function CountlyBulkUser(conf){
406406
* @param {string=} feedback.email - user's email
407407
* @param {string=} feedback.comment - user's comment
408408
**/
409-
this.report_feedback = function (feedback) {
409+
this.report_feedback = function (feedback, timestamp) {
410410
if (this.check_consent("star-rating")) {
411411
if (!feedback.widget_id) {
412412
log("Feedback must contain widget_id property");
@@ -423,6 +423,9 @@ function CountlyBulkUser(conf){
423423
count: 1,
424424
segmentation: {}
425425
};
426+
if(timestamp){
427+
event.timestamp = timestamp;
428+
}
426429
event.segmentation = getProperties(feedback, props);
427430
log("Reporting feedback: ", event);
428431
this.add_event(event);
@@ -431,6 +434,38 @@ function CountlyBulkUser(conf){
431434
return this;
432435
};
433436

437+
/**
438+
* Report performance trace
439+
* @param {Object} trace - apm trace object
440+
* @param {string} trace.type - device or network
441+
* @param {string} trace.name - url or view of the trace
442+
* @param {number} trace.stz - start timestamp
443+
* @param {number} trace.etz - end timestamp
444+
* @param {Object} trace.app_metrics - key/value metrics like duration, to report with trace where value is number
445+
* @param {Object=} trace.apm_attr - object profiling attributes (not yet supported)
446+
*/
447+
this.report_trace = function (trace) {
448+
if (this.check_consent("apm")) {
449+
var props = ["type", "name", "stz", "etz", "apm_metrics", "apm_attr"];
450+
for (var i = 0; i < props.length; i++) {
451+
if (props[i] !== "apm_attr" && typeof trace[props[i]] === "undefined") {
452+
log("APM trace must have a", props[i]);
453+
return;
454+
}
455+
}
456+
457+
var e = getProperties(trace, props);
458+
e.timestamp = trace.stz;
459+
var date = new Date();
460+
e.hour = date.getHours();
461+
e.dow = date.getDay();
462+
var query = prepareQuery({ apm: JSON.stringify(e) });
463+
log("Adding APM trace: ", e);
464+
conf.server.add_request(query);
465+
}
466+
return this;
467+
};
468+
434469
/**
435470
* Report crash
436471
* @param {Object} crash - object containing information about crash and state of device

lib/countly.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -944,6 +944,56 @@ Countly.Bulk = Bulk;
944944
Countly.track_view(name, viewSegments);
945945
};
946946

947+
/**
948+
* Report performance trace
949+
* @param {Object} trace - apm trace object
950+
* @param {string} trace.type - device or network
951+
* @param {string} trace.name - url or view of the trace
952+
* @param {number} trace.stz - start timestamp
953+
* @param {number} trace.etz - end timestamp
954+
* @param {Object} trace.app_metrics - key/value metrics like duration, to report with trace where value is number
955+
* @param {Object=} trace.apm_attr - object profiling attributes (not yet supported)
956+
*/
957+
Countly.report_trace = function (trace) {
958+
if (Countly.check_consent("apm")) {
959+
var props = ["type", "name", "stz", "etz", "apm_metrics", "apm_attr"];
960+
for (var i = 0; i < props.length; i++) {
961+
if (props[i] !== "apm_attr" && typeof trace[props[i]] === "undefined") {
962+
log("APM trace must have a", props[i]);
963+
return;
964+
}
965+
}
966+
967+
var e = getProperties(trace, props);
968+
e.timestamp = trace.stz;
969+
var date = new Date();
970+
e.hour = date.getHours();
971+
e.dow = date.getDay();
972+
toRequestQueue({ apm: JSON.stringify(e) });
973+
log("Adding APM trace: ", e);
974+
}
975+
};
976+
977+
/**
978+
* Report app start trace
979+
*/
980+
Countly.report_app_start = function () {
981+
//do on next tick to allow synchronous code to load
982+
process.nextTick(function() {
983+
var start = Math.floor(process.uptime() * 1000);
984+
var end = Date.now();
985+
Countly.report_trace({
986+
type: "device",
987+
name: process.title || process.argv.join(" "),
988+
stz: start,
989+
etz: end,
990+
app_metrics: {
991+
duration: end - start
992+
}
993+
});
994+
});
995+
};
996+
947997
/**
948998
* Make raw request with provided parameters
949999
* @example Countly.request({app_key:"somekey", devide_id:"someid", events:"[{'key':'val','count':1}]", begin_session:1});

0 commit comments

Comments
 (0)