Skip to content

Commit

Permalink
Revert Python services from uWSGI to Gunicorn + call Locust directly (#…
Browse files Browse the repository at this point in the history
…501)

* Revert "Python/Flask - Replaces gunicorn with uWSGI  (#463)"

This reverts commit b5b0024.

* bump gunicorn and adjust dockerfiles

* call locust directly in loadgenerator

* remove escapes from entrypoint

* update copyright year in touched files

Co-authored-by: Megan O'Keefe <[email protected]>
  • Loading branch information
j-windsor and askmeegs authored Jun 22, 2021
1 parent 55206c6 commit 368549b
Show file tree
Hide file tree
Showing 27 changed files with 154 additions and 170 deletions.
3 changes: 1 addition & 2 deletions .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,4 @@ disable=F0401, # import loading
E1101, # function members
R0801, # duplicate code
R0903, # public methods
R0915, # too many statements
R0914 # too many local variables
R0915 # too many statements
4 changes: 2 additions & 2 deletions dev-kubernetes-manifests/frontend.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2019 Google LLC
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -43,7 +43,7 @@ spec:
value: "true"
- name: SCHEME
value: "http"
# Valid levels are debug, info, warning, error, critical. If no valid level is set, defaults to info.
# Valid levels are debug, info, warning, error, critical. If no valid level is set, gunicorn will default to info.
- name: LOG_LEVEL
value: "info"
# Set to "true" to enable the CymbalBank logo + title
Expand Down
4 changes: 2 additions & 2 deletions dev-kubernetes-manifests/userservice.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2019 Google LLC
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -48,7 +48,7 @@ spec:
value: "3600"
- name: PRIV_KEY_PATH
value: "/root/.ssh/privatekey"
# Valid levels are debug, info, warning, error, critical. If no valid level is set, defaults to info.
# Valid levels are debug, info, warning, error, critical. If no valid level is set, gunicorn will default to info.
- name: LOG_LEVEL
value: "info"
envFrom:
Expand Down
4 changes: 2 additions & 2 deletions extras/cloudsql/kubernetes-manifests/frontend.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2019 Google LLC
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -46,7 +46,7 @@ spec:
value: "true"
- name: SCHEME
value: "http"
# Valid levels are debug, info, warning, error, critical. If no valid level is set, defaults to info.
# Valid levels are debug, info, warning, error, critical. If no valid level is set, gunicorn will default to info.
- name: LOG_LEVEL
value: "info"
- name: DEFAULT_USERNAME
Expand Down
4 changes: 2 additions & 2 deletions extras/cloudsql/kubernetes-manifests/userservice.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2020 Google LLC
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -48,7 +48,7 @@ spec:
value: "3600"
- name: PRIV_KEY_PATH
value: "/root/.ssh/privatekey"
# Valid levels are debug, info, warning, error, critical. If no valid level is set, defaults to info.
# Valid levels are debug, info, warning, error, critical. If no valid level is set, gunicorn will default to info.
- name: LOG_LEVEL
value: "info"
envFrom:
Expand Down
11 changes: 5 additions & 6 deletions src/contacts/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
# https://github.com/GoogleCloudPlatform/python-docker
FROM gcr.io/google-appengine/python


# show python logs as they occur
ENV PYTHONUNBUFFERED=0

Expand All @@ -38,11 +37,11 @@ ENV LOG_LEVEL info
ADD requirements.txt /app/requirements.txt
RUN pip install -r /app/requirements.txt

# Copy uwsgi conf
COPY uwsgi-conf.ini /uwsgi-conf.ini

# Add application code.
ADD *.py /app/

# Start server with user-provided PORT
CMD uwsgi --ini /uwsgi-conf.ini --http :${PORT}
# Copy logging configuration for gunicorn
COPY logging.conf /logging.conf

# Start server using gunicorn
CMD gunicorn -b :$PORT --threads 4 --log-config /logging.conf --log-level=$LOG_LEVEL "contacts:create_app()"
23 changes: 4 additions & 19 deletions src/contacts/contacts.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2020 Google LLC
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -189,24 +189,9 @@ def _shutdown():
"""Executed when web app is terminated."""
app.logger.info("Stopping contacts service.")

