win*_*aed 2 python json amazon-sqs flask amazon-elastic-beanstalk
我有一个使用Elastic Beanstalk的Python'worker',它从SQS读取消息.虽然扩展很笨重,因为它基于cpu,但这种方法很好.因此,我正在尝试将其转换为使用AWS的新"工人层级环境".
在Flask的深处,但我在EB工作层上运行了Flask.目前它被设置为只记录它收到的消息信息 - 这是为了确保我可以在移动其他所有内容之前读取信息.不幸的是我看不到任何消息的迹象?
这是我的Flask测试代码:
import logging
import logging.handlers
from flask import Flask, request
logfile = "/opt/python/log/scan.log"
mylog = logging.getLogger('helloworld')
# (for brevity, log format/config code removed)
application = Flask(__name__)
app = application
app.Debug=True
@app.route('/', methods=['POST'])
def hello():
global mylog
err = "Unrecognized method"
mylog.warning("Hello called")
request_detail = """
# Before Request #
request.endpoint: {request.endpoint}
request.method: {request.method}
request.view_args: {request.view_args}
request.args: {request.args}
request.form: {request.form}
request.user_agent: {request.user_agent}
request.files: {request.files}
request.is_xhr: {request.is_xhr}
## request.headers ##
{request.headers}
""".format(request=request).strip()
mylog.warning(request_detail)
mylog.warning("Moreinfo:")
mylog.warning("Args:")
for k in request.args.keys():
mylog.warning(k + ": "+request.args[k])
mylog.warning("Form:")
for k in request.form.keys():
mylog.warning(k + ": "+request.form[k])
mylog.warning("Files:"+len(request.files))
for k in request.files.keys():
mylog.warning(k + ": "+request.files[k])
try:
myJSON = request.get_json(force=True)
if myJSON is None:
mylog.warning("JSON could not be forced")
else:
mylog.warning("MyJSON size: " + len(myJSON))
mylog.warning( "MyJSON: {myJSON}".format(myJSON=myJSON))
if request.json is None:
mylog.warning("NO JSON")
except Exception as e:
mylog.warning("Exception: " + e)
# the code below is executed if the request method
# was GET or the credentials were invalid
mylog.warning("failure 404")
return 'Failure: '+err , 404, {'Content-Type': 'text/plain'}
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
Run Code Online (Sandbox Code Playgroud)
是的,大型长格式声明是从一本书借来的:-)
以下是消息的典型日志输出:
WARNING:2014-02-20 15:34:37,418: Hello called
WARNING:2014-02-20 15:34:37,419:
# Before Request #
request.endpoint: hello
request.method: POST
request.view_args: {}
request.args: ImmutableMultiDict([])
request.form: ImmutableMultiDict([])
request.user_agent: aws-sqsd
request.files: ImmutableMultiDict([])
request.is_xhr: False
## request.headers ##
X-Aws-Sqsd-Msgid: 232eea42-5485-478c-a57f-4afddbf77ba9
X-Aws-Sqsd-Receive-Count: 199
X-Aws-Sqsd-Queue: #<AWS::SQS::Queue:0xb9255e90>
Content-Length: 59
User-Agent: aws-sqsd
X-Aws-Sqsd-First-Received-At: 2014-02-20T13:55:34Z
Host: localhost
Content-Type: application/json
WARNING:2014-02-20 15:34:37,419: Moreinfo:
WARNING:2014-02-20 15:34:37,419: Args:
WARNING:2014-02-20 15:34:37,420: Form:
Run Code Online (Sandbox Code Playgroud)
请注意,ImmutableMultiDict结构似乎都没有任何键.此外,没有任何JSON方法/属性返回任何内容.
Content-Length字段确实在日志条目之间变化,因此它看起来就像信息一样.但是我怎么看呢?
我的JSON消息使用BOTO写入SQS,例如:
my_queue = conn.get_queue('my_queue_name')
m = Message()
m.set_body( json.dumps( my_structure ) )
my_queue.write(m)
Run Code Online (Sandbox Code Playgroud)
我还尝试使用SQS Web界面手动输入原始JSON消息.这也不起作用 - 我猜测我们可能有字符编码问题/
目前尚不清楚为什么你的消息记录被切断了; 也许你有一个缩进错误,你的部分日志代码不被视为view方法的一部分.
但是,如果我理解正确,Boto SQS消息不仅编码为JSON,JSON消息本身也是base64编码,这意味着该flask.get_json()
方法不会为您解码.
相反,使用该request.get_data()
方法访问原始POST数据并自行进行解码; 首先验证该request.content_length
值是否在可容忍的大小内,以防止攻击者向您发送超大邮件:
from flask import json
import base64
if request.mime_type == 'application/json' and request.content_length <= 1024**2:
# message is JSON and smaller than 1 megabyte
try:
decoded = base64.b64decode(request.get_data())
data = json.loads(decoded)
except (ValueError, TypeError):
mylog.exception('Failed to decode JSON')
else:
# do something with the decoded data
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2433 次 |
最近记录: |