2.해당 EC2는 Public Subnet에 존재해야하며, Public IP로 API 요청 시 정상적으로 접근이 가능하여야 한다. 3.해당 curl로 요청시 app.log에 저장된 내용이 CloudWatch Logs에 저장되어야한다.
-단,, CloudWatch Agent만을 사용하도록 한다.
명시되지 않은 값은 선수 재량으로 설정하며, 절대 물어보지 않는다.
-단, AWS Well Architected 6 Pillars를 기준으로 한다.
인스턴스를 만들고 유저 데이터에 이거를 넣어준다
#!/bin/bash
dnf install -y python3-pip amazon-cloudwatch-agent
pip3 install flask
nohup python3 /home/ec2-user/app.py > /dev/null 2>&1 &
cat << EOF > /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json
{
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/home/ec2-user/app.log",
"log_group_name": "app-logs",
"log_stream_name": "{instance_id}",
"retention_in_days": 7
}
]
}
}
}
}
EOF
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard 이 명령어 입력
vi app.py치고 이 안에
from flask import Flask, request, jsonify, abort
import datetime
import logging
app = Flask(__name__)
class KSTFormatter(logging.Formatter):
def formatTime(self, record, datefmt=None):
utc_dt = datetime.datetime.fromtimestamp(
record.created,
datetime.timezone.utc
)
kst_dt = utc_dt.astimezone(
datetime.timezone(datetime.timedelta(hours=9))
)
if datefmt:
return kst_dt.strftime(datefmt)
return kst_dt.strftime('%Y-%m-%d %H:%M:%S,%f')[:-3]
access_log_format = '%(asctime)s - - %(client_ip)s %(port)s %(method)s %(path)s %(status)s'
access_log_formatter = KSTFormatter(access_log_format)
access_log_handler = logging.FileHandler('app.log')
access_log_handler.setFormatter(access_log_formatter)
access_log = logging.getLogger('access')
access_log.setLevel(logging.INFO)
access_log.addHandler(access_log_handler)
@app.after_request
def after_request(response):
extra = {
'client_ip': request.remote_addr,
'port': request.environ['SERVER_PORT'],
'method': request.method,
'path': request.path,
'status': response.status_code
}
access_log.info('', extra=extra)
return response
@app.route('/2xx', methods=['GET'])
def get_2xx():
try:
ret = {"status": "200"}
return jsonify(ret), 200
except Exception as e:
app.logger.error(e)
abort(500)
@app.route('/3xx', methods=['GET'])
def get_3xx():
try:
ret = {"status": "300"}
return jsonify(ret), 300
except Exception as e:
app.logger.error(e)
abort(500)
@app.route('/4xx', methods=['GET'])
def get_4xx():
try:
ret = {"status": "400"}
return jsonify(ret), 400
except Exception as e:
app.logger.error(e)
abort(500)
@app.route('/5xx', methods=['GET'])
def get_5xx():
try:
ret = {"status": "500"}
return jsonify(ret), 500
except Exception as e:
app.logger.error(e)
abort(500)
@app.route('/healthcheck', methods=['GET'])
def get_healthcheck():
try:
ret = {"status": "ok"}
return jsonify(ret), 200
except Exception as e:
app.logger.error(e)
abort(500)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=8080)
이거다 넣어준다