Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Metrics with Prometheus #2069

Merged
merged 24 commits into from
Nov 4, 2018
Merged

Metrics with Prometheus #2069

merged 24 commits into from
Nov 4, 2018

Conversation

platan
Copy link
Member

@platan platan commented Sep 10, 2018

Idea behind this change is described in #2068

This change contains:

  • /metrics resource with access limit with default metrics (disabled by default)
  • METRICS_PROMETHEUS_ENABLED environment variable to enable metrics
  • METRICS_PROMETHEUS_ALLOWED_IPS env variable for controlling allowed IP adresses

@shields-ci
Copy link

shields-ci commented Sep 10, 2018

Warnings
⚠️

This PR modified the server but none of the service tests.
That's okay so long as it's refactoring existing code. Otherwise, please consider adding tests to the service: How-to

Messages
📖

✨ Thanks for your contribution to Shields, @platan!

📖

Thanks for contributing to our documentation. We ❤️ our documentarians!

Generated by 🚫 dangerJS

@platan platan changed the title WIP Metrics with Prometheus Metrics with Prometheus Sep 11, 2018
@platan
Copy link
Member Author

platan commented Sep 11, 2018

I would like to have tests for this. But I do not know is it possible to run service tests with config.metrics.prometheus.enabled set to false and true.
My first attempt:
services/metrics/metrics.tester.js

'use strict'

const ServiceTester = require('../service-tester')

const t = new ServiceTester({ id: 'metrics', title: 'Prometheus metrics', pathPrefix: '' })
module.exports = t

t.create('metric are disabled by default')
  .get('/metrics')
  .expectStatus(404)

// below test will fail, we have to set config.metrics.prometheus.enabled = true
// const config = require('../../lib/server-config')
// config.metrics.prometheus.enabled = true

t.create('metric can be enabled by feature flag')
  .get('/metrics')
  .expectStatus(200)
  .expectBodyContains('nodejs_version_info')

Both tests requires change in services/service-tester.js (we have response which is not a JSON)

diff --git a/services/service-tester.js b/services/service-tester.js
index 91223be..17009af 100644
--- a/services/service-tester.js
+++ b/services/service-tester.js
@@ -62,12 +62,18 @@ class ServiceTester {
       })
       // eslint-disable-next-line mocha/prefer-arrow-callback
       .finally(function() {
+        let content;
+        try {
+          content = JSON.parse(this._response.body)
+        } catch(e) {
+          content = this._response.body;
+        }
         // `this` is the IcedFrisby instance.
         trace.logTrace(
           'outbound',
           emojic.shield,
           'Response',
-          JSON.parse(this._response.body)
+          content
         )
       })

I've tried with separate test files for both cases, but server is started only once for all tests.
@paulmelnikow maybe you have an idea how to test both cases?

@chris48s chris48s added the operations Hosting, monitoring, and reliability for the production badge servers label Sep 28, 2018
@paulmelnikow
Copy link
Member

The approach I'd probably take to testing this is to test it with a lower-level unit test. I just did something similar for the GitHub token acceptor in https://github.com/badges/shields/pull/2021/files#diff-e852a48eb7b4b8dcdf24b0bb30321a60.

The module exposes a function setRoutes, which gets a camp instance and adds routes to it. The unit test creates a new server, invokes setRoutes, and then fires some requests at it using got or fetch.

We have to trust that the wiring in server.js works, and don't get coverage of the config option, though that code is simple enough that it seems like a decent tradeoff.

There's some similar code for the github admin route and its test:

https://github.com/badges/shields/blob/master/services/github/auth/admin.js
https://github.com/badges/shields/blob/master/services/github/auth/admin.spec.js

@platan
Copy link
Member Author

platan commented Nov 3, 2018

I've refactored the code and I've added an access limit. @paulmelnikow thanks for the hints about testing! :-)

lib/sys/prometheus-metrics.js Outdated Show resolved Hide resolved
class PrometheusMetrics {
constructor(config = {}) {
this.enabled = config.enabled || false
const matchNothing = /(?!)/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

server.js Outdated Show resolved Hide resolved
@paulmelnikow paulmelnikow temporarily deployed to shields-staging-pr-2069 November 4, 2018 07:25 Inactive
@platan
Copy link
Member Author

platan commented Nov 4, 2018

Can we merge it?

@paulmelnikow
Copy link
Member

Let's merge it! I'll make sure @espadrine is aware of it before we turn it on in production.

@platan platan merged commit bc4bd79 into badges:master Nov 4, 2018
@shields-deployment
Copy link

This pull request was merged to master branch. This change is now waiting for deployment, which will usually happen within a few days. Stay tuned by joining our #ops channel on Discord!

After deployment, changes are copied to gh-pages branch:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
operations Hosting, monitoring, and reliability for the production badge servers
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants