Skip to content

Commit c5026df

Browse files
committed
Initial commit
1 parent bfaed78 commit c5026df

File tree

5 files changed

+271
-0
lines changed

5 files changed

+271
-0
lines changed

.dockerignore

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
# Created by .ignore support plugin (hsz.mobi)
2+
### JetBrains template
3+
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
4+
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
5+
6+
# User-specific stuff:
7+
.idea/**/workspace.xml
8+
.idea/**/tasks.xml
9+
.idea/dictionaries
10+
11+
# Sensitive or high-churn files:
12+
.idea/**/dataSources/
13+
.idea/**/dataSources.ids
14+
.idea/**/dataSources.xml
15+
.idea/**/dataSources.local.xml
16+
.idea/**/sqlDataSources.xml
17+
.idea/**/dynamic.xml
18+
.idea/**/uiDesigner.xml
19+
20+
# Gradle:
21+
.idea/**/gradle.xml
22+
.idea/**/libraries
23+
24+
# CMake
25+
cmake-build-debug/
26+
27+
# Mongo Explorer plugin:
28+
.idea/**/mongoSettings.xml
29+
30+
## File-based project format:
31+
*.iws
32+
33+
## Plugin-specific files:
34+
35+
# IntelliJ
36+
out/
37+
38+
# mpeltonen/sbt-idea plugin
39+
.idea_modules/
40+
41+
# JIRA plugin
42+
atlassian-ide-plugin.xml
43+
44+
# Cursive Clojure plugin
45+
.idea/replstate.xml
46+
47+
# Crashlytics plugin (for Android Studio and IntelliJ)
48+
com_crashlytics_export_strings.xml
49+
crashlytics.properties
50+
crashlytics-build.properties
51+
fabric.properties
52+
### Python template
53+
# Byte-compiled / optimized / DLL files
54+
__pycache__/
55+
*.py[cod]
56+
*$py.class
57+
58+
# C extensions
59+
*.so
60+
61+
# Distribution / packaging
62+
.Python
63+
build/
64+
develop-eggs/
65+
dist/
66+
downloads/
67+
eggs/
68+
.eggs/
69+
lib/
70+
lib64/
71+
parts/
72+
sdist/
73+
var/
74+
wheels/
75+
*.egg-info/
76+
.installed.cfg
77+
*.egg
78+
79+
# PyInstaller
80+
# Usually these files are written by a python script from a template
81+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
82+
*.manifest
83+
*.spec
84+
85+
# Installer logs
86+
pip-log.txt
87+
pip-delete-this-directory.txt
88+
89+
# Unit test / coverage reports
90+
htmlcov/
91+
.tox/
92+
.coverage
93+
.coverage.*
94+
.cache
95+
nosetests.xml
96+
coverage.xml
97+
*.cover
98+
.hypothesis/
99+
100+
# Translations
101+
*.mo
102+
*.pot
103+
104+
# Django stuff:
105+
*.log
106+
local_settings.py
107+
108+
# Flask stuff:
109+
instance/
110+
.webassets-cache
111+
112+
# Scrapy stuff:
113+
.scrapy
114+
115+
# Sphinx documentation
116+
docs/_build/
117+
118+
# PyBuilder
119+
target/
120+
121+
# Jupyter Notebook
122+
.ipynb_checkpoints
123+
124+
# pyenv
125+
.python-version
126+
127+
# celery beat schedule file
128+
celerybeat-schedule
129+
130+
# SageMath parsed files
131+
*.sage.py
132+
133+
# Environments
134+
.env
135+
.venv
136+
env/
137+
venv/
138+
ENV/
139+
140+
# Spyder project settings
141+
.spyderproject
142+
.spyproject
143+
144+
# Rope project settings
145+
.ropeproject
146+
147+
# mkdocs documentation
148+
/site
149+
150+
# mypy
151+
.mypy_cache/
152+
153+
.gitignore
154+
Dockerfile
155+
LICENSE
156+
README.md
157+
.circleci/

