使用 InfluxDB 衡量和监控 Discourse 上的社区参与度

导航至

监控 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 项目都不会完整,这样我就可以可视化结果——并且让管理层可以一目了然地看到社区的健康状况和活动。

SafariScreenSnapz005

真的很高兴看到我们现在有零个未回复的主题!这件事最棒的部分是,它自动化了我过去不得不手动收集的大量统计数据,从而让我可以自由地去做其他很酷的事情!

接下来是什么?

嗯,我认为这个项目没有什么后续了,但我上周在欧洲 EclipseCon 大会上度过,我将写一些关于那里发生的非常酷的事情,敬请期待!别忘了,如果你对我想做的项目或任何问题有任何想法,请告诉我!

别忘了加入我们的社区并开始参与!