Core metrics prometheus collector
This commit is contained in:
commit
0490a43f17
|
|
@ -0,0 +1,17 @@
|
|||
.sw?
|
||||
.*.sw?
|
||||
*.beam
|
||||
*~
|
||||
\#*
|
||||
.#*
|
||||
*.d
|
||||
/.erlang.mk/
|
||||
/cover/
|
||||
/deps/
|
||||
/doc/
|
||||
/ebin/
|
||||
/logs/
|
||||
/plugins/
|
||||
|
||||
/rabbitmq_management_metrics.d
|
||||
erl_crash.dump
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
# Contributor Code of Conduct
|
||||
|
||||
As contributors and maintainers of this project, and in the interest of fostering an open
|
||||
and welcoming community, we pledge to respect all people who contribute through reporting
|
||||
issues, posting feature requests, updating documentation, submitting pull requests or
|
||||
patches, and other activities.
|
||||
|
||||
We are committed to making participation in this project a harassment-free experience for
|
||||
everyone, regardless of level of experience, gender, gender identity and expression,
|
||||
sexual orientation, disability, personal appearance, body size, race, ethnicity, age,
|
||||
religion, or nationality.
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery
|
||||
* Personal attacks
|
||||
* Trolling or insulting/derogatory comments
|
||||
* Public or private harassment
|
||||
* Publishing other's private information, such as physical or electronic addresses,
|
||||
without explicit permission
|
||||
* Other unethical or unprofessional conduct
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments,
|
||||
commits, code, wiki edits, issues, and other contributions that are not aligned to this
|
||||
Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors
|
||||
that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
By adopting this Code of Conduct, project maintainers commit themselves to fairly and
|
||||
consistently applying these principles to every aspect of managing this project. Project
|
||||
maintainers who do not follow or enforce the Code of Conduct may be permanently removed
|
||||
from the project team.
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an
|
||||
individual is representing the project or its community.
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by
|
||||
contacting a project maintainer at [info@rabbitmq.com](mailto:info@rabbitmq.com). All complaints will
|
||||
be reviewed and investigated and will result in a response that is deemed necessary and
|
||||
appropriate to the circumstances. Maintainers are obligated to maintain confidentiality
|
||||
with regard to the reporter of an incident.
|
||||
|
||||
This Code of Conduct is adapted from the
|
||||
[Contributor Covenant](http://contributor-covenant.org), version 1.3.0, available at
|
||||
[contributor-covenant.org/version/1/3/0/](http://contributor-covenant.org/version/1/3/0/)
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
Thank you for using RabbitMQ and for taking the time to contribute to the project.
|
||||
This document has two main parts:
|
||||
|
||||
* when and how to file GitHub issues for RabbitMQ projects
|
||||
* how to submit pull requests
|
||||
|
||||
They intend to save you and RabbitMQ maintainers some time, so please
|
||||
take a moment to read through them.
|
||||
|
||||
## Overview
|
||||
|
||||
### GitHub issues
|
||||
|
||||
The RabbitMQ team uses GitHub issues for _specific actionable items_ that
|
||||
engineers can work on. This assumes the following:
|
||||
|
||||
* GitHub issues are not used for questions, investigations, root cause
|
||||
analysis, discussions of potential issues, etc (as defined by this team)
|
||||
* Enough information is provided by the reporter for maintainers to work with
|
||||
|
||||
The team receives many questions through various venues every single
|
||||
day. Frequently, these questions do not include the necessary details
|
||||
the team needs to begin useful work. GitHub issues can very quickly
|
||||
turn into a something impossible to navigate and make sense
|
||||
of. Because of this, questions, investigations, root cause analysis,
|
||||
and discussions of potential features are all considered to be
|
||||
[mailing list][rmq-users] material. If you are unsure where to begin,
|
||||
the [RabbitMQ users mailing list][rmq-users] is the right place.
|
||||
|
||||
Getting all the details necessary to reproduce an issue, make a
|
||||
conclusion or even form a hypothesis about what's happening can take a
|
||||
fair amount of time. Please help others help you by providing a way to
|
||||
reproduce the behavior you're observing, or at least sharing as much
|
||||
relevant information as possible on the [RabbitMQ users mailing
|
||||
list][rmq-users].
|
||||
|
||||
Please provide versions of the software used:
|
||||
|
||||
* RabbitMQ server
|
||||
* Erlang
|
||||
* Operating system version (and distribution, if applicable)
|
||||
* All client libraries used
|
||||
* RabbitMQ plugins (if applicable)
|
||||
|
||||
The following information greatly helps in investigating and reproducing issues:
|
||||
|
||||
* RabbitMQ server logs
|
||||
* A code example or terminal transcript that can be used to reproduce
|
||||
* Full exception stack traces (a single line message is not enough!)
|
||||
* `rabbitmqctl report` and `rabbitmqctl environment` output
|
||||
* Other relevant details about the environment and workload, e.g. a traffic capture
|
||||
* Feel free to edit out hostnames and other potentially sensitive information.
|
||||
|
||||
To make collecting much of this and other environment information, use
|
||||
the [`rabbitmq-collect-env`][rmq-collect-env] script. It will produce an archive with
|
||||
server logs, operating system logs, output of certain diagnostics commands and so on.
|
||||
Please note that **no effort is made to scrub any information that may be sensitive**.
|
||||
|
||||
### Pull Requests
|
||||
|
||||
RabbitMQ projects use pull requests to discuss, collaborate on and accept code contributions.
|
||||
Pull requests is the primary place of discussing code changes.
|
||||
|
||||
Here's the recommended workflow:
|
||||
|
||||
* [Fork the repository][github-fork] or repositories you plan on contributing to. If multiple
|
||||
repositories are involved in addressing the same issue, please use the same branch name
|
||||
in each repository
|
||||
* Create a branch with a descriptive name in the relevant repositories
|
||||
* Make your changes, run tests (usually with `make tests`), commit with a
|
||||
[descriptive message][git-commit-msgs], push to your fork
|
||||
* Submit pull requests with an explanation what has been changed and **why**
|
||||
* Submit a filled out and signed [Contributor Agreement][ca-agreement] if needed (see below)
|
||||
* Be patient. We will get to your pull request eventually
|
||||
|
||||
If what you are going to work on is a substantial change, please first
|
||||
ask the core team for their opinion on the [RabbitMQ users mailing list][rmq-users].
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
See [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md).
|
||||
|
||||
## Contributor Agreement
|
||||
|
||||
If you want to contribute a non-trivial change, please submit a signed
|
||||
copy of our [Contributor Agreement][ca-agreement] around the time you
|
||||
submit your pull request. This will make it much easier (in some
|
||||
cases, possible) for the RabbitMQ team at Pivotal to merge your
|
||||
contribution.
|
||||
|
||||
## Where to Ask Questions
|
||||
|
||||
If something isn't clear, feel free to ask on our [mailing list][rmq-users].
|
||||
|
||||
[rmq-collect-env]: https://github.com/rabbitmq/support-tools/blob/master/scripts/rabbitmq-collect-env
|
||||
[git-commit-msgs]: https://chris.beams.io/posts/git-commit/
|
||||
[rmq-users]: https://groups.google.com/forum/#!forum/rabbitmq-users
|
||||
[ca-agreement]: https://cla.pivotal.io/sign/rabbitmq
|
||||
[github-fork]: https://help.github.com/articles/fork-a-repo/
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
PROJECT = rabbitmq_prometheus
|
||||
PROJECT_MOD = rabbit_prometheus_app
|
||||
|
||||
dep_prometheus = hex 3.5.1
|
||||
dep_prometheus_httpd = hex 2.1.8
|
||||
dep_accept = hex 0.3.3
|
||||
dep_prometheus_cowboy = hex 0.1.4
|
||||
|
||||
DEPS = rabbit_common rabbit prometheus prometheus_httpd accept prometheus_cowboy rabbitmq_web_dispatch
|
||||
|
||||
DEP_EARLY_PLUGINS = rabbit_common/mk/rabbitmq-early-plugin.mk
|
||||
DEP_PLUGINS = rabbit_common/mk/rabbitmq-plugin.mk
|
||||
|
||||
# FIXME: Use erlang.mk patched for RabbitMQ, while waiting for PRs to be
|
||||
# reviewed and merged.
|
||||
|
||||
ERLANG_MK_REPO = https://github.com/rabbitmq/erlang.mk.git
|
||||
ERLANG_MK_COMMIT = rabbitmq-tmp
|
||||
|
||||
include rabbitmq-components.mk
|
||||
include erlang.mk
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
# RabbitMQ Prometheus.io core metrics exporter
|
||||
|
||||
## Getting Started
|
||||
|
||||
This is an Prometheus.io core metrics exporter plugin for RabbitMQ.
|
||||
|
||||
The plugin is included in the RabbitMQ distribution. To enable
|
||||
it, use [rabbitmq-plugins](http://www.rabbitmq.com/man/rabbitmq-plugins.1.man.html):
|
||||
|
||||
rabbitmq-plugins enable rabbitmq_prometheus
|
||||
|
||||
Default port used by the plugin is `15673`.
|
||||
|
||||
## Configuration
|
||||
|
||||
This exporter supports the following options via `rabbitmq_prometheus` app env:
|
||||
- `path` - scrape endpoint. Default is `"metrics"`.
|
||||
- `ssl_config`
|
||||
- `tcp_config`
|
||||
|
||||
Sample `/etc/rabbitmq/rabbitmq.config`:
|
||||
|
||||
```erlang
|
||||
[
|
||||
{rabbitmq_exporter, [
|
||||
{path, "/mymetrics"},
|
||||
{tcp_config, [{port, 15673}]}
|
||||
]}
|
||||
].
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
See [CONTRIBUTING.md](https://github.com/rabbitmq/rabbitmq-prometheus/blob/master/CONTRIBUTING.md).
|
||||
|
||||
|
||||
## Copyright
|
||||
|
||||
(c) Pivotal Software Inc., 2007-2019.
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,320 @@
|
|||
ifeq ($(.DEFAULT_GOAL),)
|
||||
# Define default goal to `all` because this file defines some targets
|
||||
# before the inclusion of erlang.mk leading to the wrong target becoming
|
||||
# the default.
|
||||
.DEFAULT_GOAL = all
|
||||
endif
|
||||
|
||||
# PROJECT_VERSION defaults to:
|
||||
# 1. the version exported by rabbitmq-server-release;
|
||||
# 2. the version stored in `git-revisions.txt`, if it exists;
|
||||
# 3. a version based on git-describe(1), if it is a Git clone;
|
||||
# 4. 0.0.0
|
||||
|
||||
PROJECT_VERSION := $(RABBITMQ_VERSION)
|
||||
|
||||
ifeq ($(PROJECT_VERSION),)
|
||||
PROJECT_VERSION := $(shell \
|
||||
if test -f git-revisions.txt; then \
|
||||
head -n1 git-revisions.txt | \
|
||||
awk '{print $$$(words $(PROJECT_DESCRIPTION) version);}'; \
|
||||
else \
|
||||
(git describe --dirty --abbrev=7 --tags --always --first-parent \
|
||||
2>/dev/null || echo rabbitmq_v0_0_0) | \
|
||||
sed -e 's/^rabbitmq_v//' -e 's/^v//' -e 's/_/./g' -e 's/-/+/' \
|
||||
-e 's/-/./g'; \
|
||||
fi)
|
||||
endif
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# RabbitMQ components.
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
# For RabbitMQ repositories, we want to checkout branches which match
|
||||
# the parent project. For instance, if the parent project is on a
|
||||
# release tag, dependencies must be on the same release tag. If the
|
||||
# parent project is on a topic branch, dependencies must be on the same
|
||||
# topic branch or fallback to `stable` or `master` whichever was the
|
||||
# base of the topic branch.
|
||||
|
||||
dep_amqp_client = git_rmq rabbitmq-erlang-client $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_amqp10_client = git_rmq rabbitmq-amqp1.0-client $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_amqp10_common = git_rmq rabbitmq-amqp1.0-common $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbit = git_rmq rabbitmq-server $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbit_common = git_rmq rabbitmq-common $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_amqp1_0 = git_rmq rabbitmq-amqp1.0 $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_auth_backend_amqp = git_rmq rabbitmq-auth-backend-amqp $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_auth_backend_cache = git_rmq rabbitmq-auth-backend-cache $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_auth_backend_http = git_rmq rabbitmq-auth-backend-http $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_auth_backend_ldap = git_rmq rabbitmq-auth-backend-ldap $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_auth_mechanism_ssl = git_rmq rabbitmq-auth-mechanism-ssl $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_aws = git_rmq rabbitmq-aws $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_boot_steps_visualiser = git_rmq rabbitmq-boot-steps-visualiser $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_cli = git_rmq rabbitmq-cli $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_codegen = git_rmq rabbitmq-codegen $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_consistent_hash_exchange = git_rmq rabbitmq-consistent-hash-exchange $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_ct_client_helpers = git_rmq rabbitmq-ct-client-helpers $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_ct_helpers = git_rmq rabbitmq-ct-helpers $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_delayed_message_exchange = git_rmq rabbitmq-delayed-message-exchange $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_dotnet_client = git_rmq rabbitmq-dotnet-client $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_event_exchange = git_rmq rabbitmq-event-exchange $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_federation = git_rmq rabbitmq-federation $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_federation_management = git_rmq rabbitmq-federation-management $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_java_client = git_rmq rabbitmq-java-client $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_jms_client = git_rmq rabbitmq-jms-client $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_jms_cts = git_rmq rabbitmq-jms-cts $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_jms_topic_exchange = git_rmq rabbitmq-jms-topic-exchange $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_lvc_exchange = git_rmq rabbitmq-lvc-exchange $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_management = git_rmq rabbitmq-management $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_management_agent = git_rmq rabbitmq-management-agent $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_management_exchange = git_rmq rabbitmq-management-exchange $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_management_themes = git_rmq rabbitmq-management-themes $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_message_timestamp = git_rmq rabbitmq-message-timestamp $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_metronome = git_rmq rabbitmq-metronome $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_mqtt = git_rmq rabbitmq-mqtt $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_objc_client = git_rmq rabbitmq-objc-client $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_peer_discovery_aws = git_rmq rabbitmq-peer-discovery-aws $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_peer_discovery_common = git_rmq rabbitmq-peer-discovery-common $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_peer_discovery_consul = git_rmq rabbitmq-peer-discovery-consul $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_peer_discovery_etcd = git_rmq rabbitmq-peer-discovery-etcd $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_peer_discovery_k8s = git_rmq rabbitmq-peer-discovery-k8s $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_random_exchange = git_rmq rabbitmq-random-exchange $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_recent_history_exchange = git_rmq rabbitmq-recent-history-exchange $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_routing_node_stamp = git_rmq rabbitmq-routing-node-stamp $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_rtopic_exchange = git_rmq rabbitmq-rtopic-exchange $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_server_release = git_rmq rabbitmq-server-release $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_sharding = git_rmq rabbitmq-sharding $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_shovel = git_rmq rabbitmq-shovel $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_shovel_management = git_rmq rabbitmq-shovel-management $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_stomp = git_rmq rabbitmq-stomp $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_toke = git_rmq rabbitmq-toke $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_top = git_rmq rabbitmq-top $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_tracing = git_rmq rabbitmq-tracing $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_trust_store = git_rmq rabbitmq-trust-store $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_test = git_rmq rabbitmq-test $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_web_dispatch = git_rmq rabbitmq-web-dispatch $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_web_stomp = git_rmq rabbitmq-web-stomp $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_web_stomp_examples = git_rmq rabbitmq-web-stomp-examples $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_web_mqtt = git_rmq rabbitmq-web-mqtt $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_web_mqtt_examples = git_rmq rabbitmq-web-mqtt-examples $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_website = git_rmq rabbitmq-website $(current_rmq_ref) $(base_rmq_ref) live master
|
||||
dep_toke = git_rmq toke $(current_rmq_ref) $(base_rmq_ref) master
|
||||
|
||||
dep_rabbitmq_public_umbrella = git_rmq rabbitmq-public-umbrella $(current_rmq_ref) $(base_rmq_ref) master
|
||||
|
||||
# Third-party dependencies version pinning.
|
||||
#
|
||||
# We do that in this file, which is copied in all projects, to ensure
|
||||
# all projects use the same versions. It avoids conflicts and makes it
|
||||
# possible to work with rabbitmq-public-umbrella.
|
||||
|
||||
dep_cowboy = hex 2.6.1
|
||||
dep_cowlib = hex 2.7.0
|
||||
dep_jsx = hex 2.9.0
|
||||
dep_lager = hex 3.6.5
|
||||
dep_ra = git https://github.com/rabbitmq/ra.git master
|
||||
dep_ranch = hex 1.7.1
|
||||
dep_recon = hex 2.3.6
|
||||
dep_sysmon_handler = hex 1.1.0
|
||||
|
||||
RABBITMQ_COMPONENTS = amqp_client \
|
||||
amqp10_common \
|
||||
amqp10_client \
|
||||
rabbit \
|
||||
rabbit_common \
|
||||
rabbitmq_amqp1_0 \
|
||||
rabbitmq_auth_backend_amqp \
|
||||
rabbitmq_auth_backend_cache \
|
||||
rabbitmq_auth_backend_http \
|
||||
rabbitmq_auth_backend_ldap \
|
||||
rabbitmq_auth_mechanism_ssl \
|
||||
rabbitmq_aws \
|
||||
rabbitmq_boot_steps_visualiser \
|
||||
rabbitmq_cli \
|
||||
rabbitmq_codegen \
|
||||
rabbitmq_consistent_hash_exchange \
|
||||
rabbitmq_ct_client_helpers \
|
||||
rabbitmq_ct_helpers \
|
||||
rabbitmq_delayed_message_exchange \
|
||||
rabbitmq_dotnet_client \
|
||||
rabbitmq_event_exchange \
|
||||
rabbitmq_federation \
|
||||
rabbitmq_federation_management \
|
||||
rabbitmq_java_client \
|
||||
rabbitmq_jms_client \
|
||||
rabbitmq_jms_cts \
|
||||
rabbitmq_jms_topic_exchange \
|
||||
rabbitmq_lvc_exchange \
|
||||
rabbitmq_management \
|
||||
rabbitmq_management_agent \
|
||||
rabbitmq_management_exchange \
|
||||
rabbitmq_management_themes \
|
||||
rabbitmq_message_timestamp \
|
||||
rabbitmq_metronome \
|
||||
rabbitmq_mqtt \
|
||||
rabbitmq_objc_client \
|
||||
rabbitmq_peer_discovery_aws \
|
||||
rabbitmq_peer_discovery_common \
|
||||
rabbitmq_peer_discovery_consul \
|
||||
rabbitmq_peer_discovery_etcd \
|
||||
rabbitmq_peer_discovery_k8s \
|
||||
rabbitmq_random_exchange \
|
||||
rabbitmq_recent_history_exchange \
|
||||
rabbitmq_routing_node_stamp \
|
||||
rabbitmq_rtopic_exchange \
|
||||
rabbitmq_server_release \
|
||||
rabbitmq_sharding \
|
||||
rabbitmq_shovel \
|
||||
rabbitmq_shovel_management \
|
||||
rabbitmq_stomp \
|
||||
rabbitmq_toke \
|
||||
rabbitmq_top \
|
||||
rabbitmq_tracing \
|
||||
rabbitmq_trust_store \
|
||||
rabbitmq_web_dispatch \
|
||||
rabbitmq_web_mqtt \
|
||||
rabbitmq_web_mqtt_examples \
|
||||
rabbitmq_web_stomp \
|
||||
rabbitmq_web_stomp_examples \
|
||||
rabbitmq_website
|
||||
|
||||
# Several components have a custom erlang.mk/build.config, mainly
|
||||
# to disable eunit. Therefore, we can't use the top-level project's
|
||||
# erlang.mk copy.
|
||||
NO_AUTOPATCH += $(RABBITMQ_COMPONENTS)
|
||||
|
||||
ifeq ($(origin current_rmq_ref),undefined)
|
||||
ifneq ($(wildcard .git),)
|
||||
current_rmq_ref := $(shell (\
|
||||
ref=$$(LANG=C git branch --list | awk '/^\* \(.*detached / {ref=$$0; sub(/.*detached [^ ]+ /, "", ref); sub(/\)$$/, "", ref); print ref; exit;} /^\* / {ref=$$0; sub(/^\* /, "", ref); print ref; exit}');\
|
||||
if test "$$(git rev-parse --short HEAD)" != "$$ref"; then echo "$$ref"; fi))
|
||||
else
|
||||
current_rmq_ref := master
|
||||
endif
|
||||
endif
|
||||
export current_rmq_ref
|
||||
|
||||
ifeq ($(origin base_rmq_ref),undefined)
|
||||
ifneq ($(wildcard .git),)
|
||||
possible_base_rmq_ref := master
|
||||
ifeq ($(possible_base_rmq_ref),$(current_rmq_ref))
|
||||
base_rmq_ref := $(current_rmq_ref)
|
||||
else
|
||||
base_rmq_ref := $(shell \
|
||||
(git rev-parse --verify -q master >/dev/null && \
|
||||
git rev-parse --verify -q $(possible_base_rmq_ref) >/dev/null && \
|
||||
git merge-base --is-ancestor $$(git merge-base master HEAD) $(possible_base_rmq_ref) && \
|
||||
echo $(possible_base_rmq_ref)) || \
|
||||
echo master)
|
||||
endif
|
||||
else
|
||||
base_rmq_ref := master
|
||||
endif
|
||||
endif
|
||||
export base_rmq_ref
|
||||
|
||||
# Repository URL selection.
|
||||
#
|
||||
# First, we infer other components' location from the current project
|
||||
# repository URL, if it's a Git repository:
|
||||
# - We take the "origin" remote URL as the base
|
||||
# - The current project name and repository name is replaced by the
|
||||
# target's properties:
|
||||
# eg. rabbitmq-common is replaced by rabbitmq-codegen
|
||||
# eg. rabbit_common is replaced by rabbitmq_codegen
|
||||
#
|
||||
# If cloning from this computed location fails, we fallback to RabbitMQ
|
||||
# upstream which is GitHub.
|
||||
|
||||
# Macro to transform eg. "rabbit_common" to "rabbitmq-common".
|
||||
rmq_cmp_repo_name = $(word 2,$(dep_$(1)))
|
||||
|
||||
# Upstream URL for the current project.
|
||||
RABBITMQ_COMPONENT_REPO_NAME := $(call rmq_cmp_repo_name,$(PROJECT))
|
||||
RABBITMQ_UPSTREAM_FETCH_URL ?= https://github.com/rabbitmq/$(RABBITMQ_COMPONENT_REPO_NAME).git
|
||||
RABBITMQ_UPSTREAM_PUSH_URL ?= git@github.com:rabbitmq/$(RABBITMQ_COMPONENT_REPO_NAME).git
|
||||
|
||||
# Current URL for the current project. If this is not a Git clone,
|
||||
# default to the upstream Git repository.
|
||||
ifneq ($(wildcard .git),)
|
||||
git_origin_fetch_url := $(shell git config remote.origin.url)
|
||||
git_origin_push_url := $(shell git config remote.origin.pushurl || git config remote.origin.url)
|
||||
RABBITMQ_CURRENT_FETCH_URL ?= $(git_origin_fetch_url)
|
||||
RABBITMQ_CURRENT_PUSH_URL ?= $(git_origin_push_url)
|
||||
else
|
||||
RABBITMQ_CURRENT_FETCH_URL ?= $(RABBITMQ_UPSTREAM_FETCH_URL)
|
||||
RABBITMQ_CURRENT_PUSH_URL ?= $(RABBITMQ_UPSTREAM_PUSH_URL)
|
||||
endif
|
||||
|
||||
# Macro to replace the following pattern:
|
||||
# 1. /foo.git -> /bar.git
|
||||
# 2. /foo -> /bar
|
||||
# 3. /foo/ -> /bar/
|
||||
subst_repo_name = $(patsubst %/$(1)/%,%/$(2)/%,$(patsubst %/$(1),%/$(2),$(patsubst %/$(1).git,%/$(2).git,$(3))))
|
||||
|
||||
# Macro to replace both the project's name (eg. "rabbit_common") and
|
||||
# repository name (eg. "rabbitmq-common") by the target's equivalent.
|
||||
#
|
||||
# This macro is kept on one line because we don't want whitespaces in
|
||||
# the returned value, as it's used in $(dep_fetch_git_rmq) in a shell
|
||||
# single-quoted string.
|
||||
dep_rmq_repo = $(if $(dep_$(2)),$(call subst_repo_name,$(PROJECT),$(2),$(call subst_repo_name,$(RABBITMQ_COMPONENT_REPO_NAME),$(call rmq_cmp_repo_name,$(2)),$(1))),$(pkg_$(1)_repo))
|
||||
|
||||
dep_rmq_commits = $(if $(dep_$(1)), \
|
||||
$(wordlist 3,$(words $(dep_$(1))),$(dep_$(1))), \
|
||||
$(pkg_$(1)_commit))
|
||||
|
||||
define dep_fetch_git_rmq
|
||||
fetch_url1='$(call dep_rmq_repo,$(RABBITMQ_CURRENT_FETCH_URL),$(1))'; \
|
||||
fetch_url2='$(call dep_rmq_repo,$(RABBITMQ_UPSTREAM_FETCH_URL),$(1))'; \
|
||||
if test "$$$$fetch_url1" != '$(RABBITMQ_CURRENT_FETCH_URL)' && \
|
||||
git clone -q -n -- "$$$$fetch_url1" $(DEPS_DIR)/$(call dep_name,$(1)); then \
|
||||
fetch_url="$$$$fetch_url1"; \
|
||||
push_url='$(call dep_rmq_repo,$(RABBITMQ_CURRENT_PUSH_URL),$(1))'; \
|
||||
elif git clone -q -n -- "$$$$fetch_url2" $(DEPS_DIR)/$(call dep_name,$(1)); then \
|
||||
fetch_url="$$$$fetch_url2"; \
|
||||
push_url='$(call dep_rmq_repo,$(RABBITMQ_UPSTREAM_PUSH_URL),$(1))'; \
|
||||
fi; \
|
||||
cd $(DEPS_DIR)/$(call dep_name,$(1)) && ( \
|
||||
$(foreach ref,$(call dep_rmq_commits,$(1)), \
|
||||
git checkout -q $(ref) >/dev/null 2>&1 || \
|
||||
) \
|
||||
(echo "error: no valid pathspec among: $(call dep_rmq_commits,$(1))" \
|
||||
1>&2 && false) ) && \
|
||||
(test "$$$$fetch_url" = "$$$$push_url" || \
|
||||
git remote set-url --push origin "$$$$push_url")
|
||||
endef
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Component distribution.
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
list-dist-deps::
|
||||
@:
|
||||
|
||||
prepare-dist::
|
||||
@:
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Umbrella-specific settings.
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
# If this project is under the Umbrella project, we override $(DEPS_DIR)
|
||||
# to point to the Umbrella's one. We also disable `make distclean` so
|
||||
# $(DEPS_DIR) is not accidentally removed.
|
||||
|
||||
ifneq ($(wildcard ../../UMBRELLA.md),)
|
||||
UNDER_UMBRELLA = 1
|
||||
else ifneq ($(wildcard UMBRELLA.md),)
|
||||
UNDER_UMBRELLA = 1
|
||||
endif
|
||||
|
||||
ifeq ($(UNDER_UMBRELLA),1)
|
||||
ifneq ($(PROJECT),rabbitmq_public_umbrella)
|
||||
DEPS_DIR ?= $(abspath ..)
|
||||
endif
|
||||
|
||||
ifneq ($(filter distclean distclean-deps,$(MAKECMDGOALS)),)
|
||||
SKIP_DEPS = 1
|
||||
endif
|
||||
endif
|
||||
261
deps/rabbitmq_prometheus/src/collectors/prometheus_rabbitmq_core_metrics_collector.erl
vendored
Normal file
261
deps/rabbitmq_prometheus/src/collectors/prometheus_rabbitmq_core_metrics_collector.erl
vendored
Normal file
|
|
@ -0,0 +1,261 @@
|
|||
%% The contents of this file are subject to the Mozilla Public License
|
||||
%% Version 1.1 (the "License"); you may not use this file except in
|
||||
%% compliance with the License. You may obtain a copy of the License at
|
||||
%% http://www.mozilla.org/MPL/
|
||||
%%
|
||||
%% Software distributed under the License is distributed on an "AS IS"
|
||||
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
||||
%% License for the specific language governing rights and limitations
|
||||
%% under the License.
|
||||
%%
|
||||
%% The Original Code is RabbitMQ.
|
||||
%%
|
||||
%% The Initial Developer of the Original Code is GoPivotal, Inc.
|
||||
%% Copyright (c) 2007-2019 Pivotal Software, Inc. All rights reserved.
|
||||
%%
|
||||
-module(prometheus_rabbitmq_core_metrics_collector).
|
||||
-export([register/0,
|
||||
register/1,
|
||||
deregister_cleanup/1,
|
||||
collect_mf/2,
|
||||
collect_metrics/2]).
|
||||
|
||||
-import(prometheus_model_helpers, [create_mf/4,
|
||||
create_mf/5,
|
||||
label_pairs/1,
|
||||
gauge_metrics/1,
|
||||
gauge_metric/1,
|
||||
gauge_metric/2,
|
||||
counter_metric/1,
|
||||
counter_metric/2,
|
||||
untyped_metric/1,
|
||||
untyped_metric/2]).
|
||||
|
||||
-include_lib("prometheus/include/prometheus.hrl").
|
||||
-include_lib("rabbit_common/include/rabbit.hrl").
|
||||
|
||||
-behaviour(prometheus_collector).
|
||||
|
||||
-define(METRIC_NAME_PREFIX, "rabbitmq_core_").
|
||||
|
||||
-define(METRICS,
|
||||
[
|
||||
{connection_coarse_metrics, [{2, connection_recv_oct, counter, "Count of octects received on the connection."},
|
||||
{3, connection_send_oct, counter, "Count of octects sent on the connection."},
|
||||
{4, connection_reductions, counter, "Count of reductions that take place on the queue process."}
|
||||
]},
|
||||
{queue_coarse_metrics, [{2, queue_messages_ready, gauge, "Number of messages ready to be delivered to clients."},
|
||||
{3, queue_messages_unacknowledge, gauge, "Number of messages delivered to clients but not yet acknowledged."},
|
||||
{4, queue_messages, gauge, "Sum of ready and unacknowledged messages (queue depth)."},
|
||||
{5, queue_reductions, counter, "Count of reductions that take place on the queue process."}
|
||||
]},
|
||||
{channel_exchange_metrics, [{2, channel_exchange_publish, gauge, "Count of messages published."},
|
||||
{3, channel_exchange_confirm, gauge, "Count of messages confirmed."},
|
||||
{4, channel_exchange_return_unroutable, gauge, "Count of messages returned to publisher as unroutable."}
|
||||
]},
|
||||
{channel_process_metrics, [{2, channel_process_reductions, counter, "Count of reductions that take place on the channel process."}
|
||||
]},
|
||||
{queue_metrics, [{2, queue_disk_reads, gauge, "Total number of times messages have been read from disk by this queue.", disk_reads},
|
||||
{2, queue_disk_writes, gauge, "Total number of times messages have been written to disk by this queue.", disk_writes}
|
||||
]},
|
||||
{node_persister_metrics,
|
||||
[{2, node_io_read_count, counter, "Read operations since node start.", io_read_count},
|
||||
{2, node_io_read_bytes, gauge, "Bytes read since node start.", io_read_bytes},
|
||||
{2, node_io_read_time, gauge, "Total time of read operations.", io_read_time},
|
||||
{2, node_io_write_count, counter, "Write operations since node start.", io_write_count},
|
||||
{2, node_io_write_bytes, gauge, "Bytes written since node start.", io_write_bytes},
|
||||
{2, node_io_write_time, gauge, "Total time of write operations.", io_write_time},
|
||||
{2, node_io_sync_count, counter, "Sync operations since node start.", io_sync_count},
|
||||
{2, node_io_sync_time, gauge, "Total time of sync operations.", io_sync_time},
|
||||
{2, node_io_seek_count, counter, "Seek operations since node start.", io_seek_count},
|
||||
{2, node_io_seek_time, gauge, "Total time of seek operations.", io_seek_time},
|
||||
{2, node_io_reopen_count, counter, "Times files have been reopened by the file handle cache.", io_reopen_count},
|
||||
{2, node_mnesia_ram_tx_count, counter, "Mnesia transactions in RAM since node start.",
|
||||
mnesia_ram_tx_count},
|
||||
{2, node_mnesia_disk_tx_count, counter, "Mnesia transactions in disk since node start.",
|
||||
mnesia_disk_tx_count},
|
||||
{2, node_msg_store_read_count, counter, "Read operations in the message store since node start.",
|
||||
msg_store_read_count},
|
||||
{2, node_msg_store_write_count, counter, "Write operations in the message store since node start.",
|
||||
msg_store_write_count},
|
||||
{2, queue_index_journal_write_count, counter, "Write operations in the queue index journal since node start.", queue_index_journal_write_count},
|
||||
{2, queue_index_write_count, counter, "Queue index write operations since node start.", index_write_count},
|
||||
{2, queue_index_read_count, counter, "Queue index read operations since node start.", index_read_count},
|
||||
{2, queue_io_file_handle_open_attempt_count, counter, "File descriptor open attempts.",
|
||||
io_file_handle_open_attempt_count},
|
||||
{2, queue_io_file_handle_open_attempt_time, gauge, "Total time of file descriptor open attempts.",
|
||||
io_file_handle_open_attempt_time}
|
||||
]},
|
||||
{node_coarse_metrics,
|
||||
[{2, node_fd_used, gauge, "File descriptors used.", fd_used},
|
||||
{2, node_sockets_used, gauge, "Sockets used.", sockets_used},
|
||||
{2, node_mem_used, gauge, "Memory used in bytes.", mem_used},
|
||||
{2, node_disk_free, gauge, "Disk free in bytes.", disk_free},
|
||||
{2, node_proc_used, gauge, "Erlang processes used.", proc_used},
|
||||
{2, node_gc_num, counter, "GC runs.", gc_num},
|
||||
{2, node_gc_bytes_reclaimed, counter, "Bytes reclaimed by GC.", gc_bytes_reclaimed},
|
||||
{2, node_context_switches, counter, "Context switches since node start.", context_switches}
|
||||
]},
|
||||
{connection_churn_metrics,
|
||||
[{2, connection_created, counter, "Connections created."},
|
||||
{3, connection_closed, counter, "Connections closed."},
|
||||
{4, channel_created, counter, "Channels created."},
|
||||
{5, channel_closed, counter, "Channels closed."},
|
||||
{6, queue_declared, counter, "Queues declared."},
|
||||
{7, queue_deleted, counter, "Queues deleted."}
|
||||
]},
|
||||
{node_node_metrics,
|
||||
[{2, node_node_send_bytes, counter, "Count of bytes sent to node.", send_bytes},
|
||||
{2, node_node_recv_bytes, counter, "Count of bytes received from node.", recv_bytes}
|
||||
]},
|
||||
{channel_queue_metrics,
|
||||
[{2, channel_queue_get, counter, "Count of messages delivered in acknowledgement mode in response to basic.get."},
|
||||
{3, channel_queue_get_no_ack, counter, "Count of messages delivered in no-acknowledgement mode in response to basic.get."},
|
||||
{4, channel_queue_deliver, counter, "Count of messages delivered in acknowledgement mode to consumers."},
|
||||
{5, channel_queue_deliver_no_ack, counter, "Count of messages delivered in no-acknowledgement mode to consumers."},
|
||||
{6, channel_queue_redeliver, counter, "Count of subset of delivered messages which had the redelivered flag set."},
|
||||
{7, channel_queue_ack, counter, "Count of messages acknowledged."},
|
||||
{8, channel_queue_get_empty, counter, "Count of basic.get operations on empty queues."}
|
||||
]},
|
||||
{channel_metrics,
|
||||
[{2, channel_consumer_count, gauge, "Consumers count.", consumer_count},
|
||||
{2, channel_messages_unacknowledged, gauge, "Count of messages unacknowledged.", messages_unacknowledged},
|
||||
{2, channel_messages_unconfirmed, gauge, "Count of messages unconfirmed.", messages_unconfirmed},
|
||||
{2, channel_messages_uncommited, gauge, "Count of messages uncommited.", messages_uncommited},
|
||||
{2, channel_messages_prefetch_count, gauge, "Limit to the number of unacknowledged messages on every connection on a channel.", prefetch_count},
|
||||
{2, channel_messages_global_prefetch_count, gauge, "Global limit to the number of unacknowledged messages shared between all connections on a channel.", global_prefetch_count}
|
||||
]},
|
||||
{connection_metrics,
|
||||
[{2, connection_recv_count, counter, "Count of bytes received on the connection.", recv_count},
|
||||
{2, connection_send_count, counter, "Count of bytes send on the connection.", send_count}
|
||||
]},
|
||||
{node_metrics,
|
||||
[{2, node_fd_total, gauge, "File descriptors available.", fd_total},
|
||||
{2, node_sockets_total, gauge, "Sockets available.", sockets_total},
|
||||
{2, node_mem_limit, gauge, "Memory usage high watermark.", mem_limit},
|
||||
{2, node_disk_free_limit, gauge, "Free disk space low watermark.", disk_free_limit},
|
||||
{2, node_proc_total, gauge, "Erlang processes limit.", proc_total},
|
||||
{2, node_uptime, gauge, "Time in milliseconds since node start.", uptime},
|
||||
{2, node_run_queue, gauge, "Runtime run queue.", run_queue},
|
||||
{2, node_processors, gauge, "Logical processors.", processors},
|
||||
{2, node_net_ticktime, gauge, "Periodic tick interval between all pairs of nodes to maintain the connections and to detect disconnections.", net_ticktime}
|
||||
]},
|
||||
{channel_queue_exchange_metrics,
|
||||
[{2, channel_queue_exchange_publish, counter, "Count of messages published."}
|
||||
]}
|
||||
]).
|
||||
|
||||
-define(TOTALS, [
|
||||
{connection_created, connections, gauge, "RabbitMQ Connections count."},
|
||||
{channel_created, channels, gauge, "RabbitMQ Channels count."},
|
||||
{consumer_created, consumers, gauge, "RabbitMQ Consumers count."},
|
||||
{queue_metrics, queues, gauge, "RabbitMQ Queues count."}
|
||||
]).
|
||||
|
||||
%%====================================================================
|
||||
%% Collector API
|
||||
%%====================================================================
|
||||
|
||||
register() ->
|
||||
register(default).
|
||||
|
||||
register(Registry) ->
|
||||
ok = prometheus_registry:register_collector(Registry, ?MODULE).
|
||||
|
||||
deregister_cleanup(_) -> ok.
|
||||
|
||||
collect_mf(_Registry, Callback) ->
|
||||
[begin
|
||||
Data = ets:tab2list(Table),
|
||||
mf(Callback, Contents, Data)
|
||||
end || {Table, Contents} <- ?METRICS],
|
||||
[begin
|
||||
Size = ets:info(Table, size),
|
||||
mf_totals(Callback, Name, Type, Help, Size)
|
||||
end || {Table, Name, Type, Help} <- ?TOTALS],
|
||||
ok.
|
||||
|
||||
mf(Callback, Contents, Data) ->
|
||||
[begin
|
||||
Fun = fun(D) -> element(Index, D) end,
|
||||
Callback(create_mf(?METRIC_NAME(Name), Help, catch_boolean(Type), ?MODULE,
|
||||
{Type, Fun, Data}))
|
||||
end || {Index, Name, Type, Help} <- Contents],
|
||||
[begin
|
||||
Fun = fun(D) -> proplists:get_value(Key, element(Index, D)) end,
|
||||
Callback(create_mf(?METRIC_NAME(Name), Help, catch_boolean(Type), ?MODULE,
|
||||
{Type, Fun, Data}))
|
||||
end || {Index, Name, Type, Help, Key} <- Contents].
|
||||
|
||||
mf_totals(Callback, Name, Type, Help, Size) ->
|
||||
Callback(create_mf(?METRIC_NAME(Name), Help, catch_boolean(Type), Size)).
|
||||
|
||||
collect_metrics(_, {Type, Fun, Items}) ->
|
||||
[metric(Type, labels(Item), Fun(Item)) || Item <- Items].
|
||||
|
||||
labels(Item) ->
|
||||
label(element(1, Item)).
|
||||
|
||||
label(A) when is_atom(A) ->
|
||||
%% Don't need node label
|
||||
[];
|
||||
label(L) ->
|
||||
label0(L).
|
||||
|
||||
label0(#resource{virtual_host = VHost, kind = exchange, name = Name}) ->
|
||||
[{vhost, VHost}, {exchange, Name}];
|
||||
label0(#resource{virtual_host = VHost, kind = queue, name = Name}) ->
|
||||
[{vhost, VHost}, {queue, Name}];
|
||||
label0({P, {#resource{virtual_host = QVHost, kind = queue, name = QName},
|
||||
#resource{virtual_host = EVHost, kind = exchange, name = EName}}}) when is_pid(P) ->
|
||||
%% channel_queue_exchange_metrics {channel_id, {queue_id, exchange_id}}
|
||||
[{channel, P}, {queue_vhost, QVHost}, {queue_name, QName},
|
||||
{exchange_vhost, EVHost}, {exchange_name, EName}];
|
||||
label0({A1, A2}) when is_atom(A1) and is_atom(A2) ->
|
||||
%% node_node_metrics, only need the remote node
|
||||
[{node, A2}];
|
||||
label0({I1, I2}) ->
|
||||
label(I1) ++ label(I2);
|
||||
label0(P) when is_pid(P) ->
|
||||
[{channel, P}].
|
||||
|
||||
metric(counter, Labels, Value) ->
|
||||
emit_counter_metric_if_defined(Labels, Value);
|
||||
metric(gauge, Labels, Value) ->
|
||||
emit_gauge_metric_if_defined(Labels, Value);
|
||||
metric(untyped, Labels, Value) ->
|
||||
untyped_metric(Labels, Value);
|
||||
metric(boolean, Labels, Value0) ->
|
||||
Value = case Value0 of
|
||||
true -> 1;
|
||||
false -> 0;
|
||||
undefined -> undefined
|
||||
end,
|
||||
untyped_metric(Labels, Value).
|
||||
|
||||
|
||||
%%====================================================================
|
||||
%% Private Parts
|
||||
%%====================================================================
|
||||
catch_boolean(boolean) ->
|
||||
untyped;
|
||||
catch_boolean(T) ->
|
||||
T.
|
||||
|
||||
emit_counter_metric_if_defined(Labels, Value) ->
|
||||
case Value of
|
||||
undefined -> undefined;
|
||||
'' ->
|
||||
counter_metric(Labels, undefined);
|
||||
Value ->
|
||||
counter_metric(Labels, Value)
|
||||
end.
|
||||
|
||||
emit_gauge_metric_if_defined(Labels, Value) ->
|
||||
case Value of
|
||||
undefined -> undefined;
|
||||
'' ->
|
||||
gauge_metric(Labels, undefined);
|
||||
Value ->
|
||||
gauge_metric(Labels, Value)
|
||||
end.
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
%% The contents of this file are subject to the Mozilla Public License
|
||||
%% Version 1.1 (the "License"); you may not use this file except in
|
||||
%% compliance with the License. You may obtain a copy of the License at
|
||||
%% http://www.mozilla.org/MPL/
|
||||
%%
|
||||
%% Software distributed under the License is distributed on an "AS IS"
|
||||
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
||||
%% License for the specific language governing rights and limitations
|
||||
%% under the License.
|
||||
%%
|
||||
%% The Original Code is RabbitMQ.
|
||||
%%
|
||||
%% The Initial Developer of the Original Code is GoPivotal, Inc.
|
||||
%% Copyright (c) 2007-2019 Pivotal Software, Inc. All rights reserved.
|
||||
%%
|
||||
|
||||
-module(rabbit_prometheus_app).
|
||||
|
||||
-behaviour(application).
|
||||
-export([start/2, stop/1, reset_dispatcher/1]).
|
||||
|
||||
-behaviour(supervisor).
|
||||
-export([init/1]).
|
||||
|
||||
-define(TCP_CONTEXT, rabbitmq_prometheus_tcp).
|
||||
-define(TLS_CONTEXT, rabbitmq_prometheus_tls).
|
||||
-define(DEFAULT_PORT, 15673).
|
||||
|
||||
start(_Type, _StartArgs) ->
|
||||
%% TCP listener uses prometheus.tcp.*.
|
||||
%% TLS listener uses prometheus.ssl.*
|
||||
start_configured_listener(true),
|
||||
supervisor:start_link({local,?MODULE},?MODULE,[]).
|
||||
|
||||
stop(_State) ->
|
||||
unregister_all_contexts(),
|
||||
ok.
|
||||
|
||||
|
||||
init(_) ->
|
||||
{ok, {{one_for_one, 3, 10}, []}}.
|
||||
|
||||
reset_dispatcher(_IgnoreApps) ->
|
||||
unregister_all_contexts(),
|
||||
start_configured_listener(false).
|
||||
|
||||
-spec start_configured_listener(boolean()) -> ok.
|
||||
start_configured_listener(NeedLogStartup) ->
|
||||
Listeners = case {has_configured_tcp_listener(),
|
||||
has_configured_tls_listener()} of
|
||||
{false, false} ->
|
||||
%% nothing is configured
|
||||
[get_tcp_listener()];
|
||||
{false, true} ->
|
||||
[get_tls_listener()];
|
||||
{true, false} ->
|
||||
[get_tcp_listener()];
|
||||
{true, true} ->
|
||||
[get_tcp_listener(),
|
||||
get_tls_listener()]
|
||||
end,
|
||||
[ start_listener(Listener, NeedLogStartup)
|
||||
|| Listener <- Listeners ].
|
||||
|
||||
has_configured_tcp_listener() ->
|
||||
has_configured_listener(tcp_config).
|
||||
|
||||
has_configured_tls_listener() ->
|
||||
has_configured_listener(ssl_config).
|
||||
|
||||
has_configured_listener(Key) ->
|
||||
case application:get_env(rabbitmq_prometheus, Key, undefined) of
|
||||
undefined -> false;
|
||||
_ -> true
|
||||
end.
|
||||
|
||||
get_tls_listener() ->
|
||||
{ok, Listener0} = application:get_env(rabbitmq_prometheus, ssl_config),
|
||||
[{ssl, true} | Listener0].
|
||||
|
||||
get_tcp_listener() ->
|
||||
application:get_env(rabbitmq_prometheus, tcp_config, []).
|
||||
|
||||
start_listener(Listener, NeedLogStartup) ->
|
||||
{Type, ContextName} = case is_tls(Listener) of
|
||||
true -> {tls, ?TLS_CONTEXT};
|
||||
false -> {tcp, ?TCP_CONTEXT}
|
||||
end,
|
||||
{ok, _} = register_context(ContextName, Listener),
|
||||
case NeedLogStartup of
|
||||
true -> log_startup(Type, Listener);
|
||||
false -> ok
|
||||
end,
|
||||
ok.
|
||||
|
||||
register_context(ContextName, Listener0) ->
|
||||
M0 = maps:from_list(Listener0),
|
||||
%% include default port if it's not provided in the config
|
||||
%% as Cowboy won't start if the port is missing
|
||||
M1 = maps:merge(#{port => ?DEFAULT_PORT}, M0),
|
||||
rabbit_web_dispatch:register_context_handler(
|
||||
ContextName, maps:to_list(M1), "",
|
||||
rabbit_prometheus_dispatcher:build_dispatcher(),
|
||||
"RabbitMQ Prometheus").
|
||||
|
||||
unregister_all_contexts() ->
|
||||
rabbit_web_dispatch:unregister_context(?TCP_CONTEXT),
|
||||
rabbit_web_dispatch:unregister_context(?TLS_CONTEXT).
|
||||
|
||||
log_startup(tcp, Listener) ->
|
||||
rabbit_log:info("Prometheus metrics: HTTP (non-TLS) listener started on port ~w", [port(Listener)]);
|
||||
log_startup(tls, Listener) ->
|
||||
rabbit_log:info("Prometheus metrics: HTTPS listener started on port ~w", [port(Listener)]).
|
||||
|
||||
|
||||
port(Listener) ->
|
||||
proplists:get_value(port, Listener, ?DEFAULT_PORT).
|
||||
|
||||
is_tls(Listener) ->
|
||||
case proplists:get_value(ssl, Listener) of
|
||||
undefined -> false;
|
||||
false -> false;
|
||||
_ -> true
|
||||
end.
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
%% The contents of this file are subject to the Mozilla Public License
|
||||
%% Version 1.1 (the "License"); you may not use this file except in
|
||||
%% compliance with the License. You may obtain a copy of the License at
|
||||
%% http://www.mozilla.org/MPL/
|
||||
%%
|
||||
%% Software distributed under the License is distributed on an "AS IS"
|
||||
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
||||
%% License for the specific language governing rights and limitations
|
||||
%% under the License.
|
||||
%%
|
||||
%% The Original Code is RabbitMQ.
|
||||
%%
|
||||
%% The Initial Developer of the Original Code is GoPivotal, Inc.
|
||||
%% Copyright (c) 2007-2019 Pivotal Software, Inc. All rights reserved.
|
||||
%%
|
||||
|
||||
-module(rabbit_prometheus_dispatcher).
|
||||
|
||||
-export([build_dispatcher/0]).
|
||||
|
||||
-define(DEFAULT_PATH, "/metrics").
|
||||
|
||||
build_dispatcher() ->
|
||||
{ok, _} = application:ensure_all_started(prometheus),
|
||||
maybe_register_collectors(),
|
||||
prometheus_http_impl:setup(),
|
||||
cowboy_router:compile([{'_', dispatcher()}]).
|
||||
|
||||
dispatcher() ->
|
||||
[{path() ++ "/[:registry]", rabbit_prometheus_handler, []}].
|
||||
|
||||
maybe_register_collectors() ->
|
||||
prometheus_registry:register_collectors([prometheus_rabbitmq_core_metrics_collector]).
|
||||
|
||||
path() ->
|
||||
Config = application:get_env(rabbitmq_prometheus, path, []),
|
||||
proplists:get_value(path, Config, ?DEFAULT_PATH).
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
%% The contents of this file are subject to the Mozilla Public License
|
||||
%% Version 1.1 (the "License"); you may not use this file except in
|
||||
%% compliance with the License. You may obtain a copy of the License at
|
||||
%% http://www.mozilla.org/MPL/
|
||||
%%
|
||||
%% Software distributed under the License is distributed on an "AS IS"
|
||||
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
||||
%% License for the specific language governing rights and limitations
|
||||
%% under the License.
|
||||
%%
|
||||
%% The Original Code is RabbitMQ.
|
||||
%%
|
||||
%% The Initial Developer of the Original Code is GoPivotal, Inc.
|
||||
%% Copyright (c) 2007-2019 Pivotal Software, Inc. All rights reserved.
|
||||
%%
|
||||
-module(rabbit_prometheus_handler).
|
||||
|
||||
-export([init/2]).
|
||||
-export([generate_response/2, content_types_provided/2, is_authorized/2]).
|
||||
|
||||
%% ===================================================================
|
||||
%% Cowboy Handler Callbacks
|
||||
%% ===================================================================
|
||||
|
||||
init(Req, _State) ->
|
||||
{cowboy_rest, Req, #{}}.
|
||||
|
||||
content_types_provided(ReqData, Context) ->
|
||||
{[
|
||||
{<<"*/*">>, generate_response}
|
||||
], ReqData, Context}.
|
||||
|
||||
is_authorized(ReqData, Context) ->
|
||||
{true, ReqData, Context}.
|
||||
|
||||
%% ===================================================================
|
||||
%% Private functions
|
||||
%% ===================================================================
|
||||
|
||||
generate_response(ReqData, Context) ->
|
||||
{ok, Response, undefined} = prometheus_cowboy2_handler:init(ReqData, Context),
|
||||
{stop, Response, Context}.
|
||||
Loading…
Reference in New Issue