Logging
The AEA framework supports flexible logging capabilities with the standard Python logging library.
In this tutorial, we configure logging for an AEA.
First of all, create your AEA.
The aea-config.yaml
file should look like this.
agent_name: my_aea
author: fetchai
version: 0.1.0
description: ''
license: Apache-2.0
aea_version: 0.6.0
fingerprint: {}
fingerprint_ignore_patterns: []
connections:
- fetchai/stub:0.21.0
contracts: []
protocols:
- fetchai/default:1.1.0
skills:
- fetchai/error:0.18.0
default_connection: fetchai/stub:0.21.0
default_ledger: fetchai
required_ledgers:
- fetchai
logging_config:
disable_existing_loggers: false
version: 1
private_key_paths: {}
By updating the logging_config
section, you can configure the loggers of your application.
The format of this section is specified in the logging.config
module.
At this section you'll find the definition of the configuration dictionary schema.
Below is an example of the logging_config
value.
logging_config:
version: 1
disable_existing_loggers: False
formatters:
standard:
format: '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
handlers:
logfile:
class: logging.FileHandler
formatter: standard
level: DEBUG
filename: logconfig.log
console:
class: logging.StreamHandler
formatter: standard
level: DEBUG
loggers:
aea:
handlers:
- logfile
- console
level: DEBUG
propagate: False
This configuration will set up a logger with name aea
. It prints both on console and on file with a format specified by the standard
formatter.
Streaming to browser
It is possible to configure the AEA to stream logs to a browser.
First, add the following configuration to your AEA:
logging_config:
version: 1
disable_existing_loggers: false
formatters:
standard:
format: '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
handlers:
http:
class: logging.handlers.HTTPHandler
formatter: standard
level: INFO
host: localhost:5000
url: /stream
method: POST
loggers:
aea:
handlers:
- http
level: INFO
propagate: false
Second, create a log server:
# -*- coding: utf-8 -*-
"""A simple flask server to serve logs."""
import datetime
import itertools
import queue
from flask import Flask, Response, request, stream_with_context
def format_log(log_dict):
"""Format a log record."""
date = datetime.datetime.fromtimestamp(float(log_dict["created"]))
formatted_log = f"[{date.isoformat()}] [{log_dict['levelname']}] {log_dict['name']}: {log_dict['msg']}"
return formatted_log
def create_app():
"""Create Flask app for streaming logs."""
all_logs = []
unread_logs = queue.Queue()
app = Flask(__name__)
@app.route("/")
def index():
"""Stream logs to client."""
def generate():
# stream old logs
div = "<div>{}</div>"
for old_row in all_logs:
yield div.format(old_row)
# stream unread logs
while True:
row = unread_logs.get()
all_logs.append(row)
yield f"<div>{row}</div>"
rows = generate()
title = "<p>Waiting for logs...</p>"
return Response(stream_with_context(itertools.chain([title], rows)))
@app.route("/stream", methods=["POST"])
def stream():
"""Save log record from AEA."""
log_record_formatted = format_log(dict(request.form))
unread_logs.put(log_record_formatted)
return {}, 200
app.run()
if __name__ == "__main__":
create_app()
Save the script in a file called server.py
, install flask with pip install flask
and run the server with python server.py
.
Third, run your AEA and visit localhost:5000
in your browser.