使用 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 大会上度过,我将写一些关于那里发生的非常酷的事情,敬请期待!别忘了,如果你对我想做的项目或任何问题有任何想法,请告诉我!
别忘了加入我们的社区并开始参与!