payla-utils


Namepayla-utils JSON
Version 0.3.1 PyPI version JSON
download
home_page
Summarypayla_utils python package
upload_time2024-01-16 16:54:26
maintainer
docs_urlNone
authorPayla Services
requires_python>=3.9,<4
licenseMIT
keywords payla_utils
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # payla_utils python package

## Features

### Structlog config

#### Example, structlog configuration, django

in django settings.py

    from payla_utils.logging import LoggingConfigurator

    LoggingConfigurator(
        'testapp',
        log_level='INFO',
        own_apps=settings.OWN_APPS,
        setup_logging_dict=True,
    ).configure_structlog(formatter='plain_console')

#### Example, structlog configuration, passing extra loggers names

in django settings.py

    from payla_utils.logging import LoggingConfigurator

    LoggingConfigurator(
        'testapp',
        log_level='INFO',
        own_apps=settings.OWN_APPS,
        setup_logging_dict=True,
    ).configure_structlog(formatter='plain_console', extra_loggers_name=['mylogger1', 'mylogger2'])

#### If you want to use structlog in django celery

in celery.py

    from django.conf import settings
    from payla_utils.logging import LoggingConfigurator

    @signals.setup_logging.connect
    def receiver_setup_logging(
        loglevel, logfile, format, colorize, **kwargs
    ):  # pragma: no cover

        LoggingConfigurator(
            'testapp',
            log_level='INFO',
            own_apps=settings.OWN_APPS,
            setup_logging_dict=True,
        ).configure_structlog(formatter='plain_console')

#### If you want to use structlog with Sentry

You will have to set `PaylaLoggingIntegration` in sentry sdk setup

```python
sentry_sdk.init(
    # take sentry DSN from environment or add a default value here:
    dsn=env.str('SENTRY_DSN'),
    integrations=[DjangoIntegration(), CeleryIntegration(), PaylaLoggingIntegration()],
    auto_session_tracking=False,
    traces_sample_rate=0.01,
    send_default_pii=True,
    attach_stacktrace=True,
    request_bodies='medium',
    release=PROJECT_VERSION,
    environment=ENVIRONMENT,
)
```

### If you want to use a structlog, not Django based project

    from payla_utils.logging import LoggingConfigurator

    LoggingConfigurator(
        'testapp',
        log_level='INFO',
        own_apps=[],
        setup_logging_dict=True,
    ).configure_structlog(formatter='plain_console')

#### How to use generic structured logger:

    logger = structlog.get_logger(__name__)
    logger.warning("Here is your message", key_1="value_1", key_2="value_2", key_n="value_n")

#### Using request middleware to inject request_id and/or trace_id:

This middleware will inject reqest_id and/or trace_id to all logs producer during a request/response cycle.

    MIDDLEWARE += ['payla_utils.logging.middlewares.RequestMiddleware']

-   Pass your custom request id header via the PAYLA_UTILS settings: `REQUEST_ID_HEADER`, defaults to `X-Request-ID`
-   Enable tracing (Only supports opentelemetry) via `configure_structlog(tracing_enabled=True)`

