brunch

You can make anything
by writing

C.S.Lewis

by 유윤식 Jun 04. 2019

Python: Elastic APM

파이썬 플라스크 웹 서버 모니터링

간단 사용기.


우선,

AWS에서 Elasticsearch 서비스를 활용하고 있다는 가정하에.


Elasticsearch API 로 접근하기 위한 IP 는 10.10.0.2


Python Web Server 로 접근하기 위한 IP 는 10.10.2.2


첫번째로,

Elasticsearch 를 서비스하고 있는 VM 에 APM 전용 서비스를 설치


>> curl -L -O https://artifacts.elastic.co/downloads/apm-server/apm-server-7.1.1-x86_64.rpm

>> rpm -vi apm-server-7.1.1-x86_64.rpm

>> service apm-server start

정상 구동 되었다면,

>> systemctl enable apm-server



잠시 APM 서비스의 .yml 파일을 살펴볼 필요가 있다.

2 곳의 설정을 바꿔주면 우선 간단하게 실행 할 수 있다.


APM 서비스 호스트
Elasticsearch output 호스트


다음으로,

Flask 라이브러리 설치


>> pip install flask

or,

>> python3 -m pip install flask

and,

>> python3 -m pip install elastic-apm[flask]



80% 완료!


간단한 flask 구동 서버 코드

file: app.py


from elasticapm.contrib.flask import ElasticAPM

from elasticapm.handlers.logging import LoggingHandler

from flask import Flask, flash, redirect, render_template, request, url_for, logging


app = Flask(__name__)

app.secret_key = 'random string'

app.config['ELASTIC_APM'] ={

    'SERVICE_NAME': 'aws',

    'SECRET_TOKEN': 'david',

    'SERVER_URL': 'http://10.10.0.2:8200'

}

apm = ElasticAPM(app, logging=True)

@app.route('/')

def index():

    return render_template('index.html')

@app.route('/login', methods = ['GET', 'POST'])

def login():

    error = None

    if request.method == 'POST':

        if request.form['username'] != 'admin' or request.form['password'] != 'admin':

            error = 'Invalid username or password. Please try again!'

            app.logger.error( 'Critical Error!! Call 112!!!', exc_info=True)

        else:

            flash('You were successfully logged in')

            return redirect(url_for('index'))

    return render_template('login.html', error = error)

if __name__ == "__main__":

    handler = LoggingHandler(client=apm.client)

    #handler.setLevel(logging.DEBUG)

    app.logger.addHandler(handler)

    app.run(host="10.10.2.2")


file: /templates/index.html


<!doctype html>

<html>   

   <head>

      <title>Flask Message flashing</title>

   </head>

   <body>   

      {% with messages = get_flashed_messages() %}

         {% if messages %}

            <ul>

               {% for message in messages %}

               <li>{{ message }}</li>

               {% endfor %}

            </ul>

         {% endif %}

      {% endwith %}

      <h1>Flask Message Flashing Example</h1>

      <p>Do you want to <a href = "{{ url_for('login') }}">

         <b>log in?</b></a></p>      

   </body>

</html>


file: /templates/login.html


<!doctype html>

<html>

   <body>   

      <h1>Login</h1>      

      {% if error %}

      <p><strong>Error:</strong> {{ error }}

      {% endif %}      

      <form action = "" method = post>

         <dl>

            <dt>Username:</dt>            

            <dd>

               <input type = text name = username 

                  value = "{{request.form.username }}">

            </dd>            

            <dt>Password:</dt>

            <dd><input type = password name = password></dd>

         </dl>

         <p><input type = submit value = Login></p>

      </form>      

   </body>

</html>



간단한 테스트!


>> python3 app.py

 * Serving Flask app "app" (lazy loading)

 * Environment: production

   WARNING: This is a development server. Do not use it in a production deployment.

   Use a production WSGI server instead.

 * Debug mode: off



접속!

Flask 는 기본을 5000번 포트를 사용한다.

처음 접속 화면
로그인 실패
로그인 성공
Kibana APM 화면구성
로그인 실패 관련 로깅


이게 사실은 DB 접속, 외부 웹 사이트 접속, 인증 등의 다양한 서비스를 포함하는

웹 서비스에 사용하면 좋다.


응답 속도, 응답 내용 등에 대한 간단한 내용뿐만 아니라.

누가 어떤 경로로 어떤 요청과 어떤 응답을 받았는지,

이게 다른 사용자와 어떻게 다르고,

어떤 문제점을 가지는지에 대해서 분석할 수 있는

기본 정보를 제공한다.


결국! Graph!!


끝.


* 참고로 Elastic 도 Graph 모듈이 존재한다.

작가의 이전글 Linux:iptables on AWS VPC
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari