이 장에서는 제니퍼 Python 에이전트를 설치하는 방법을 설명한다.
Python 에이전트 지원 환경
지원하는 OS
지원하는 Linux 배포 버전은 아래와 같고,
CentOS 7 이상
Ubuntu 18.04 이상
macOS의 경우 지원은 하지만 일부 플랫폼 관련 메트릭스 데이터가 수집되지 않을 수 있다.
지원하는 Python 버전
CPython 버전만 지원하며 파이썬 3.3 이상을 지원한다.
파이썬 2.x 환경은 jennifer-python 5.6.4 버전 이후로 지원 중단
지원하는 Web Framework 버전
Flask >= v0.11
Django >= v1.5
FastAPI >= v0.78.0
(* 위의 목록에 포함되지 않은 경우 요청 시 추가 가능)
지원하는 데이터베이스 드라이버 버전
1. MySQL or MariaDB * mysqlclient >= 2.0.3 * pymysql >= 1.0.2 2. sqlite3 * sqlite3 3. PostgreSQL * psycopg2 >= 2.8 * psycopg2-binary >= 2.8 4. Oracle * cx-Oracle >= 8.0.0 5. mongodb * pymongo >= 3.10.1 6. redis * redis >= 4.0.2 7. pyodbc * pyodbc >= 4.0.39
파이썬 에이전트 설치
파이썬 에이전트는 PyPI에 등록돼 있으므로 pip를 이용해 설치할 수 있다. 인터넷이 설치되지 않은 환경에서는 마찬가지로 PyPI로부터 패키지를 미리 내려받는다는 점을 제외하고는 동일하게 pip를 이용해 설치할 수 있다.
PyPI를 이용한 설치
pip를 이용해 다른 패키지를 설치하는 방법과 동일하게 제니퍼 에이전트를 설치할 수 있다.
$ pip install jennifer-python
수동 설치
아래의 PyPI 사이트를 방문해,
https://pypi.org/project/jennifer-python/
좌측의 "Download files" 링크를 눌러 원하는 버전의 jennifer-python 패키지를 다운로드한다. 예를 들어, "jennifer_python-5.6.1.31-py3-none-any.whl" 파일을 다운로드했다면 이 파일을 에이전트를 설치할 대상 컴퓨터에 복사한다. 그다음, pip 명령어를 이용해 whl 파일을 직접 설치한다.
// 예를 들어, /tmp 디렉터리에 whl 파일을 복사한 경우 $ pip install /tmp/jennifer_python-5.6.1.31-py3-none-any.whl
압축 파일만 풀어서 설치 (5.6.3.0부터 지원)
명시적인 pip 설치 없이 압축 파일만 풀어서 동작시키는 것도 가능하다. 이런 경우 다운로드한 whl 파일을 unzip을 이용해 압축 해제를 한다.
// 아래의 명령어는 /app/agent 디렉터리에 압축을 해제 $ unzip jennifer_python-5.6.3.0-py3-none-any.whl -d /app/agent
대신 이렇게 압축만 해제하면 이후의 내용에서 설명할 jennifer-admin 명령어를 사용할 수 없다.
설치를 하지 않았으므로 jennifer-admin 명령어를 사용할 수 없기 때문에 이후 응용 프로그램에서 에이전트를 로드하려면 PYTHONPATH 환경변수를 적용해야 한다.
// 아래의 명령어는 /app/agent 디렉터리에 압축이 풀린 것으로 가정 $ export PYTHONPATH=/app/agent/jennifer/admin
Azure Web App에 설치하는 방법
Azure Portal에 접속해 해당 Web App의 "Development Tools" / "SSH" 화면으로 들어가 pip install 명령어로 설치할 수 있다. 한 가지 차이점은, Web App의 경우 자동 스케일링이나 재시작 시 "/home" 디렉터리를 제외하고는 초기화가 되므로 반드시 그 하위에 제니퍼 에이전트를 설치해야 한다.
// 반드시 /home 디렉터리 하위에 설치 $ pip install jennifer-python -t /home/jennifer
// 기존 버전을 업데이트하는 경우 // 디렉터리를 바꿔서 설치 $ pip install jennifer-python -t /home/jennifer2 // 기존 디렉터리는 Web App을 재시작한 후에만 삭제가 가능
NVIDIA Triton Inference Server에 설치하는 방법
Triton 서버는 자체 빌드한 파이썬 실행 파일을 자식 프로세스로 실행하기 때문에 PYTHONPATH를 이용한 환경 변수 설정을 필요로 한다. 이를 위해 파이썬 에이전트 설치 파일인 WHL 파일의 압축을 풀고,
// 아래의 명령어는 /app/agent 디렉터리에 압축을 해제 $ unzip jennifer_python-5.6.3.0-py3-none-any.whl -d /app/agent
해당 경로를 기준으로 ./jennifer/admin 경로를 PYTHONPATH 환경 변수에 적용한다.
// 아래의 명령어는 /app/agent 디렉터리에 압축이 풀린 것으로 가정 $ export PYTHONPATH=/app/agent/jennifer/admin
파이썬 에이전트 적용
웹 애플리케이션에 적용할 INI 파일 생성
pip를 이용해 에이전트 모듈을 설치했으면, 로컬 환경에서 jennifer-admin 명령어를 사용할 수 있다. 이를 이용해 대상 웹 애플리케이션의 모니터링을 위한 설정 파일을 만든다.
$ jennifer-admin generate-config
pip 설치를 하지 않은 경우, jennifer-admin을 사용할 수 없으므로 편집기를 이용해 INI 파일을 직접 생성해야 한다.
위의 명령어를 실행하면 현재 디렉터리에 jennifer.ini 파일이 생성된다. 원한다면 이름을 바꿔도 되고, 어차피 내용은 텍스트이므로 jennifer-admin 명령어를 사용하지 않고 파일을 직접 생성해 텍스트를 입력해도 된다.
ini 파일에는 다음과 같은 내용을 포함하고 있으며,
항목 | 기본값 | 설명 |
---|---|---|
server_address | 127.0.0.1 | 데이터서버 IP Address |
server_port | 5000 | 데이터 서버 Port |
domain_id | 1000 | 도메인 ID, 유효값은 1 ~ 32767이다. |
inst_id | -1 | 에이전트 인스턴스 ID '-1'이면 서버로 부터 자동으로 ID를 할당받게 된다. 유효값은 1 ~ 32767이다. |
제니퍼 데이터 서버의 구성에 따라 적절한 값으로 편집하면 된다.
웹 애플리케이션에 에이전트 적용 (PIP로 설치한 경우)
마지막으로, 모니터링을 해야 하는 웹 애플리케이션의 실행 명령어를 다음과 같이 jennifer-admin 경유해 실행하는 방식으로 변경한다.
[wsgi 웹 애플리케이션인 경우] $ JENNIFER_CONFIG_FILE=<설정 파일 경로> jennifer-admin run <python 실행 코드> [asgi 웹 애플리케이션인 경우] $ JENNIFER_CONFIG_FILE=<설정 파일 경로> jennifer-admin runasync <python 실행 코드>
예를 들어, 기존의 파이썬 명령어가 uwsgi를 이용해 다음과 같이 호스팅을 시작했다면,
$ uwsgi -i uwsgi.ini
제니퍼를 적용하기 위해서는 위에서 만들었던 ini 파일 위치를 지정하는 환경변수 JENNIFER_CONFIG_FILE과 함께 jennifer-admin 명령어를 경유해 실행하는 방식으로 변경한다.
[ini 파일의 위치와 jennifer-admin을 이용해 "run" 옵션과 함께 기존 프로그램 실행] $ JENNIFER_CONFIG_FILE=/home/user/jennifer/jennifer.ini jennifer-admin run uwsgi -i uwsgi.ini [또는, 환경변수를 분리해 실행] $ export JENNIFER_CONFIG_FILE=/home/user/jennifer/jennifer.ini $ jennifer-admin run uwsgi -i uwsgi.ini
만약 FastAPI로 만들어 비동기 호스팅을 하는 uvicorn인 경우라면 jennifer-admin의 옵션만 "run"에서 "runasync"로 바꿔 실행한다.
$ JENNIFER_CONFIG_FILE=/home/user/jennifer/jennifer.ini jennifer-admin runasync uvicorn --loop asyncio main:app
웹 애플리케이션에 에이전트 적용 (압축 파일 해제만 한 경우)
압축 파일을 해제한 경우에는 jennifer-admin 도구를 사용할 수 없다. 따라서 jennifer-admin 도구가 하는 역할을 직접 python 프로세스의 인자로 전달해 실행하는 방식으로 바꿔야 한다. 예를 들어 jennifer-admin을 이용하는 경우 기존의 명령어에 다음과 같이 연결만 하면 되지만,
$ export JENNIFER_CONFIG_FILE=/home/user/jennifer/jennifer.ini $ jennifer-admin run uwsgi -i uwsgi.ini
"jennifer-admin run" 대신 직접 파이썬을 이용해 jennifer-admin에 해당하는 코드를 다음과 같이 실행하게끔 바꾸면 된다.
// jennifer 패키지를 /app/agent에 압축 해제를 한 경우 // PYTHONPATH 환경변수를 설정하지 않은 경우 $ export JENNIFER_CONFIG_FILE=/home/user/jennifer/jennifer.ini $ python3 /app/agent/jennifer/admin/__init__.py run uwsgi -i uwsgi.ini
또는, PYTHONPATH를 이용해 /app/agent/jennifer/admin 경로를 지정했다면 uwsgi를 실행하는 것만으로 에이전트가 로드된다.
// jennifer 패키지를 /app/agent에 압축 해제를 한 경우 $ export PYTHONPATH=/app/agent/jennifer/admin $ export JENNIFER_CONFIG_FILE=/home/user/jennifer/jennifer.ini $ uwsgi -i uwsgi.ini
docker 컨테이너 환경
$ unzip jennifer_python-5.6.3.0-py3-none-any.whl -d /app/agent
압축이 해제된 디렉터리(위의 예제에서는 /app/agent)를 docker 컨테이너에 볼륨 매핑을 한다. 그다음 제니퍼 서버 정보 및 인스턴스 ID 정보를 담은 INI 파일을 생성해 볼륨 매핑을 한다. (또는, 볼륨 매핑 없이 이미지 내에 복사해도 된다.)
이후 Dockerfile에 다음과 같이 2개의 환경변수만 추가하면 제니퍼 에이전트가 활성화된다.
# WHL 파일의 압축을 /app/agent에 풀어 놓은 것으로 가정 # JENNIFER.INI 파일이 /app/jennifer.ini에 위치한 것으로 가정 ENV PYTHONPATH=/app/agent/jennifer/admin ENV JENNIFER_CONFIG_FILE=/app/jennifer.ini
Azure Web App 환경
Web App 환경에서 오직 /home 디렉터리 하위만 인스턴스 재생성 시에도 유지가 되므로 INI 파일을 반드시 그 하위에 만들어야 한다.
# 반드시 /home 디렉터리 하위에 생성 $ cat /home/jennifer_conf.ini [JENNIFER] server_address = ...[생략: 제니퍼 서버 주소]... server_port = 5000 domain_id = 1000 inst_id = -1
그다음 "Settings" / "Environment variables"를 통해 INI 파일의 경로를 설정하는 환경변수를 추가하고
[App settings] NAME: JENNIFER_CONFIG_FILE VALUE: /home/jennifer_conf.ini
그다음 "Settings" / "Configuration"을 통해 "Startup Command"에 설정된 기존 명령어에 더해 jennifer 시작 명령어를 추가한다.
예를 들어 현재 "Startup Command" 값이 "python -m uvicorn main:app --host 0.0.0.0"이라고 설정돼 있으면 다음과 같이 추가한다.
[General settings] Startup Command: python /home/jennifer/jennifer/admin/__init__.py run python -m uvicorn main:app --host 0.0.0.0
파이썬 에이전트 제거
제거 역시 pip 명령어를 사용한다.
$ pip uninstall jennifer-python
위의 명령어는 설치된 파일만을 제거하므로 현재 모니터링 중인 프로세스가 있다면 "jennifer-admin"을 뺀 기존의 명령어로 다시 실행해야 한다.
Azure Web App 환경
Startup Command에서 __init__.py를 실행하도록 변경한 명령어를 원래의 명령어로 변경한다. 이후 기존에 pip install로 -t 옵션을 지정한 디렉터리에 대해 삭제까지 하려면 Web App을 재시작한다.
NVIDIA Triton Inference Server에 적용하는 방법
5.6.4.7 버전부터 지원
Triton 서버는 자체 빌드한 파이썬 실행 파일을 자식 프로세스로 실행하기 때문에 PYTHONPATH를 이용한 환경 변수 설정을 필요로 한다. 이를 위해 파이썬 에이전트 설치 파일인 WHL 파일의 압축을 풀고,
// 아래의 명령어는 /app/agent 디렉터리에 압축을 해제 $ unzip jennifer_python-5.6.3.0-py3-none-any.whl -d /app/agent
압축 해제한 경로를 기준으로 ./jennifer/admin 디렉터리를 PYTHONPATH 환경 변수에 적용한다.
// 아래의 명령어는 /app/agent 디렉터리에 압축이 풀린 것으로 가정 $ export PYTHONPATH=/app/agent/jennifer/admin
그다음 TritonPythonModel의 execute 함수를 profile_service_method로 INI 파일에 등록해야 한다. 예를 들어 사용자가 구현한 Model 디렉터리가 다음과 같고,
$ tree ./triton/ ./triton/ ├── core │ ├── 1 │ │ └── model.pt │ └── config.pbtxt ├── ensemble │ ├── 1 │ │ └── placeholder │ └── config.pbtxt ├── postprocessing │ ├── 1 │ │ └── model.py │ ├── config.pbtxt │ └── post_env.tar.gz └── preprocessing ├── 1 │ └── model.py ├── config.pbtxt └── pre_env.tar.gz
./preprocessing/1/model.py와 ./postprocessing/1/model.py를 모니터링하고 싶다면 INI 파일에 이렇게 등록한다.
$ cat /home/jennifer_conf.ini [JENNIFER] server_address = ...[생략: 제니퍼 서버 주소]... server_port = 5000 domain_id = 1000 inst_id = -1 profile_service_class = 1.model TritonPythonModel.execute ; model.py에 정의된 전역 함수를 프로파일에 추가하고 싶다면? ; profile_method_pattern = 1.model.*
이후 Triton 서버를 재시작하면 모니터링이 적용된다. 예를 들어 docker를 이용한 환경인 경우 다음과 같이 JENNIFER_CONFIG_FILE, PYTHONPATH를 환경 변수를 등록해 주면 된다.
$ export MODEL_FOLDER_PATH=/home/test/triton_server_example/triton $ docker run --gpus='"device=0"' -it --rm --shm-size=8g -p 8005:8000 -e JENNIFER_CONFIG_FILE=/app/jennifer_conf.ini -e PYTHONPATH=/app/agent/jennifer/admin -e SSL_CERT_DIR=/etc/ssl/certs/ -v /app:/app -v ${MODEL_FOLDER_PATH}:/model_dir tis tritonserver --model-repository=/model_dir --strict-model-config=false --model-control-mode=poll --repository-poll-secs=6000 --backend-config=tensorflow,version=2 --log-verbose=1
또는 독립 실행형 서버로 직접 실행하는 경우라면 TritonServer 명령어를 실행하는 구문 앞에 환경 변수를 설정한다.
$ JENNIFER_CONFIG_FILE=/app/jennifer_conf.ini -e PYTHONPATH=/app/agent/jennifer/admin tritonserver --model-repository=/model_dir --strict-model-config=false --model-control-mode=poll --repository-poll-secs=6000 --backend-config=tensorflow,version=2 --log-verbose=1
이렇게 Triton 서버가 재기동되면 preprocessing과 postprocessing 각각 1개씩 인스턴스가 추가되고 요청이 들어올 때마다 X-View에 점 데이터가 추가된다.
알려진 문제
uwsgi에서 호스팅하는 경우
제니퍼 콘솔의 각종 차트에 데이터 수집이 없는 현상
일부 웹 애플리케이션 서버의 경우 jennifer-python의 적절한 데이터 수집을 위해 아래와 같은 옵션을 추가해야 한다.
호스팅 서버 | 옵션 |
---|---|
uwsgi | -enable-threads |
메모리 부족으로 uwsgi에서 호스팅에 실패하는 현상
uwsgi의 경우 "limit-as" 옵션을 설정해 메모리 상한을 거의 딱 맞게 설정하면 제니퍼 에이전트의 추가 메모리 사용으로 로딩이 실패할 수 있다. 이런 경우 오류 메시지도 없이 조용하게 웹 응용 프로그램만 실행한다.
profile_method_pattern 등의 다이나믹 프로파일링이 적용되지 않는 문제
파이썬 인터프리터가 대상 메서드의 바인딩을 미리 수행한 경우에는 다이나믹 프로파일링이 적용되지 않는다. 예를 들어 아래와 같이 FlaskApp을 만든 경우
# 파일명: app.py from flask import Flask class FlaskApp(object): def __init__(self): self.app = Flask(__name__) self.app.add_url_rule('/', view_func=self.view_data) def get_data(self): return "<h2>테스트</h2>" def view_data(self): html = self.get_data() return html def run(self, host='0.0.0.0', port=5500, debug=True): self.app.run(host=host, port=port, debug=debug) if __name__ == '__main__': app = FlaskApp() app.run()
get_data 함수를 다이나믹 프로파일링으로 모니터링하기 위해 INI 파일에 다음과 같은 설정을 추가해도
profile_method_pattern = app FlaskApp.get_data
get_data 함수를 다이나믹 프로파일링으로 모니터링하기 위해 INI 파일에 다음과 같은 설정을 추가해도 get_data 함수 호출이 프로파일링되지는 않는다. 만약, 저런 경우 모니터링을 하고 싶다면 get_data 함수를 별도의 파일로 분리해야 한다.