[See configuration section](#Configuration-and-settings)

### Why structured logger

-   By default, the logging frameworks outputs the traces in plain text and tools like EFK stack or Grafana Loki can’t fully process these traces.
-   Therefore, if we “structure” or send the traces in JSON format directly, all the tools can benefit of.
-   As a developer, it would be nice to be able to filter all logs by a certain customer or transaction.
-   The goal of structured logging is to solve these sorts of problems and allow additional analytics.

-   When you log something, remember that the actual consumer is the machine Grafana Loki (EFK stack), not only humans.
-   Our generic logger comes with some default context structure, but as you can see, you can introduce new keys.
-   We use structlog as wraper on standard logging library, you can check for more details [structlog](https://www.structlog.org/en/stable/).

## Access decorator

To prohibit access to only internal IPs for a specific view it's possible to use the `only_internal_access` decorator.

SERVER_IP is required to be set on payla_utils settings.

[See configuration section](#Configuration-and-settings)

Example usage

```python
@only_internal_access
def test_view(request):
    return HttpResponse('OK')
```

Or inline

```python
path('test/', only_internal_access(test_view), name="test-view"),
```

## Management command to init environment

This management command will init environment based on the current env (local.dev, dev, stage, playground and prod)

-   load fixtures on the first run (when the DB is empty)
-   setup custom theme for admin_interface
-   create user when not in prod if `LOCAL_DJANGO_ADMIN_PASSWORD` is set

APP_NAME and ENVIRONMENT settings are required. [See configuration section](#Configuration-and-settings)

## Configuration and settings

Settings for Payla Utils are all namespaced in the PAYLA_UTILS setting.
For example your project's `settings.py` file might look like this:

```python
PAYLA_UTILS = {
    'APP_NAME': 'My App',
    # Used for json logging
    'MICROSERVICE_NAME: 'myapp',
    # dev, stage, prod ...
    'ENVIRONMENT': ENVIRONMENT,
    'INITIAL_FIXTURES': [
        os.path.join(BASE_DIR, 'testapp', 'fixtures', 'users.json'),
    ],
    'SERVER_IP': '192.168.1.4',
    'REQUEST_ID_HEADER': 'X-Request-ID',
    'RUN_EXTRA_COMMANDS': ['loadinitialusers', 'setup_something'],
    'LOCAL_DJANGO_ADMIN_PASSWORD': os.environ.get('LOCAL_DJANGO_ADMIN_PASSWORD', 'admin'),
    # Only in case you need to change the defaults
    'ENV_THEMES': {
        'local.dev': {
            ...
        },
        'dev': {
            ...
        },
        'stage': {
            ...
        },
        'playground': {
            ...
        },
        'prod': {
            ...
        },
    }
}
```

## Payla Generic model

### Usage

    from payla_utils.models import PaylaModel

    class MyModel(PaylaModel):
        ...

This model will add the following fields:

-   `created_at` - datetime
-   `modified_at` - datetime

It has also a QuerySet that will add the following methods:

-   `get_or_none` - returns the object or None

# DRF view action permission

See full documentation [here](payla_utils/access/README.md)

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "payla-utils",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.9,<4",
    "maintainer_email": "",
    "keywords": "payla_utils",
    "author": "Payla Services",
    "author_email": "tools@payla.de",
    "download_url": "https://files.pythonhosted.org/packages/1d/26/d774894046931c6c3bd668cc0184b03a8f5aca3f16f987d7aa464da6bc0b/payla_utils-0.3.1.tar.gz",
    "platform": null,
    "description": "# payla_utils python package\n\n## Features\n\n### Structlog config\n\n#### Example, structlog configuration, django\n\nin django settings.py\n\n    from payla_utils.logging import LoggingConfigurator\n\n    LoggingConfigurator(\n        'testapp',\n        log_level='INFO',\n        own_apps=settings.OWN_APPS,\n        setup_logging_dict=True,\n    ).configure_structlog(formatter='plain_console')\n\n#### Example, structlog configuration, passing extra loggers names\n\nin django settings.py\n\n    from payla_utils.logging import LoggingConfigurator\n\n    LoggingConfigurator(\n        'testapp',\n        log_level='INFO',\n        own_apps=settings.OWN_APPS,\n        setup_logging_dict=True,\n    ).configure_structlog(formatter='plain_console', extra_loggers_name=['mylogger1', 'mylogger2'])\n\n#### If you want to use structlog in django celery\n\nin celery.py\n\n    from django.conf import settings\n    from payla_utils.logging import LoggingConfigurator\n\n    @signals.setup_logging.connect\n    def receiver_setup_logging(\n        loglevel, logfile, format, colorize, **kwargs\n    ):  # pragma: no cover\n\n        LoggingConfigurator(\n            'testapp',\n            log_level='INFO',\n            own_apps=settings.OWN_APPS,\n            setup_logging_dict=True,\n        ).configure_structlog(formatter='plain_console')\n\n#### If you want to use structlog with Sentry\n\nYou will have to set `PaylaLoggingIntegration` in sentry sdk setup\n\n```python\nsentry_sdk.init(\n    # take sentry DSN from environment or add a default value here:\n    dsn=env.str('SENTRY_DSN'),\n    integrations=[DjangoIntegration(), CeleryIntegration(), PaylaLoggingIntegration()],\n    auto_session_tracking=False,\n    traces_sample_rate=0.01,\n    send_default_pii=True,\n    attach_stacktrace=True,\n    request_bodies='medium',\n    release=PROJECT_VERSION,\n    environment=ENVIRONMENT,\n)\n```\n\n### If you want to use a structlog, not Django based project\n\n    from payla_utils.logging import LoggingConfigurator\n\n    LoggingConfigurator(\n        'testapp',\n        log_level='INFO',\n        own_apps=[],\n        setup_logging_dict=True,\n    ).configure_structlog(formatter='plain_console')\n\n#### How to use generic structured logger:\n\n    logger = structlog.get_logger(__name__)\n    logger.warning(\"Here is your message\", key_1=\"value_1\", key_2=\"value_2\", key_n=\"value_n\")\n\n#### Using request middleware to inject request_id and/or trace_id:\n\nThis middleware will inject reqest_id and/or trace_id to all logs producer during a request/response cycle.\n\n    MIDDLEWARE += ['payla_utils.logging.middlewares.RequestMiddleware']\n\n-   Pass your custom request id header via the PAYLA_UTILS settings: `REQUEST_ID_HEADER`, defaults to `X-Request-ID`\n-   Enable tracing (Only supports opentelemetry) via `configure_structlog(tracing_enabled=True)`\n\n[See configuration section](#Configuration-and-settings)\n\n### Why structured logger\n\n-   By default, the logging frameworks outputs the traces in plain text and tools like EFK stack or Grafana Loki can\u2019t fully process these traces.\n-   Therefore, if we \u201cstructure\u201d or send the traces in JSON format directly, all the tools can benefit of.\n-   As a developer, it would be nice to be able to filter all logs by a certain customer or transaction.\n-   The goal of structured logging is to solve these sorts of problems and allow additional analytics.\n\n-   When you log something, remember that the actual consumer is the machine Grafana Loki (EFK stack), not only humans.\n-   Our generic logger comes with some default context structure, but as you can see, you can introduce new keys.\n-   We use structlog as wraper on standard logging library, you can check for more details [structlog](https://www.structlog.org/en/stable/).\n\n## Access decorator\n\nTo prohibit access to only internal IPs for a specific view it's possible to use the `only_internal_access` decorator.\n\nSERVER_IP is required to be set on payla_utils settings.\n\n[See configuration section](#Configuration-and-settings)\n\nExample usage\n\n```python\n@only_internal_access\ndef test_view(request):\n    return HttpResponse('OK')\n```\n\nOr inline\n\n```python\npath('test/', only_internal_access(test_view), name=\"test-view\"),\n```\n\n## Management command to init environment\n\nThis management command will init environment based on the current env (local.dev, dev, stage, playground and prod)\n\n-   load fixtures on the first run (when the DB is empty)\n-   setup custom theme for admin_interface\n-   create user when not in prod if `LOCAL_DJANGO_ADMIN_PASSWORD` is set\n\nAPP_NAME and ENVIRONMENT settings are required. [See configuration section](#Configuration-and-settings)\n\n## Configuration and settings\n\nSettings for Payla Utils are all namespaced in the PAYLA_UTILS setting.\nFor example your project's `settings.py` file might look like this:\n\n```python\nPAYLA_UTILS = {\n    'APP_NAME': 'My App',\n    # Used for json logging\n    'MICROSERVICE_NAME: 'myapp',\n    # dev, stage, prod ...\n    'ENVIRONMENT': ENVIRONMENT,\n    'INITIAL_FIXTURES': [\n        os.path.join(BASE_DIR, 'testapp', 'fixtures', 'users.json'),\n    ],\n    'SERVER_IP': '192.168.1.4',\n    'REQUEST_ID_HEADER': 'X-Request-ID',\n    'RUN_EXTRA_COMMANDS': ['loadinitialusers', 'setup_something'],\n    'LOCAL_DJANGO_ADMIN_PASSWORD': os.environ.get('LOCAL_DJANGO_ADMIN_PASSWORD', 'admin'),\n    # Only in case you need to change the defaults\n    'ENV_THEMES': {\n        'local.dev': {\n            ...\n        },\n        'dev': {\n            ...\n        },\n        'stage': {\n            ...\n        },\n        'playground': {\n            ...\n        },\n        'prod': {\n            ...\n        },\n    }\n}\n```\n\n## Payla Generic model\n\n### Usage\n\n    from payla_utils.models import PaylaModel\n\n    class MyModel(PaylaModel):\n        ...\n\nThis model will add the following fields:\n\n-   `created_at` - datetime\n-   `modified_at` - datetime\n\nIt has also a QuerySet that will add the following methods:\n\n-   `get_or_none` - returns the object or None\n\n# DRF view action permission\n\nSee full documentation [here](payla_utils/access/README.md)\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "payla_utils python package",
    "version": "0.3.1",
    "project_urls": null,
    "split_keywords": [
        "payla_utils"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "752d2fdc4bdd89a9444e814a9b3386108a75a0e25c971fd728fc19d1dad80c64",
                "md5": "238f0cfc36c40b976c40c769ec5d7a86",
                "sha256": "30b8f24f6abd9f890242f564a42c82c6ba59b57543d4d9f93155cf8ad7aeb167"
            },
            "downloads": -1,
            "filename": "payla_utils-0.3.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "238f0cfc36c40b976c40c769ec5d7a86",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9,<4",
            "size": 20433,
            "upload_time": "2024-01-16T16:54:25",
            "upload_time_iso_8601": "2024-01-16T16:54:25.056384Z",
            "url": "https://files.pythonhosted.org/packages/75/2d/2fdc4bdd89a9444e814a9b3386108a75a0e25c971fd728fc19d1dad80c64/payla_utils-0.3.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "1d26d774894046931c6c3bd668cc0184b03a8f5aca3f16f987d7aa464da6bc0b",
                "md5": "c66f4a975c53fdb3deb62acaf3aaee0c",
                "sha256": "6cb8591ee9a0c5bc4cf2c21e92083163500fa78615436717ca1c776526926883"
            },
            "downloads": -1,
            "filename": "payla_utils-0.3.1.tar.gz",
            "has_sig": false,
            "md5_digest": "c66f4a975c53fdb3deb62acaf3aaee0c",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9,<4",
            "size": 17767,
            "upload_time": "2024-01-16T16:54:26",
            "upload_time_iso_8601": "2024-01-16T16:54:26.825960Z",
            "url": "https://files.pythonhosted.org/packages/1d/26/d774894046931c6c3bd668cc0184b03a8f5aca3f16f987d7aa464da6bc0b/payla_utils-0.3.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-01-16 16:54:26",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "payla-utils"
}
        
Elapsed time: 0.16368s