Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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 .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ dist
.coverage.*
.coverage
.tox
examples/loadtest/logs/*
examples/storage/*
5 changes: 5 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
include setup.py README.rst MANIFEST.in LICENSE *.txt
recursive-include client_python/ *
graft tests
global-exclude *~
recursive-exclude dist/* examples/*
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -458,3 +458,22 @@ for family in text_string_to_metric_families("my_gauge 1.0\n"):
for sample in family.samples:
print("Name: {0} Labels: {1} Value: {2}".format(*sample))
```


## UWSGI sharedarea MODE

This mode enable uwsgi sharedarea memory to store all metrics and sync between processes.

To enable mode, setup `PROMETHEUS_UWSGI_SHAREDAREA` environment variable with sharedarea id value.

Example uwsgi config:

``` ini

[uwsgi]

#...

sharedarea=10

```
25 changes: 25 additions & 0 deletions examples/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
FROM python:2.7.8

ENV PYTHONUNBUFFERED=1

WORKDIR /usr/src/app

RUN apt-get update && apt-get install -y \
libxml2-dev libxslt-dev python-dev \
libyaml-dev \
graphviz

COPY requirements.txt requirements.txt

RUN pip install -U plop gprof2dot ipython
RUN pip install -r requirements.txt

RUN mkdir /app-entrypoint.d

#COPY app-entrypoint.sh /

#ENTRYPOINT ["/app-entrypoint.sh"]

ENTRYPOINT ["/bin/bash", "-c"]

#CMD ["echo 'hello'"]
22 changes: 22 additions & 0 deletions examples/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
current_dir = $(shell pwd)

docker-clean: docker-clean-containers

docker-clean-containers:
docker ps -q -f status=exited | xargs docker rm

docker-build:
@echo "Run development services via docker"
sudo docker-compose -f compose-uwsgi.yml build --force-rm #--no-cache

docker-stop:
@echo "Stop docker services"
sudo docker-compose -f compose-uwsgi.yml -f stop

docker-start:
@echo "Run development services via docker"
docker-compose -f compose-uwsgi.yml up --force-recreate

tank:
@echo "Tank load"
docker run --rm --net examples_default --link dev_flask_app:dev_flask_app -v $(current_dir)/loadtest/:/var/loadtest/ direvius/yandex-tank
15 changes: 15 additions & 0 deletions examples/app-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash
set -e

echo "Application entrypoint";

for f in /app-entrypoint.d/*; do
echo "File: $f";
case "$f" in
*.sh) echo "$0: running $f"; . "$f" ;;
*) echo "$0: ignoring $f" ;;
esac
echo
done

exec "$@";
24 changes: 24 additions & 0 deletions examples/compose-uwsgi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
version: "2.0"

services:
dev_flask_app:
image: dev_flask_app:latest
build:
dockerfile: Dockerfile
context: .
environment:
- PROMETEUS_STATUS=1
- prometheus_multiproc_dir=/usr/src/app/storage/prometheus/
#- PROMETHEUS_UWSGI_SHAREDAREA=1
- PYTHONUNBUFFERED=1

command:
- "rm -rf /usr/src/app/storage/prometheus/* && find /usr/src/app/ -name '*.pyc' -exec rm -f {} + && cd /prometheus_client && python /prometheus_client/setup.py install && cd /uwsgi_lib && python /uwsgi_lib/uwsgiconfig.py --build && cd /usr/src/app/ && /uwsgi_lib/uwsgi --ini=/usr/src/app/uwsgi.ini"
volumes:
- ./uwsgi.ini:/usr/src/app/uwsgi.ini
- ./:/usr/src/app/
- ../:/prometheus_client
- /projects/libs/uwsgi:/uwsgi_lib

ports:
- 8051:8051
54 changes: 54 additions & 0 deletions examples/flask_app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os

import prometheus_client
from flask import request, Response, Flask
from prometheus_client import Counter, Gauge, Summary, Histogram
from prometheus_client.core import CollectorRegistry
from string import ascii_letters
from random import choice

REGISTRY = CollectorRegistry(auto_describe=False)


requests_total = Counter("app:requests_total", "Total count of requests", ["method", "url_rule", "env_role"], registry=REGISTRY)
inprogress_total = Gauge("app:inprogress_total", "Total count of requests in progress", ["method", "url_rule", "env_role"], registry=REGISTRY)
request_duration_summary_sec = Summary("app:request_duration_summary_sec", "Request duration in seconds", ["method", "url_rule", "env_role", "rnd"], registry=REGISTRY)
request_duration_historam_sec = Histogram("app:request_duration_histogram_sec", "Request duration in seconds", ["method", "url_rule", "env_role", "rnd"], registry=REGISTRY)

random_counter = Counter("random_counter", "random counter", ["rnd"], registry=REGISTRY)

APP_ENV_ROLE = os.environ.get('APP_ROLE', 'unknown')

app = Flask(__name__)
app.debug = True


@app.route("/metrics")
def metrics():
text = "# Process in {0}\n".format(os.getpid())

return Response(text + prometheus_client.generate_latest(REGISTRY), mimetype="text/plain")


@app.route('/<path:path>')
@app.route('/')
def index(path='/'):
requests_total.labels(method=request.method, url_rule=path, env_role=APP_ENV_ROLE).inc()

#requests_total.labels(method=request.method, url_rule=path, env_role=APP_ENV_ROLE).inc()

rnd = ''.join([choice(ascii_letters) for x in xrange(10)])

text = "# Process in {0} rnd={1}\n".format(os.getpid(), rnd)

#random_counter.labels(rnd=rnd).inc()

#with request_duration_summary_sec.labels(method=request.method, url_rule=path, env_role=APP_ENV_ROLE, rnd=rnd).time():#, \
#request_duration_historam_sec.labels(method=request.method, url_rule=path, env_role=APP_ENV_ROLE, rnd=rnd).time():

return Response(text, mimetype="text/plain")

application = app
print("Debug app init")
8 changes: 8 additions & 0 deletions examples/loadtest/load.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[phantom]
address=dev_flask_app:8051 ;
rps_schedule=const(100, 1m) ;
connection_test=0 ;

ammofile=/var/loadtest/uris.txt
ammo_type=uri
writelog=1
20 changes: 20 additions & 0 deletions examples/loadtest/uris.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[Connection: close]
[Host: dev_flask_app]
[Cookie: None]

/api/v
/business/
/auto/
/starlife/
/politics/
/sport/
/kids/
/lifestyle/
/incidents/
/9may/
/health/
/newyear/
/kinomusic/
/games/
/scitech/
/
3 changes: 3 additions & 0 deletions examples/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Flask==0.10.1
#git+https://github.com/Lispython/client_python.git
#uwsgi==2.0.14
21 changes: 21 additions & 0 deletions examples/uwsgi.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[uwsgi]
chdir=/usr/src/app/
env = APP_ROLE=dev_uwsgi
wsgi-file = /usr/src/app/flask_app.py
master=True
vacuum=True
max-requests=5000
harakiri=120
post-buffering=65536
workers=1
#enable-threads=True
#listen=4000
# socket=0.0.0.0:8997
stats=/tmp/uwsgi-app.stats
#logger=syslog:uwsgi_app_stage,local0
buffer-size=65536
http = 0.0.0.0:8051
thunder-lock=True

sharedarea=1000
sharedarea=1000
Loading