-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
140 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# ! time formats need to always be consistent | ||
# string datetime in ISO 8601 format (datetime default) preferred | ||
|
||
version: 1 | ||
disable_existing_loggers: true | ||
formatters: | ||
json_request: | ||
class: src.logging.AccesslogFormatter | ||
json_error: | ||
class: src.logging.VerboseJSONFormatter | ||
json_catchall: | ||
class: src.logging.VerboseJSONFormatter | ||
json_api: | ||
class: src.logging.APILogFormatter | ||
handlers: | ||
json_api: | ||
class: logging.StreamHandler | ||
stream: ext://sys.stdout | ||
formatter: json_api | ||
json_request: | ||
class: logging.StreamHandler | ||
stream: ext://sys.stdout | ||
formatter: json_request | ||
json_error: | ||
class: logging.StreamHandler | ||
stream: ext://sys.stderr | ||
formatter: json_error | ||
json_catchall: | ||
# this is just so we never drop logs, nothing should be handled by this handler | ||
class: logging.StreamHandler | ||
stream: ext://sys.stdout | ||
formatter: json_catchall | ||
loggers: | ||
uvicorn.access: | ||
level: INFO | ||
handlers: [json_request] | ||
propagate: false | ||
uvicorn.error: | ||
level: ERROR | ||
handlers: [json_error] | ||
propagate: false | ||
bia.api: | ||
level: INFO | ||
handlers: [json_api] | ||
propagate: false | ||
root: | ||
level: INFO | ||
handlers: [json_catchall] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import logging | ||
import datetime | ||
|
||
import json_log_formatter | ||
|
||
|
||
class APILogFormatter(json_log_formatter.JSONFormatter): | ||
def json_record( | ||
self, | ||
message: str, | ||
extra: dict[str, str | int | float], | ||
record: logging.LogRecord, | ||
) -> dict[str, str | int | float]: | ||
return dict( | ||
level=record.levelname, | ||
time=datetime.datetime.fromtimestamp(record.created), | ||
message=message, | ||
extra=extra, | ||
) | ||
|
||
|
||
class AccesslogFormatter(json_log_formatter.JSONFormatter): | ||
def json_record( | ||
self, | ||
message: str, | ||
extra: dict[str, str | int | float], | ||
record: logging.LogRecord, | ||
) -> dict[str, str | int | float]: | ||
return dict( | ||
level=record.levelname, | ||
response_time_ms=int(record.msecs), | ||
time=datetime.datetime.fromtimestamp(record.created), | ||
source=record.args[0], | ||
verb=record.args[1], | ||
path=record.args[2], | ||
status=record.args[4], | ||
) | ||
|
||
|
||
class VerboseJSONFormatter(json_log_formatter.VerboseJSONFormatter): | ||
""" | ||
Wrapper to make logs uniform / easy to search | ||
""" | ||
|
||
def json_record( | ||
self, | ||
message: str, | ||
extra: dict[str, str | int | float], | ||
record: logging.LogRecord, | ||
): | ||
log_item = super().json_record(message, extra, record) | ||
log_item["level"] = log_item.pop("levelname") | ||
|
||
return log_item | ||
|
||
|
||
""" | ||
Wrappers to make sure we always do logs right | ||
- never use a global logger to avoid locks | ||
- don't DI the logger to avoid messyness | ||
Name tweaked to avoid mixup with logging functions | ||
""" | ||
|
||
|
||
def log_info(msg, *args, **kwargs): | ||
logger = logging.getLogger("bia.api") | ||
return logger.info(msg, *args, **kwargs) | ||
|
||
|
||
def log_error(msg, *args, **kwargs): | ||
logger = logging.getLogger("bia.api") | ||
return logger.error(msg, *args, **kwargs) |