Skip to content

Master #2

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

Open
wants to merge 89 commits into
base: 0.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
2877104
Update README.md
Gyvastis Apr 21, 2020
d8a1474
Update README.md
Gyvastis Apr 21, 2020
4b056c9
Update README.md
Gyvastis Apr 21, 2020
f446df0
Update README.md
Gyvastis Apr 21, 2020
1067fa8
Create LICENSE
Gyvastis Apr 21, 2020
b561957
Merge pull request #1 from comsave/add-license-1
Gyvastis Apr 21, 2020
5d75467
Update README.md
Gyvastis Apr 21, 2020
baa0159
Update README.md
Gyvastis Apr 21, 2020
c98c017
Update README.md
Gyvastis Apr 21, 2020
8e23012
Update README.md
Gyvastis Apr 21, 2020
828ee2c
init
Apr 21, 2020
f17717d
require ext-redis
Apr 21, 2020
271ecb7
init bundle
Apr 21, 2020
d62dc59
init config
Apr 21, 2020
328532a
init prometheus publisher
Apr 21, 2020
94dcdea
add pushgateway factory
Apr 22, 2020
59991c3
add redis storage adapter factory
Apr 22, 2020
b0a5b60
add prometheus & grafana to compose
Apr 22, 2020
382d1cb
update prometheus config
Apr 22, 2020
ceeec75
init tests
Apr 22, 2020
a734deb
add PrometheusPushTest
Apr 22, 2020
f0d447c
update PrometheusPushTest
Apr 22, 2020
425b7e0
update PushGatewayClient
Apr 22, 2020
30f372f
update PrometheusPushTest; populate PrometheusPushCommand
Apr 22, 2020
ac5c7be
update PrometheusPushTest
Apr 22, 2020
35b04eb
update services config
Apr 22, 2020
2e9a343
add serializer for prometheus responses
Apr 22, 2020
38f79d5
add composer description
Apr 22, 2020
224a4f3
update PrometheusClient to use POST to avoid query string limits
Apr 22, 2020
28e2ab2
simplify JmsSerializer
Apr 22, 2020
216a46d
prometheus response serializer update
Apr 23, 2020
24e972c
--amend
Apr 23, 2020
11bf48e
include metric type methods in PushGatewayClient
Apr 23, 2020
3356bfe
--amend
Apr 23, 2020
aef3188
--amend
Apr 23, 2020
ca57d38
update PrometheusPushTest
Apr 23, 2020
bb89ca9
Merge branch 'master' of github.com:comsave/morty-counts
Apr 23, 2020
36ac43e
move out usage of prometheus job name
Apr 23, 2020
5e86d1d
add multi node set up
Apr 23, 2020
abe92ea
update multinode config
Apr 23, 2020
f589792
update prometheus multi node config; add tests for multi-node & haproxy
Apr 24, 2020
e2c82fa
update prometheus config
Apr 24, 2020
13406fc
Update README.md
Gyvastis Apr 24, 2020
a17d32f
single node remove prometheus config
Apr 28, 2020
f6fb5a2
add cluster diagrams
Apr 28, 2020
eabad44
Merge branch 'master' of github.com:comsave/morty-counts
Apr 28, 2020
fb68a26
update diagrams
Apr 28, 2020
0049781
update prometheus config
Apr 28, 2020
d2874ce
update prometheus config
Apr 28, 2020
1aa4393
optimize tests
Apr 28, 2020
0debda3
clean up unit tests
Apr 28, 2020
db0eebf
update tests to use ->counter
Apr 29, 2020
0a1c3b0
extend PushGateway to accept basic auth
Apr 29, 2020
12a1463
add PromethusClient basic auth
Apr 29, 2020
6237d4e
rewrite pushgatewa
Apr 29, 2020
a9d22f0
update tests
Apr 29, 2020
0f03d1e
update readme
Apr 29, 2020
2bd14b9
update diagrams
Apr 29, 2020
dec0ec1
update diagrams
Apr 29, 2020
62cb347
readme update
Apr 29, 2020
142ebdf
Update README.md
Gyvastis Apr 29, 2020
07456b6
Update README.md
Gyvastis Apr 29, 2020
8103056
Update README.md
Gyvastis Apr 29, 2020
debcfb4
Update README.md
Gyvastis Apr 30, 2020
6873097
Update README.md
Gyvastis Apr 30, 2020
8df4312
add jms serializer fallback
Apr 30, 2020
b436ac6
Merge branch 'master' of github.com:comsave/morty-counts
Apr 30, 2020
9b844b1
add dependancy injection config
Apr 30, 2020
6abfbd3
update readme
Apr 30, 2020
9fc9dd5
update readme
Apr 30, 2020
123da5e
update autoload
May 1, 2020
7e265b6
update readme
May 1, 2020
29f4ca4
update configuration options & services
May 1, 2020
2f6ee09
cast redis port
May 4, 2020
388b40f
Update README.md
Gyvastis May 4, 2020
d9c7b81
update bundle name
May 4, 2020
9ea2143
Merge branch 'master' of github.com:comsave/morty-counts
May 4, 2020
8f28bd1
rename extension
May 4, 2020
4cbe5e7
update ConfigurationTest
May 4, 2020
62aedb0
Update README.md
Gyvastis May 5, 2020
f2ec783
proper prom call for current val
May 5, 2020
4dff5cb
Merge branch 'master' of github.com:comsave/morty-counts
May 5, 2020
de21556
update configuration
May 5, 2020
dd94c48
update configuration
May 5, 2020
53840ef
update configuration
May 5, 2020
6ba4392
update prometheus client dep
May 5, 2020
514e112
init collector registry override; add pre register event for a counter
May 5, 2020
a6cd125
add current value fetching
May 5, 2020
2b1b8fd
Update README.md
Gyvastis May 6, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.git
docker
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.idea/
vendor/
composer.lock
__pycache__
.DS_Store
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2020 Comsave

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
82 changes: 80 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,81 @@
# morty-counts
# PrometheusPushGatewayBundle

