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

Add prometheus metrics collectors for http handlers #958

Merged
merged 16 commits into from
Dec 20, 2018

Conversation

t-tomalak
Copy link
Member

@t-tomalak t-tomalak commented Dec 3, 2018

What is the problem I am trying to address?

In Athens we don't collect metrics for http requests

How is the fix applied?

Added middleware that wraps buffalo handlers and instruments them to collect count of requests, requests duration, response size, request sizes. As first I wanted to add base http stats in follow up Pull Request there can be added other stats collectors . Some of them are:

  1. Errors - count,
  2. Disk usage
  3. network usage
  4. For workers number of in/out work items and time spent in a queue
  5. Cache hit rate (because it's fun to watch)

Mention the issue number it fixes or add the details of the changes if it doesn't have a specific issue.

Fixes #816

@t-tomalak t-tomalak requested a review from a team as a code owner December 3, 2018 22:15
Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

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

Just a quick glance so far. But super excited for the possibilities. Like memory and disk, error count 😁

forcessl "github.com/gobuffalo/mw-forcessl"
paramlogger "github.com/gobuffalo/mw-paramlogger"
sessions "github.com/gobuffalo/x/sessions"
"github.com/gobuffalo/mw-forcessl"
Copy link

Choose a reason for hiding this comment

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

These three imports should not be changed, unless their respective uses are also updated.

Copy link
Member Author

Choose a reason for hiding this comment

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

I double checked that and I see that they are redundant. github.com/gobuffalo/mw-forcessl is package forcessl and github.com/gobuffalo/mw-paramlogger is package paramlogger. I can revert, but with this changes everything still works 🙂

Copy link

Choose a reason for hiding this comment

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

Oh weird, just the import path doesn't match. I was wondering why the build didn't fail.

Copy link
Member

@manugupt1 manugupt1 left a comment

Choose a reason for hiding this comment

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

Hi @t-tomalak,
Thanks for getting this started. Before digging deep into it, I have a couple of requiests.
Can we move metrics to observ package and use opencensus as it was earlier decided. Further, by using opencensus, we can use various exporters pretty easily?

Would you mind making those changes?

@codecov-io
Copy link

codecov-io commented Dec 5, 2018

Codecov Report

Merging #958 into master will increase coverage by <.01%.
The diff coverage is 62.5%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #958      +/-   ##
==========================================
+ Coverage   59.66%   59.67%   +<.01%     
==========================================
  Files          81       81              
  Lines        2603     2611       +8     
==========================================
+ Hits         1553     1558       +5     
- Misses        908      909       +1     
- Partials      142      144       +2
Impacted Files Coverage Δ
pkg/config/config.go 27.27% <ø> (ø) ⬆️
cmd/proxy/actions/app_proxy.go 93.75% <100%> (+0.13%) ⬆️
cmd/proxy/actions/app.go 50.5% <57.14%> (+0.5%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 5eba6f2...d74b16d. Read the comment docs.

prometheus.HistogramOpts{
Name: "athens_http_request_duration_seconds",
Help: "Duration of request handled by Athens server",
Buckets: []float64{.1, 1, 5, 10},
Copy link
Member

Choose a reason for hiding this comment

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

this is in seconds right? do you think we can have a .5 as well

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes this are the second. Sure we can add that. I just put here some sample seconds which were feel right for my local Athens proxy. Any suggestions here are welcome.


// Middleware is middleware that instruments buffalo handlers
func Middleware(collectors ...prometheus.Collector) buffalo.MiddlewareFunc {
return func(next buffalo.Handler) buffalo.Handler {
Copy link
Member

Choose a reason for hiding this comment

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

trying to figure out if we can be buffalo independent here, but i guess it's ok, we will revisit once we're there

Copy link
Member Author

Choose a reason for hiding this comment

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

Prometheus accept only http.Handler from std, but unfortunately buffalo handlers are not compatible with it. I know that there are plans to migrate out of buffalo but then it will be just the case of building new middleware.

@t-tomalak t-tomalak changed the title Add prometheus metrics collectors for http handlers [WIP] Add prometheus metrics collectors for http handlers Dec 6, 2018
@t-tomalak t-tomalak changed the title [WIP] Add prometheus metrics collectors for http handlers Add prometheus metrics collectors for http handlers Dec 6, 2018
@t-tomalak
Copy link
Member Author

@manugupt1 now metrics are exported using opencensus exporters 🙂

return nil, errors.E(op, err)
}

return func() {}, nil
Copy link
Member Author

@t-tomalak t-tomalak Dec 6, 2018

Choose a reason for hiding this comment

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

Currently func() {} it's not needed but when we would add StackDriver or DataDog exporter it will be needed and by having that already here it will be easy to implement them.

Copy link
Member

Choose a reason for hiding this comment

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

can you then add a comment there so we know why it is there.
i'm not a big fan of future code and what if we will need it approach.

Copy link
Member Author

Choose a reason for hiding this comment

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

Added, also removed that func() from registerPrometheusExporter method

@manugupt1
Copy link
Member

Hi @t-tomalak, codewise it looks perfect to me. This is rad.

Can you link the instructions that you used to run it. So, that I can use it to test it. You can also add it in the docs in this PR if you would like to?

Have a great holiday!

}

// registerPrometheusExporter creates exporter that collects stats for Prometheus.
func registerPrometheusExporter(app *buffalo.App, service string) (func(), error) {
Copy link
Member

Choose a reason for hiding this comment

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

no need to return func(), this is not the iface method, return arg is ignored up there and RegisterStatsExporter returns func(){} by itselft

@t-tomalak
Copy link
Member Author

@manugupt1 I already created #970 issue that will allow to automaticaly set up prometheus in local environment, so I don't think we need docs about how to setup prometheus. Metrics can be either checkd manually on localhost:3000/metrics or you can start own prometheus. You can start it by creating configuration file prometheus.yml

global:
  scrape_interval: 2s

  external_labels:
    monitor: 'athens'

scrape_configs:
  - job_name: 'athens'

    scrape_interval: 2s

    static_configs:
      - targets: ['localhost:3000']

Then run:
docker run --name prometheus --network=host -v prometheus.yml:/etc/prometheus/prometheus.yml -d -p 9090:9090 prom/prometheus

And after that prometheus should be accessible under loclhost:9090 in your browser.

Copy link
Member

@manugupt1 manugupt1 left a comment

Choose a reason for hiding this comment

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

This is awesome @t-tomalak!

I am approving it! We will create new issues as they come through.

// RegisterStatsExporter determines the type of StatsExporter service for exporting stats from Opencensus
// Currently it supports: prometheus
func RegisterStatsExporter(app *buffalo.App, statsExporter, service string) (func(), error) {
const op errors.Op = "RegisterStatsExporter"
Copy link
Member

Choose a reason for hiding this comment

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

Can you add the pkg name like observ.RegisterStatsExporter ?

Copy link
Member Author

@t-tomalak t-tomalak Dec 18, 2018

Choose a reason for hiding this comment

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

sure, I was keeping convention from second obervable file with traces. Should I change there also?

Copy link
Member Author

Choose a reason for hiding this comment

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

I guess yes so I added 🙂


// registerViews register stats which should be collected in Athens
func registerViews() error {
const op errors.Op = "registerViews"
Copy link
Member

Choose a reason for hiding this comment

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

add pkg name please

Copy link
Member

@marpio marpio left a comment

Choose a reason for hiding this comment

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

Thanks Tomasz!

}

// StatsMiddleware is middleware that instruments buffalo handlers
func StatsMiddleware() buffalo.MiddlewareFunc {
Copy link
Member

Choose a reason for hiding this comment

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

just a small nit, can be exported first and unexported after them?

Copy link
Member Author

Choose a reason for hiding this comment

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

Sorted! Thanks for review 🙂

Copy link
Member

@michalpristas michalpristas left a comment

Choose a reason for hiding this comment

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

just a small nit and then 🚢 it

@michalpristas michalpristas merged commit fb696b2 into gomods:master Dec 20, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support for Metrics using Prometheus
5 participants