Dockerfile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
FROM python:3.6-alpine3.6
2+
3+
WORKDIR /usr/src/app
4+
5+
COPY requirements.txt ./
6+
RUN pip install --no-cache-dir -r requirements.txt
7+
8+
COPY . .
9+
10+
CMD [ "python", "./app.py" ]

README.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Example Prometheus Instrumentation for Python
2+
3+
This is a quick example of how to instrument your Flask-based Python app
4+
with the Python Prometheus client.
5+
6+
This project is built with:
7+
8+
- Python 3.6.x
9+
10+
And is packaged as a Docker container. The two top level dependencies are:
11+
12+
- Flask==0.12.2
13+
- prometheus-client==0.0.21
14+
15+
See the [requirements file](./requirements.txt) for more details.
16+
17+
## Prometheus
18+
19+
[Prometheus](https://prometheus.io/) is a
20+
[Cloud Native](https://winderresearch.com/what-is-cloud-native/?utm_source=github&utm_medium=web&utm_content=link)
21+
monitoring application.
22+
23+
To instrument our Python code we need to manipulate the metrics each
24+
time a new HTTP request is received.
25+
26+
See [the application](./app.py) for more details.
27+
28+
## Building
29+
30+
This project is automatically built by Docker Automated Builds.
31+
32+
To build manually:
33+
34+
`docker build -t python-app .`
35+
36+
## Running
37+
38+
Simply open port 5000 when running as a container:
39+
40+
`docker run -p 5000:5000 --name python-app philwinder/prometheus-python`

app.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import random
2+
import time
3+
4+
from flask import Flask, render_template_string
5+
from prometheus_client import generate_latest, REGISTRY, Counter, Gauge, Histogram
6+
7+
app = Flask(__name__)
8+
9+
# A counter to count the total number of HTTP requests
10+
REQUESTS = Counter('http_requests_total', 'Total HTTP Requests (count)', ['method', 'endpoint'])
11+
12+
# A gauge (i.e. goes up and down) to monitor the total number of in progress requests
13+
IN_PROGRESS = Gauge('http_requests_inprogress', 'Number of in progress HTTP requests')
14+
15+
# A histogram to measure the latency of the HTTP requests
16+
TIMINGS = Histogram('http_requests_latency_seconds', 'HTTP request latency (seconds)')
17+
18+
19+
# Standard Flask route stuff.
20+
@app.route('/')
21+
# Helper annotation to measure how long a method takes and save as a histogram metric.
22+
@TIMINGS.time()
23+
# Helper annotation to increment a gauge when entering the method and decrementing when leaving.
24+
@IN_PROGRESS.track_inprogress()
25+
def hello_world():
26+
REQUESTS.labels(method='GET', endpoint="/").inc() # Increment the counter
27+
return 'Hello, World!'
28+
29+
30+
@app.route('/slow')
31+
@TIMINGS.time()
32+
@IN_PROGRESS.track_inprogress()
33+
def slow_request():
34+
REQUESTS.labels(method='GET', endpoint="/slow").inc()
35+
v = random.random()
36+
time.sleep(v)
37+
return render_template_string('<h1>Wow, that took {{v}} s!</h1>', v=v)
38+
39+
40+
@app.route('/hello/<name>')
41+
@IN_PROGRESS.track_inprogress()
42+
@TIMINGS.time()
43+
def index(name):
44+
REQUESTS.labels(method='GET', endpoint="/hello/<name>").inc()
45+
return render_template_string('<b>Hello {{name}}</b>!', name=name)
46+
47+
48+
@app.route('/metrics')
49+
@IN_PROGRESS.track_inprogress()
50+
@TIMINGS.time()
51+
def metrics():
52+
REQUESTS.labels(method='GET', endpoint="/metrics").inc()
53+
return generate_latest(REGISTRY)
54+
55+
56+
if __name__ == "__main__":
57+
app.run(host='0.0.0.0')

requirements.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
click==6.7
2+
Flask==0.12.2
3+
itsdangerous==0.24
4+
Jinja2==2.10
5+
MarkupSafe==1.0
6+
prometheus-client==0.0.21
7+
Werkzeug==0.12.2

0 commit comments

Comments
 (0)