open-policy-agent / opa

Open Policy Agent (OPA) is an open source, general-purpose policy engine.
https://www.openpolicyagent.org
Apache License 2.0
9.68k stars 1.34k forks source link

Proposal: Allow custom plugins to create metrics #2348

Open BrunoCode opened 4 years ago

BrunoCode commented 4 years ago

Proposal: Allow custom plugins to create metrics

Explanation

OPA exposes useful prometheus metrics on the /metrics endpoint. Unfortunately there seem to be no way for custom plugins to add to those metrics.

Use Case

Imagine you create a plugin that calls an external REST api and you want to be able to track some metrics for those api calls (e.g. duration and count).

You can imagine a similar scenario if you create a plugin that makes requests to a database.

Potential Solutions

Solution No.1 A. Add method to Provider struct found in promethues.go that allows us to interact with the prometheus registry by either getting the registry or allowing us to register a prometheus.Collector.

B. Then in runtime/runtime.go when we create the new plugins.Manager we can pass it a metrics provider that can set the Provider from step A onto the plugins.Manager struct.

C. Assuming Manager has the Provider amongst it's properties, then when the custom plugin factory creates a new instance of the plugin it can attach the Manager to that Plugin thereby exposing the capabilities for a plugin to interact with the prometheus registry. And with this capability it can now create custom prometheus metrics.


Solution No.2 A. We could create a global variable that we assign the prometheus registry to, inside of prometheus.go. This would then mean we would have to import this global variable from prometheus.go to call it from our plugin.


Thoughts? Seem correct?

patrick-east commented 4 years ago

I would lean towards option # 1, I think we're in a pretty good spot where we avoid global registries so we should try and maintain that if possible.

For steps B and C we'd probably want to decide if it should be kept behind the metrics.Metrics abstraction or prometheus.Provider. If we keep it abstracted the plugins would need to potentially do some interface casting, but keeps the API a little bit more generic. Not sure without digging in more which way would work better.

tsandall commented 4 years ago

Thanks for filing this @BrunoCode!

Based on the conversation from the OPA biweekly yesterday I think the right next step would be to propose a set of interfaces (maybe just one) that would allow plugins to report metrics. I could imagine the interface living inside the github.com/open-policy-agent/opa/plugins package or perhaps a subpackage. We'd like to avoid putting a package dependency on Prometheus from the plugins package or the plugins themselves if possible. It should be possible to use the github.com/open-policy-agent/opa/metrics (or similar) APIs to count and time plugin operations (e.g., latency, errors, throughput, etc.)

BrunoCode commented 4 years ago

Fantastic I'll get right on that.

stale[bot] commented 2 years ago

This issue has been automatically marked as inactive because it has not had any activity in the last 30 days.