ft3.loggers.obj module

Loggers objects.

log = <Logger ft3.loggers.obj (DEBUG)>

Centralized application log.

Pre-configured so you do not need to. By default, this loggger will do everything it can to keep your log stream as actionable and free from pollution as possible.

  • emits neatly formatted JSON log messages

  • intercepts forgotten print statements

  • silences them in all deployed environments

  • intercepts forgotten debug-level logs

  • silences them in deployed environments > dev

  • intercepts irritating warnings, displaying them once as neatly formatted warning level log messages

  • automatically redacts things that should never be logged in the first place (like API Keys, credentials, SSN’s, etc.)

Usage

The expectation is this will be the only log used across an application.

  • Set logging level through the LOG_LEVEL environment variable.

  • Defaults to ‘DEBUG’ if Constants.ENV is either local (default) or dev, otherwise ‘INFO’.

Special Rules

  • Can only log str, dict, and Object types.

  • Automatically redacts almost all sensitive data, including api keys, tokens, credit card numbers, connection strings, and secrets.

  • All warnings will be filtered through this log and displayed only once.

  • All print statements will be silenced except when Constants.ENV is set to ‘local’ (its default if ENV is unavailable in os.environ at runtime).

  • Best practice is to set log level to ‘DEBUG’ and use the log.debug method in place of print statements.

  • warnings will be displayed once for all print statements that would otherwise be silenced in any non-local development environment.

Usage Examples

import ft3

ft3.log.debug('example')
# >>>
# {
#   "level": DEBUG,
#   "timestamp": 2024-02-25T15:30:01.061Z,
#   "logger": ft3,
#   "message": {
#     "content": "example"
#   }
# }

ft3.log.info({'str': 'example', 'a': 2})
# >>>
# {
#   "level": INFO,
#   "timestamp": 2024-02-25T15:31:11.118Z,
#   "logger": ft3,
#   "message": {
#     "a": 2,
#     "str": "example"
#   }
# }


class Pet(ft3.Object):
    """A pet."""

    id_: ft3.Field[str]
    _alternate_id: ft3.Field[str]

    name: ft3.Field[str]
    type: ft3.Field[str]
    in_: ft3.Field[str]
    is_tail_wagging: ft3.Field[bool] = True


ft3.log.debug(Pet)
# >>>
# {
#   "level": DEBUG,
#   "timestamp": 2024-02-25T15:30:01.339Z,
#   "logger": ft3,
#   "message": {
#     "Pet": {
#       "_alternate_id": "Field[str]",
#       "id": "Field[str]",
#       "in": "Field[str]",
#       "is_tail_wagging": "Field[bool]",
#       "name": "Field[str]",
#       "type": "Field[str]"
#     }
#   }
# }

ft3.log.debug(
    Pet(
        id_='abc1234',
        name='Fido',
        type='dog',
        )
    )
# >>>
# {
#   "level": DEBUG,
#   "timestamp": 2024-02-25T15:30:01.450Z,
#   "logger": ft3,
#   "message": {
#     "Pet": {
#       "_alternate_id": null,
#       "id": "abc1234",
#       "in": null,
#       "is_tail_wagging": true,
#       "name": "Fido",
#       "type": "dog"
#     }
#   }
# }