Logging and audit trails
FlowKit supports structured logging in JSON form throughout FlowMachine and FlowAPI. By default both FlowMachine and FlowAPI will only log errors, and audit logs.
Audit trail logs are always written to stdout. Error and debugging logs are, by default, only written to stderr.
Audit trail logs¶
Three kinds of access log are written on each request handled by FlowAPI: authentication, data access at API side, and data access on the FlowMachine side.
Authentication Logs¶
FlowAPI logs all access attempts whether successful or not to stdout using a logger named flowapi.access
.
Where authentication succeeds, the log message will have a level
field of info
, and an event
type of AUTHENTICATED
:
{
"request_id": "fe1d5dd2-ddfb-4b34-9d1e-4ebfc205d64c",
"route": "/api/0/run",
"user": "TEST_USER",
"src_ip": "127.0.0.1",
"json_payload": {
"params": {
"date": "2016-01-01",
"level": "admin3",
"method": "last",
"aggregation_unit": "admin3",
"subscriber_subset": "all"
},
"query_kind": "daily_location"
},
"event": "AUTHENTICATED",
"logger": "flowapi.access",
"level": "info",
"timestamp": "2019-01-10T13:57:35.262214Z"
}
In general, access log messages contain at a minimum the route that access was requested to, any json payload, source IP address for the request, and a timestamp. Every request also has a unique id, which will be the same across all log entries related to that request.
If authentication fails, then the reason is also included in the log message, along with any error message and as much information about the request and requester as can be discerned.
API Usage Logs¶
After a request is successfully authenticated (has a valid token), the nature of the request will be logged at several points. When the request is received, if at any point the request is rejected because the provided token did not grant access, and when the request is fulfilled.
As with the authentication log, the usage log is written to stdout using a logger named flowapi.query
.
FlowMachine Usage Logs¶
If a request has triggered an action in the FlowMachine backend, logs will also be written there. These logs will include the request_id
for the API request which originally triggered them.
As with the FlowAPI loggers, these messages are written to stdout, using the flowmachine.query_run_log
logger.
Complete Logging Cycle¶
A complete logging cycle for a successful request to retrieve a previously run query's results might look like this:
FlowAPI access log:
{
"request_id": "d2892489-8fb8-40ec-94e6-2467266a0226",
"route": "/api/0/get/ddc61a04f608dee16fff0655f91c2057",
"user": "TEST_USER",
"src_ip": "127.0.0.1",
"json_payload": null,
"event": "AUTHENTICATED",
"logger": "flowapi.access",
"level": "info",
"timestamp": "2019-01-10T14:11:03.331967Z"
}
FlowAPI usage log:
{
"request_id": "d2892489-8fb8-40ec-94e6-2467266a0226",
"query_kind": "DAILY_LOCATION",
"route": "/api/0/get/ddc61a04f608dee16fff0655f91c2057",
"user": "TEST_USER",
"src_ip": "127.0.0.1",
"json_payload": null,
"query_id": "ddc61a04f608dee16fff0655f91c2057",
"claims": {
"permissions": { "get_result": true, "poll": true, "run": true },
"spatial_aggregation": [
"admin2",
"admin0",
"admin3",
"admin1",
"cell",
"site"
]
},
"event": "Received",
"logger": "flowapi.query",
"level": "info",
"timestamp": "2019-01-10T14:11:03.337052Z"
}
{
"request_id": "d2892489-8fb8-40ec-94e6-2467266a0226",
"query_kind": "DAILY_LOCATION",
"route": "/api/0/get/ddc61a04f608dee16fff0655f91c2057",
"user": "TEST_USER",
"src_ip": "127.0.0.1",
"json_payload": null,
"query_id": "ddc61a04f608dee16fff0655f91c2057",
"claims": {
"permissions": { "get_result": true, "poll": true, "run": true },
"spatial_aggregation": [
"admin2",
"admin0",
"admin3",
"admin1",
"cell",
"site"
]
},
"event": "Authorised",
"logger": "flowapi.query",
"level": "info",
"timestamp": "2019-01-10T14:11:03.341010Z"
}
FlowMachine usage log:
{
"query_id": "ddc61a04f608dee16fff0655f91c2057",
"query_kind": "daily_location",
"message": "b'{\"request_id\":\"d2892489-8fb8-40ec-94e6-2467266a0226\",\"action\":\"get_query_kind\",\"query_id\":\"ddc61a04f608dee16fff0655f91c2057\"}'",
"request_id": "d2892489-8fb8-40ec-94e6-2467266a0226",
"params": { "query_id": "ddc61a04f608dee16fff0655f91c2057" },
"event": "get_query_kind",
"logger": "flowmachine.query_run_log",
"level": "info",
"timestamp": "2019-01-10T14:11:03.335437Z"
}
{
"query_id": "ddc61a04f608dee16fff0655f91c2057",
"retrieved_params": {
"aggregation_unit": "admin3",
"method": "last",
"date": "2016-01-01",
"level": "admin3",
"subscriber_subset": "all"
},
"message": "b'{\"request_id\":\"d2892489-8fb8-40ec-94e6-2467266a0226\",\"action\":\"get_params\",\"query_id\":\"ddc61a04f608dee16fff0655f91c2057\"}'",
"request_id": "d2892489-8fb8-40ec-94e6-2467266a0226",
"params": { "query_id": "ddc61a04f608dee16fff0655f91c2057" },
"event": "get_params",
"logger": "flowmachine.query_run_log",
"level": "info",
"timestamp": "2019-01-10T14:11:03.339602Z"
}
{
"query_id": "ddc61a04f608dee16fff0655f91c2057",
"message": "b'{\"request_id\":\"d2892489-8fb8-40ec-94e6-2467266a0226\",\"action\":\"get_sql\",\"query_id\":\"ddc61a04f608dee16fff0655f91c2057\"}'",
"request_id": "d2892489-8fb8-40ec-94e6-2467266a0226",
"params": { "query_id": "ddc61a04f608dee16fff0655f91c2057" },
"event": "get_sql",
"logger": "flowmachine.query_run_log",
"level": "info",
"timestamp": "2019-01-10T14:11:03.358644Z"
}
Note that the request_id
field is identical across the five log entries, which lets you match the request across the multiple services.
Error and Debugging Logs¶
FlowMachine and FlowAPI write logs to stderr. By default, the logging level is error
. For more verbose logging, set the FLOWMACHINE_LOG_LEVEL
and/or FLOWAPI_LOG_LEVEL
environment variables to info
or debug
when starting the docker container(s).
Log messages from FlowMachine will show the logger
field of the log entry as flowmachine.debug
, and the Python module that emitted the log entry in the submodule
field (e.g. {'logger':'flowmachine.debug', 'submodule':'flowmachine.core.query'}
. FlowAPI debugging messages set logger
to flowapi.debug
.
Managing and Monitoring Logs¶
Because FlowKit employs structured logging, and all log messages are JSON objects, the access and usage logs are easy to use with tools like Logstash.
Filebeat allows you to integrate the logs from stdout and stderr directly into your monitoring system.