# set log formatting
date_format = "%Y-%m-%d %H:%M:%S"
message_format = '%(asctime)s | [%(levelname)s] | %(funcName)s | %(message)s'
logging.basicConfig(format= message_format, datefmt= date_format, stream=sys.stdout)

# set log level
log_levels = {
"DEBUG": logging.DEBUG,
"WARNING": logging.WARNING,
"INFO": logging.INFO,
"ERROR": logging.ERROR,
"CRITICAL": logging.CRITICAL
}
level = logging.INFO #default
user_log_level = os.environ.get("LOG_LEVEL")
if user_log_level is not None and user_log_level.upper() in log_levels:
level = log_levels.get(user_log_level.upper())
app.logger.setLevel(level)
# set up logger
app.logger.handlers = logging.getLogger("gunicorn.error").handlers
app.logger.setLevel(logging.getLogger("gunicorn.error").level)
app.logger.info("Starting contacts service.")

# Set up tracing and export spans to Cloud Trace.
Expand Down
33 changes: 33 additions & 0 deletions src/contacts/logging.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
[loggers]
keys=root, gunicorn.error, contacts

[handlers]
keys=console

[formatters]
keys=generic

[logger_root]
handlers=console

[logger_gunicorn.error]
formatter=generic
handlers=console
propagate=0
qualname=gunicorn.error

[logger_contacts]
formatter=generic
handlers=console
propagate=0
qualname=contacts

[handler_console]
class=StreamHandler
formatter=generic
args=(sys.stdout, )

[formatter_generic]
format=%(asctime)s | [%(levelname)s] | %(funcName)s | %(message)s
datefmt=%Y-%m-%d %H:%M:%S
class=logging.Formatter
2 changes: 1 addition & 1 deletion src/contacts/requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ google-cloud-core==1.4.1
google-cloud-trace==0.24.0
googleapis-common-protos==1.52.0
grpcio==1.30.0
gunicorn==20.1.0
idna==2.10
importlib-metadata==1.7.0
itsdangerous==1.1.0
Expand Down Expand Up @@ -46,7 +47,6 @@ requests==2.24.0
rsa==4.7
six==1.14.0
urllib3==1.25.9
uwsgi==2.0.19.1
wcwidth==0.2.5
webencodings==0.5.1
Werkzeug==1.0.1
Expand Down
4 changes: 2 additions & 2 deletions src/contacts/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ grpcio==1.30.0
# via
# -r requirements.in
# google-api-core
gunicorn==20.1.0
# via -r requirements.in
idna==2.10
# via
# -r requirements.in
Expand Down Expand Up @@ -200,8 +202,6 @@ urllib3==1.25.9
# via
# -r requirements.in
# requests
uwsgi==2.0.19.1
# via -r requirements.in
wcwidth==0.2.5
# via
# -r requirements.in
Expand Down
4 changes: 1 addition & 3 deletions src/contacts/tests/test_contacts.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2020 Google LLC
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -36,8 +36,6 @@
INVALID_ROUTING_NUMS,
)

LOG_LEVEL="info"

def create_new_contact(**kwargs):
"""Helper method for creating new contacts from template"""
example_contact = EXAMPLE_CONTACT.copy()
Expand Down
11 changes: 0 additions & 11 deletions src/contacts/uwsgi-conf.ini

This file was deleted.

13 changes: 5 additions & 8 deletions src/frontend/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2020 Google LLC
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -47,11 +47,8 @@ ADD static /app/static
ADD templates /app/templates
ADD *.py /app/

# Copy uwsgi conf
COPY uwsgi-conf.ini /uwsgi-conf.ini
# Copy logging configuration for gunicorn
COPY logging.conf /logging.conf

# Add application code.
ADD *.py /app/

# Start server with user-provided PORT
CMD uwsgi --ini /uwsgi-conf.ini --http :${PORT}
# Start server using gunicorn
CMD gunicorn -b :$PORT --threads 4 --log-config /logging.conf --log-level=$LOG_LEVEL "frontend:create_app()"
26 changes: 5 additions & 21 deletions src/frontend/frontend.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2020 Google LLC
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -20,7 +20,6 @@
import logging
import os
import socket
import sys
from decimal import Decimal

import requests
Expand Down Expand Up @@ -548,25 +547,10 @@ def format_currency(int_amount):
app.jinja_env.globals.update(format_timestamp_month=format_timestamp_month)
app.jinja_env.globals.update(format_timestamp_day=format_timestamp_day)