![](https://media.giphy.com/media/e6tJpLvjY8jXa/giphy.gif)
## Symfony Prometheus + PushGateway integration

Send metrics to Prometheus. +High Availability Setup

## Requirements

1. `Redis` (the service & the PHP extension): to act as a buffer before push and avoid latency in the code, and as a store for the current counter values.

2. `bin/console comsave:prometheus:push` cronjob: to push data periodically to Prometheus Pushgateway

## Configuration

In your `services.yml` add:

```yaml
comsave_prometheus_pushgateway:
prometheus:
host: 'prometheus:9090'
username: 'admin' # optional
password: 'duuude' # optional
instance: 'moms_basement:6666' # your server host/name/etc
pushgateway:
host: 'pushgateway:9191'
username: 'admin2' # optional
password: 'duuude2' # optional
redis: 'redis:6379'
metrics:
api: # metric namespace
- name: 'orders'
type: 'counter'
help: 'counts the number of orders'
prefetch_group_label: 'user_id' # optional & only available for the counter; prefetch current value from prometheus by grouping sum() query by this label and populate the counter if it's missing in redis cache
labels:
- 'order_id'
- 'user_id'
```

Add the bundle to your Symfony kernel.
```php
new Comsave\PrometheusPushGatewayBundle\ComsavePrometheusPushGatewayBundle(),
```

## How does it work?

### General Prometheus architecture overview

![](https://camo.githubusercontent.com/78b3b29d22cea8eee673e34fd204818ea532c171/68747470733a2f2f63646e2e6a7364656c6976722e6e65742f67682f70726f6d6574686575732f70726f6d65746865757340633334323537643036396336333036383564613335626365663038343633326666643564363230392f646f63756d656e746174696f6e2f696d616765732f6172636869746563747572652e737667)

### Single Node Prometheus + Pushgateway

Single node is pretty straightforward.

1. Use `PushGatewayClient` to create a metric. Metric is stored in `Redis`.
2. Use `PushGatewayClient` can be pushed manually or with a command. After push metrics stored in Redis are transported to the actual `PushGateway` service.
3. `Prometheus` periodically pulls in new metrics from `PushGateway`.

![](./images/basic_prometheus_cluster_setup.png)

### Multi-Node Prometheus + Pushgateway Cluster

Multi-node set up works with the basics described above, with a couple exceptions:

1. There's an `Haproxy` (or other load balancer) that decides which `PushGateway` will receive the `push`.
2. Each `Prometheus` pulls from every `PushGateway` in every node. That way each `Prometheus` has the latest metrics.
3. Each `Prometheus` pulls (federates) from other `Prometheus` nodes (all but itself) though less often. This ensures data integrity (sort of replication).

![](./images/advanced_prometheus_cluster_setup.png)

## Development

Start single node `docker-compose up -d`

Or multi node `docker-compose up -f docker-compose.multi-node.yml -d`

Tests `docker exec $(docker ps | grep _php | awk '{print $1}') vendor/bin/phpunit tests`

## License

MIT
37 changes: 37 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"name": "comsave/prometheus-pushgateway-bundle",
"description": "Symfony integration to push metrics to Prometheus + PushGateway",
"license": "MIT",
"require": {
"php": ">=7.3",
"comsave/dependency-injection-config-to-parameters": "^0.1.0",
"comsave/prometheus_client_php": "^1.0.5",
"jms/serializer": "^3.0|^2.0",
"symfony/config": "^3.4|^4.4",
"symfony/console": "^3.4|^4.4",
"symfony/http-kernel": "^3.4|^4.4"
},
"require-dev": {
"phpunit/phpunit": "^8.0",
"spatie/phpunit-snapshot-assertions": "^3.0"
},
"autoload": {
"psr-4": {
"Comsave\\PrometheusPushGatewayBundle\\": "src/PrometheusPushGatewayBundle"
}
},
"autoload-dev": {
"psr-4": {
"Comsave\\PrometheusPushGatewayBundle\\Tests\\": "tests"
}
},
"authors": [
{
"name": "Vaidas Bagdonas",
"email": "[email protected]"
}
],
"config": {
"sort-packages": true
}
}
101 changes: 101 additions & 0 deletions docker-compose.multi-node.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
version: "3"

services:
php:
build:
dockerfile: ./docker/php-fpm/Dockerfile
context: .
depends_on:
- redis
volumes:
- ./:/app

redis:
image: redis:alpine

haproxy:
image: haproxy:alpine
depends_on:
- prometheus
- prometheus2
- prometheus3
- pushgateway
- pushgateway2
- pushgateway3
volumes:
- ./docker/haproxy:/usr/local/etc/haproxy:ro

prometheus:
image: prom/prometheus
command:
- '--web.listen-address=:9091'
- '--config.file=/etc/prometheus/prometheus.yml'
- '--web.console.templates=/etc/prometheus/consoles'
- '--web.console.libraries=/etc/prometheus/console_libraries'
depends_on:
- pushgateway
ports:
- 9091:9091
volumes:
- ./docker/prometheus/prometheus1.yml/:/etc/prometheus/prometheus.yml

pushgateway:
image: prom/pushgateway
command:
- '--web.listen-address=:9191'
ports:
- 9191:9191

prometheus2:
image: prom/prometheus
command:
- '--web.listen-address=:9092'
- '--config.file=/etc/prometheus/prometheus.yml'
- '--web.console.templates=/etc/prometheus/consoles'
- '--web.console.libraries=/etc/prometheus/console_libraries'
depends_on:
- pushgateway2
ports:
- 9092:9092
volumes:
- ./docker/prometheus/prometheus2.yml/:/etc/prometheus/prometheus.yml

pushgateway2:
image: prom/pushgateway
command:
- '--web.listen-address=:9192'
ports:
- 9192:9192

prometheus3:
image: prom/prometheus
command:
- '--web.listen-address=:9093'
- '--config.file=/etc/prometheus/prometheus.yml'
- '--web.console.templates=/etc/prometheus/consoles'
- '--web.console.libraries=/etc/prometheus/console_libraries'
depends_on:
- pushgateway3
ports:
- 9093:9093
volumes:
- ./docker/prometheus/prometheus3.yml/:/etc/prometheus/prometheus.yml

pushgateway3:
image: prom/pushgateway
command:
- '--web.listen-address=:9193'
ports:
- 9193:9193

grafana:
image: grafana/grafana
depends_on:
- haproxy
ports:
- 3000:3000
volumes:
- ./docker/grafana/datasources1.yml:/etc/grafana/provisioning/datasources/datasources.yml
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_USERS_ALLOW_SIGN_UP=false
49 changes: 49 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
version: "3"

services:
php:
build:
dockerfile: ./docker/php-fpm/Dockerfile
context: .
depends_on:
- redis
volumes:
- ./:/app

redis:
image: redis:alpine

prometheus:
image: prom/prometheus
command:
- '--web.listen-address=:9090'
- '--config.file=/etc/prometheus/prometheus.yml'
- '--web.console.templates=/etc/prometheus/consoles'
- '--web.console.libraries=/etc/prometheus/console_libraries'
depends_on:
- pushgateway
ports:
- 9090:9090
volumes:
- ./docker/prometheus/prometheus.yml/:/etc/prometheus/prometheus.yml

pushgateway:
image: prom/pushgateway
command:
- '--web.listen-address=:9191'
- '--push.disable-consistency-check'
- '--persistence.interval=5m'
ports:
- 9191:9191

grafana:
image: grafana/grafana
depends_on:
- prometheus
ports:
- 3000:3000
volumes:
- ./docker/grafana/datasources.yml:/etc/grafana/provisioning/datasources/datasources.yml
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_USERS_ALLOW_SIGN_UP=false
8 changes: 8 additions & 0 deletions docker/grafana/datasources.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: 1

datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
8 changes: 8 additions & 0 deletions docker/grafana/datasources1.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: 1

datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://haproxy:9090
isDefault: true
31 changes: 31 additions & 0 deletions docker/haproxy/haproxy.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
global
# global settings here

defaults
# defaults here

frontend pushgateway_fe
bind :9191
mode tcp
default_backend pushgateway_be

backend pushgateway_be
mode tcp
balance roundrobin
default-server inter 1s
server pushgateway pushgateway:9191 check id 1
server pushgateway2 pushgateway2:9192 check id 2
server pushgateway3 pushgateway3:9193 check id 3

frontend prometheus_fe
bind :9090
mode tcp
default_backend prometheus_be

backend prometheus_be
mode tcp
balance roundrobin
default-server inter 1s
server prometheus prometheus:9091 check id 1
server prometheus2 prometheus2:9092 check id 2
server prometheus3 prometheus3:9093 check id 3
18 changes: 18 additions & 0 deletions docker/php-fpm/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM php:7.3-fpm

RUN apt-get update && apt-get install git -y

RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && \
php -r "if (hash_file('sha384', 'composer-setup.php') === 'e0012edf3e80b6978849f5eff0d4b4e4c79ff1609dd1e613307e16318854d24ae64f26d17af3ef0bf7cfb710ca74755a') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" && \
php composer-setup.php && \
php -r "unlink('composer-setup.php');" && \
mv composer.phar /usr/local/bin/composer && \
chmod +x /usr/local/bin/composer

RUN pecl install redis && docker-php-ext-enable redis
RUN apt-get install zip unzip -y

WORKDIR /app
COPY composer.* ./
RUN composer install
COPY ./* ./
9 changes: 9 additions & 0 deletions docker/prometheus/prometheus.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
global:
scrape_interval: 15s

scrape_configs:
- job_name: 'pushgateway'
honor_labels: true
scrape_interval: 500ms
static_configs:
- targets: ['pushgateway:9191']
Loading