使用 InfluxDB 衡量和监控 Discourse 上的社区参与度
作者:David G. Simmons / 产品, 开发者
2017年11月03日
导航至
监控 Discourse
我们 InfluxData 在 Discourse 上建立了社区(您是社区的成员,对吧?还没加入?快去注册!!)。我的工作之一是关注社区,回答问题,并努力发展社区。这其中当然包括指标。一切都归结于你能衡量什么,不是吗?所以我的挑战是找到一种衡量社区的方法。
当然,管理界面会显示过去一天、一周和一个月的新用户数量、帖子创建数量等,所以统计数据是有的。但是每天都去那里记录这些数字的想法,嗯,实在没什么吸引力。
Discourse 提供了一些基本的监控功能,但真正的强大之处在于使用他们的 API 以全新的方式查看数据。毕竟,自动化这样的任务正是计算机发明的目的,对吧?所以,我将向您展示我是如何将所有这些管理统计数据从 Discourse 中提取出来,然后(当然)插入到 InfluxDB 中,以便我可以随时掌握它们,并随时展示。
获取统计数据
第一个挑战是找到一种方法来获取我正在寻找的所有统计数据。当然,我做的第一件事就是直接查看 Discourse API 文档,希望有一个简单的 API 调用可以得到我想要的东西。或者,最坏的情况,一系列 API 调用来获取我想要的各个统计数据。唉,事情从来没有那么简单,不是吗?有一些非常方便的 API 可以做很多事情,但获取用户和活动统计数据并不在其中。是时候逆向工程了。
通过 Google Chrome 开发者工具很容易获得大量信息。然后我加载了 Discourse 的管理界面,看看发生了什么

正如你所看到的,我找到了一个正在加载的 'dashboard.json',所以我去那里探索了一下,宾果!数据宝藏!事实上,它包含了管理仪表板上的所有数据。我几乎到家了!几乎。这给了我一个 3200 行的 JSON 对象,我必须仔细查看才能找到我需要的东西。有些数据可以通过其他方式获得。例如, http_2xx_reqs 统计数据可以从 nginx 日志中获得,但每天没有回复的主题数量等则不行。而这些正是我真正感兴趣的。所以我又回到了解析 JSON 对象并将结果插入到 InfluxDB 的工作中。你还以为我的生活很光鲜呢!
编写代码
然而,这次我不是在 Node-red 中做这件事。我决定,既然我的服务器上已经有一些 Node.js 进程在做各种事情,那我再添加一个也没关系。Node.js 非常擅长 http get 和解析 JSON,所以这似乎是个好主意。你首先需要的是 Discourse 安装的 API 密钥,所以去 Discourse API 文档获取一个用于你的 Discourse 设置的密钥。然后定义你的 URL(当然,这会与我的不同,因为你有自己的 Discourse 设置,而且你没有我的管理员访问权限)。
const url = "https://community.influxdata.com/admin/dashboard.json?api_username=foo&api_key=bar";
再次查看 JSON 文件,我决定了一些我感兴趣的“全局报告”
{"global_reports":[
{"type": "visits",
"title": "User Visits",
"xaxis": "Day",
"yaxis": "Number of visits",
"data": [
{"x": "2017-09-26",
"y": 68
},
...
],
"total": 8404,
"start_date": "2017-09-26T00:00:00.000Z",
"end_date": "2017-10-26T23:59:59.999Z",
"category_id": null,
"group_id": null,
"prev30Days": 1077
},
...
更棒的是!我可以获得总数和过去 30 天的总数!现在我已经有了 URL,并且知道 JSON 结构是什么,我可以去获取它并解析它
https.get(url, res => {
res.setEncoding("utf8");
let body = "";
res.on("data", data => {
body += data;
});
res.on("end", () => {
console.log("Influx setup");
body = JSON.parse(body);
var reports = body.global_reports;
for (var x = 0; x < reports.length; x++) {
const ty = reports[x].type;
for (var y = 0; y < reports[x].data.length; y++) {
var buffer = "stats,report=".concat(reports[x].type);
buffer = buffer.concat(" ");
buffer = buffer.concat("value=");
buffer = buffer.concat(reports[x].data[y].y).concat(" ");
buffer = buffer.concat(new Date(reports[x].data[y].x).getTime());
writeData(buffer);
}
var buffer = "stats,cumulative=".concat(reports[x].type);
buffer = buffer.concat(" ");
buffer = buffer.concat("total=").concat(reports[x].total).concat(",");
buffer = buffer.concat("prev30Days=").concat(reports[x].prev30Days).concat(" ");
buffer = buffer.concat(new Date(reports[x].end_date).getTime());
writeData(buffer);
}
这让我得到了我想要的所有单独的数据点,以及所有累积的数据点——记住,总数和过去 30 天的总数——我想要的。然后我将这些数据写入我的 InfluxDB 实例
function writeData(buffer){
var post_options = {
host: 'my_instance.influxcloud.net',
path: '/write?db=discourse&precision=ms&u=my_username&p=myPassword',
method: 'POST',
headers: {
'Content-Length': Buffer.byteLength(buffer)
}
};
req = https.request(post_options, function(result) {
if(result.statusCode > 205){
console.log('Status: ' + result.statusCode);
console.log('Headers: ' + JSON.stringify(result.headers));
}
result.setEncoding('utf8');
result.on('data', function(body) {
console.log('Body: ' + body);
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
req.write(buffer);
req.end();
}
显然,不需要将结果记录到控制台,但我喜欢看看发生了什么。这就是我编写的所有代码!
查看结果
当然,没有仪表板,任何 InfluxDB 项目都不会完整,这样我就可以可视化结果——并且让管理层可以一目了然地看到社区的健康状况和活动。

真的很高兴看到我们现在有零个未回复的主题!这件事最棒的部分是,它自动化了我过去不得不手动收集的大量统计数据,从而让我可以自由地去做其他很酷的事情!
接下来是什么?
嗯,我认为这个项目没有什么后续了,但我上周在欧洲 EclipseCon 大会上度过,我将写一些关于那里发生的非常酷的事情,敬请期待!别忘了,如果你对我想做的项目或任何问题有任何想法,请告诉我!
别忘了加入我们的社区并开始参与!