# set log formatting
date_format = "%Y-%m-%d %H:%M:%S"
message_format = '%(asctime)s | [%(levelname)s] | %(funcName)s | %(message)s'
logging.basicConfig(format= message_format, datefmt= date_format, stream=sys.stdout)

# set log level
log_levels = {
"DEBUG": logging.DEBUG,
"WARNING": logging.WARNING,
"INFO": logging.INFO,
"ERROR": logging.ERROR,
"CRITICAL": logging.CRITICAL
}
level = logging.INFO #default
user_log_level = os.environ.get("LOG_LEVEL")
if user_log_level is not None and user_log_level.upper() in log_levels:
level = log_levels.get(user_log_level.upper())
app.logger.setLevel(level)
app.logger.info("Starting frontend.")
# Set up logging
app.logger.handlers = logging.getLogger('gunicorn.error').handlers
app.logger.setLevel(logging.getLogger('gunicorn.error').level)
app.logger.info('Starting frontend service.')

# Set up tracing and export spans to Cloud Trace.
if os.environ['ENABLE_TRACING'] == "true":
Expand Down
33 changes: 33 additions & 0 deletions src/frontend/logging.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
[loggers]
keys=root, gunicorn.error, frontend

[handlers]
keys=console

[formatters]
keys=generic

[logger_root]
handlers=console

[logger_gunicorn.error]
formatter=generic
handlers=console
propagate=0
qualname=gunicorn.error

[logger_frontend]
formatter=generic
handlers=console
propagate=0
qualname=frontend

[handler_console]
class=StreamHandler
formatter=generic
args=(sys.stdout, )

[formatter_generic]
format=%(asctime)s | [%(levelname)s] | %(funcName)s | %(message)s
datefmt=%Y-%m-%d %H:%M:%S
class=logging.Formatter
4 changes: 2 additions & 2 deletions src/frontend/requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ flask==1.1.2
requests==2.23.0
pyjwt==1.7.1
cryptography==3.3.2
gunicorn==20.1.0
opentelemetry-sdk==0.13b0
opentelemetry-exporter-google-cloud==0.13b0
opentelemetry-tools-google-cloud==0.13b0
opentelemetry-instrumentation-flask==0.13b0
opentelemetry-instrumentation-sqlalchemy==0.13b0
opentelemetry-instrumentation-jinja2==0.13b0
opentelemetry-instrumentation-requests==0.13b0
uwsgi==2.0.19.1
opentelemetry-instrumentation-requests==0.13b0
4 changes: 2 additions & 2 deletions src/frontend/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ googleapis-common-protos==1.52.0
# via google-api-core
grpcio==1.30.0
# via google-api-core
gunicorn==20.1.0
# via -r requirements.in
idna==2.9
# via requests
itsdangerous==1.1.0
Expand Down Expand Up @@ -121,8 +123,6 @@ sqlalchemy==1.3.19
# via opentelemetry-instrumentation-sqlalchemy
urllib3==1.25.8
# via requests
uwsgi==2.0.19.1
# via -r requirements.in
werkzeug==1.0.1
# via flask
wrapt==1.12.1
Expand Down
11 changes: 0 additions & 11 deletions src/frontend/uwsgi-conf.ini

This file was deleted.

9 changes: 5 additions & 4 deletions src/loadgenerator/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2020 Google LLC
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -30,6 +30,9 @@ RUN virtualenv -p python3.7 /env
ENV VIRTUAL_ENV /env
ENV PATH /env/bin:$PATH

# enable gevent support in debugger
ENV GEVENT_SUPPORT=True

# explicitly set a fallback log level in case no log level is defined by Kubernetes
ENV LOG_LEVEL info

Expand All @@ -38,9 +41,7 @@ ADD requirements.txt /app/requirements.txt
RUN pip install -r /app/requirements.txt

# Add application code.
ADD loadgen.sh /app
ADD locustfile.py /app
RUN chmod +x /app/loadgen.sh

# start loadgenerator
ENTRYPOINT /app/loadgen.sh
ENTRYPOINT locust --host="http://${FRONTEND_ADDR}" --loglevel $LOG_LEVEL --no-web -c "${USERS:-10}" 2>&1
Loading

0 comments on commit 368549b

Please sign in to comment.