欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Solutions:如何为Python Flask应用进行APM

程序员文章站 2022-07-08 14:55:42
...

如果大家之前看过我写的文章“应用程序性能监控/管理(APM)实践”,那么你就会对Elastic APM有个比较清楚的认识。在今天的蚊帐中,我就再累述了。在那篇文章中,我着重介绍了APM到底是什么东东。在今天的练习中,我来展示如何对Python Flask来进行监控。

测试应用

我们的Flash测试应用非常简单,就是一个简单的查询天气的微服务。这个API的接口如下:

http://api.openweathermap.org/data/2.5/weather?q=beijing&units=imperial&appid=271d1234d3f497eed5b1d80a07b3fcd1

使用上面的接口,我们可以得到北京的天气如下:

{"coord":{"lon":116.4,"lat":39.91},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}],"base":"stations","main":{"temp":79.68,"feels_like":72.21,"temp_min":73.99,"temp_max":84.99,"pressure":1016,"humidity":11},"visibility":10000,"wind":{"speed":4.47,"deg":250},"clouds":{"all":0},"dt":1586754618,"sys":{"type":1,"id":9609,"country":"CN","sunrise":1586727568,"sunset":1586774994},"timezone":28800,"id":1816670,"name":"Beijing","cod":200}

这是一个非常简单的应用。整个应用的代码如下:

app.py

import requests
from flask import Flask, render_template, request
from flask_sqlalchemy import SQLAlchemy 

app = Flask(__name__)
app.config['DEBUG'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///weather.db'

db = SQLAlchemy(app)

class City(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), nullable=False)


@app.route('/beijing', methods=['GET'])
def getBeijing():
    url = 'http://api.openweathermap.org/data/2.5/weather?q={}&units=imperial&appid=271d1234d3f497eed5b1d80a07b3fcd1'

    city = "beijing"
    weather_data = []
    r = requests.get(url.format(city)).json()

    weather = {
        'city' : city,
        'temperature' : r['main']['temp'],
        'description' : r['weather'][0]['description'],
        'icon' : r['weather'][0]['icon'],
    }

    weather_data.append(weather)

    return render_template('weather.html', weather_data=weather_data)    

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        new_city = request.form.get('city')
        
        if new_city:
            new_city_obj = City(name=new_city)

            db.session.add(new_city_obj)
            db.session.commit()

    cities = City.query.all()

    url = 'http://api.openweathermap.org/data/2.5/weather?q={}&units=imperial&appid=271d1234d3f497eed5b1d80a07b3fcd1'

    weather_data = []

    for city in cities:

        r = requests.get(url.format(city.name)).json()

        weather = {
            'city' : city.name,
            'temperature' : r['main']['temp'],
            'description' : r['weather'][0]['description'],
            'icon' : r['weather'][0]['icon'],
        }

        weather_data.append(weather)


    return render_template('weather.html', weather_data=weather_data)

为了能够运行这个应用,我们必须安装相应的python库:

pip3 install requests
pip3 install flask
pip3 install flask_sqlalchemy

在命令行中,我们打入如下的命令:

export FLASK_APP=app.py

然后,我们运行这个应用:

flask run

如果你上面都运行正确的话,我们可以在浏览器中输入localhost:5000,并可以看到如下的内容:

$ flask run
 * Serving Flask-SocketIO app "app"
/usr/local/lib/python3.7/site-packages/flask_sqlalchemy/__init__.py:794: FSADeprecationWarning: SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future.  Set it to True or False to suppress this warning.
  'SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and '
 * Serving Flask app "app"
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

Solutions:如何为Python Flask应用进行APM

我们可以添加一个城市来得到它的天气。在这个应用中它除了得到天气之外,它也同时访问sqlite数据库。

 

安装

安装Elastic Stack,有两种方法。最简单的一种方法是运用docker来一键部署Elasticsearch, Kibana和APM服务器。详细安装步骤请参阅链接liu-xiao-guo/apm-contrib。下面我们采用一种手动的方法来部署Elastic Stack。

我们可以按照我们的文章“Elastic:菜鸟上手指南”来安装及运行我们的Elasticsearch及Kibana。

我们也必须安装和Elasticsearch一样版本的APM服务器。我们打开我们的Kibana界面,并点击左上角的部分:

Solutions:如何为Python Flask应用进行APM

然后,我们按照上面的步骤一步一步地进行安装:

Solutions:如何为Python Flask应用进行APM

我们按照上面的要求配置好Elasticsearch的地址及用户名和密码(如果你已经启动了安全的设置):

Solutions:如何为Python Flask应用进行APM

如果我们能看到上面的信息则表示我们的APM服务器的安装是成功的。由于我们针对的是Flask应用框架,所以我们点击Flask来进行安装。

Solutions:如何为Python Flask应用进行APM

按照上面的要求,我们需要进行安装如下的python 模块:

pip3 install elastic-apm[flask]
pip3 install psutil

同时按照要求,我们需要对我们的python应用进行修改。整个修改后的应用如下:

app.py

import requests
from flask import Flask, render_template, request
from flask_sqlalchemy import SQLAlchemy 

# initialize using environment variables
from elasticapm.contrib.flask import ElasticAPM
app = Flask(__name__)
apm = ElasticAPM(app)

# or configure to use ELASTIC_APM in your application's settings
from elasticapm.contrib.flask import ElasticAPM
app.config['ELASTIC_APM'] = {
  # Set required service name. Allowed characters:
  # a-z, A-Z, 0-9, -, _, and space
  'SERVICE_NAME': 'python-flask',

  # Use if APM Server requires a token
  'SECRET_TOKEN': '',

  # Set custom APM Server URL (default: http://localhost:8200)
  'SERVER_URL': 'http://localhost:8200',
}

apm = ElasticAPM(app)

#app = Flask(__name__)
#app.config['DEBUG'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///weather.db'

db = SQLAlchemy(app)

...

在上面,我们把从Kibana中拷贝过来的代码粘贴过来。同时我们需要把DEBUG功能关掉。这个可以在官方文档中可以看到。如果是在DEBUG模式下,transaction及error是不会发到我们的APM服务器中的。我们在上面填入SERVICE_NAME及SERVER_URL。

一旦完成我们上面的配置后,我们重新运行一下我们的Python Flash应用,并打开我们的 Kibana:

Solutions:如何为Python Flask应用进行APM

点击上面的python_flask:

Solutions:如何为Python Flask应用进行APM

点击上面的GET /,我们可以看到:

Solutions:如何为Python Flask应用进行APM

我们可以看到在页面启动的时候的一个transaction的时间是花在哪里。这对我们的在调试微服务及数据库的访问性能调试会有很大的帮助。

我们在浏览器中打入http://localhost:5000/beijing,这样:

Solutions:如何为Python Flask应用进行APM

点击上面的Traces:

Solutions:如何为Python Flask应用进行APM

在上面,它显示了目前在APM应用中的所有的接口的列表。我们点击上面的GET /beijing:

Solutions:如何为Python Flask应用进行APM

在上面,我们可以看到这个接口调用的情况。

整个Python flask的应用可以在地址https://github.com/liu-xiao-guo/weather_app_flask 下载

 

更多阅读

 

参考:

【1】https://www.elastic.co/guide/en/apm/agent/python/current/flask-support.html

相关标签: Elastic Solutions