diff --git a/config/asgi.py b/config/asgi.py index 92797717..61c38a22 100644 --- a/config/asgi.py +++ b/config/asgi.py @@ -19,7 +19,7 @@ ROOT_DIR = Path(__file__).resolve(strict=True).parent.parent sys.path.append(str(ROOT_DIR / "vbv_lernwelt")) # If DJANGO_SETTINGS_MODULE is unset, default to the local settings -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local") +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.base") # This application object is used by any ASGI server configured to use this file. django_application = get_asgi_application() diff --git a/config/settings/base.py b/config/settings/base.py index f28073af..a0dfee50 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -1,9 +1,11 @@ """ Base settings to build other settings files upon. """ +import logging from pathlib import Path import environ +import structlog ROOT_DIR = Path(__file__).resolve(strict=True).parent.parent.parent # vbv_lernwelt/ @@ -40,8 +42,9 @@ LOCALE_PATHS = [str(ROOT_DIR / "locale")] # DATABASES # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#databases -DATABASES = {"default": env.db("VBV_DATABASE_URL")} -DATABASES["default"]["ATOMIC_REQUESTS"] = True +DATABASES = {"default": env.db_url("VBV_DATABASE_URL")} +DATABASES["default"]["ATOMIC_REQUESTS"] = True # noqa F405 +DATABASES["default"]["CONN_MAX_AGE"] = env.int("CONN_MAX_AGE", default=60) # noqa F405 # https://docs.djangoproject.com/en/stable/ref/settings/#std:setting-DEFAULT_AUTO_FIELD DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" @@ -215,9 +218,9 @@ X_FRAME_OPTIONS = "DENY" # EMAIL # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#email-backend +# FIXME how to send emails? EMAIL_BACKEND = env( - "DJANGO_EMAIL_BACKEND", - default="django.core.mail.backends.smtp.EmailBackend", + "DJANGO_EMAIL_BACKEND", default="django.core.mail.backends.console.EmailBackend" ) # https://docs.djangoproject.com/en/dev/ref/settings/#email-timeout EMAIL_TIMEOUT = 5 @@ -255,6 +258,119 @@ LOGGING = { "root": {"level": "INFO", "handlers": ["console"]}, } +VBV_DJANGO_LOGGING_CONF = env("VBV_DJANGO_LOGGING_CONF", default="VBV_DJANGO_LOGGING_CONF_JSON_FILE") + +if VBV_DJANGO_LOGGING_CONF == "VBV_DJANGO_LOGGING_CONF_CONSOLE_COLOR": + timestamper = structlog.processors.TimeStamper(fmt="%Y-%m-%d %H:%M:%S") + pre_chain = [ + structlog.stdlib.add_log_level, + timestamper, + ] + LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'formatters': { + 'colored': { + '()': structlog.stdlib.ProcessorFormatter, + 'processor': structlog.dev.ConsoleRenderer(colors=True), + 'foreign_pre_chain': pre_chain, + }, + }, + 'handlers': { + 'default': { + 'class': 'logging.StreamHandler', + 'formatter': 'colored', + }, + }, + 'loggers': { + '': { + 'handlers': ['default'], + 'level': 'INFO', + 'propagate': True, + }, + 'vbv_lernwelt': { + 'handlers': ['default'], + 'level': 'DEBUG', + 'propagate': False, + }, + } + } + + structlog.configure( + processors=[ + structlog.threadlocal.merge_threadlocal, + structlog.stdlib.add_log_level, + structlog.stdlib.PositionalArgumentsFormatter(), + timestamper, + structlog.processors.StackInfoRenderer(), + structlog.processors.format_exc_info, + structlog.stdlib.ProcessorFormatter.wrap_for_formatter, + ], + context_class=dict, + logger_factory=structlog.stdlib.LoggerFactory(), + wrapper_class=structlog.stdlib.BoundLogger, + cache_logger_on_first_use=True, + ) +else: + LOGGING = { + 'version': 1, + 'disable_existing_loggers': True, + 'formatters': { + 'json': { + '()': 'pythonjsonlogger.jsonlogger.JsonFormatter', + 'format': '%(asctime)s %(msecs)03d %(process)d %(thread)d %(levelname)s %(name)s %(filename)s %(lineno)d %(funcName)s %(message)s', + 'datefmt': '%Y-%m-%dT%H:%M:%S', + }, + }, + 'handlers': { + 'file': { + 'class': 'concurrent_log_handler.ConcurrentRotatingFileHandler', + 'filename': f'{ROOT_DIR}/log/myservice.log', + 'maxBytes': 1024 * 1024 * 100, + 'backupCount': 50, + 'formatter': 'json', + }, + "console": { + "level": "DEBUG", + "class": "logging.StreamHandler", + "formatter": "verbose", + }, + }, + 'loggers': { + '': { + 'handlers': ['console', 'file'], + 'level': 'INFO', + }, + 'django': { + 'handlers': ['console', 'file'], + 'level': 'WARNING', + 'propagate': False, + }, + 'vbc_lernwelt': { + 'handlers': ['console', 'file'], + 'level': 'DEBUG', + 'propagate': False, + }, + "sentry_sdk": {"level": "ERROR", "handlers": ["console"], "propagate": False}, + } + } + + structlog.configure( + processors=[ + structlog.threadlocal.merge_threadlocal, + structlog.stdlib.filter_by_level, + structlog.stdlib.PositionalArgumentsFormatter(), + structlog.processors.StackInfoRenderer(), + structlog.processors.format_exc_info, + structlog.processors.UnicodeDecoder(), + structlog.stdlib.render_to_log_kwargs, + ], + context_class=dict, + logger_factory=structlog.stdlib.LoggerFactory(), + wrapper_class=structlog.stdlib.BoundLogger, + cache_logger_on_first_use=True, + ) + # django-allauth # ------------------------------------------------------------------------------ @@ -302,3 +418,156 @@ SPECTACULAR_SETTINGS = { } # Your stuff... # ------------------------------------------------------------------------------ + +DJANGO_DEV_MODE = env("VBV_DJANGO_DEV_MODE", default="development") + +SECRET_KEY = env( + "VBV_DJANGO_SECRET_KEY", + default="J9FiYN31FuY7lHrmx9Mpai3GGpTVCxakEclOfCLretDe7bTf2DtTsgazJ0aIMtbq", +) +# https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts +ALLOWED_HOSTS = env.list("VBV_DJANGO_ALLOWED_HOSTS", default=["localhost", "0.0.0.0", "127.0.0.1"]) + + +# CACHES +CACHES = { + 'default': { + 'BACKEND': env("VBV_DJANGO_CACHE_BACKEND", default='django.core.cache.backends.db.DatabaseCache'), + 'LOCATION': env("VBV_DJANGO_CACHE_LOCATION", default='django_cache_table'), + } +} + +if 'django_redis.cache.RedisCache' in env("VBV_DJANGO_CACHE_BACKEND", default=''): + CACHES = { + 'default': { + 'BACKEND': env("VBV_DJANGO_CACHE_BACKEND", default='django.core.cache.backends.db.DatabaseCache'), + 'LOCATION': env("VBV_DJANGO_CACHE_LOCATION", default='django_cache_table'), + "OPTIONS": { + "CLIENT_CLASS": "django_redis.client.DefaultClient", + # Mimicing memcache behavior. + # https://github.com/jazzband/django-redis#memcached-exceptions-behavior + "IGNORE_EXCEPTIONS": True, + }, + } + } + +if DJANGO_DEV_MODE == "development": + # http://whitenoise.evans.io/en/latest/django.html#using-whitenoise-in-development + INSTALLED_APPS = ["whitenoise.runserver_nostatic"] + INSTALLED_APPS # noqa F405 + + # django-debug-toolbar + # ------------------------------------------------------------------------------ + # https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#prerequisites + INSTALLED_APPS += ["debug_toolbar"] # noqa F405 + # https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#middleware + MIDDLEWARE += ["debug_toolbar.middleware.DebugToolbarMiddleware"] # noqa F405 + # https://django-debug-toolbar.readthedocs.io/en/latest/configuration.html#debug-toolbar-config + DEBUG_TOOLBAR_CONFIG = { + "DISABLE_PANELS": ["debug_toolbar.panels.redirects.RedirectsPanel"], + "SHOW_TEMPLATE_CONTEXT": True, + } + # https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#internal-ips + INTERNAL_IPS = ["127.0.0.1", "10.0.2.2"] + if env.bool("VBV_DJANGO_LOCAL_DOCKER", False): + import socket + + hostname, _, ips = socket.gethostbyname_ex(socket.gethostname()) + INTERNAL_IPS += [".".join(ip.split(".")[:-1] + ["1"]) for ip in ips] + try: + _, _, ips = socket.gethostbyname_ex("node") + INTERNAL_IPS.extend(ips) + except socket.gaierror: + # The node container isn't started (yet?) + pass + + # django-extensions + # ------------------------------------------------------------------------------ + # https://django-extensions.readthedocs.io/en/latest/installation_instructions.html#configuration + INSTALLED_APPS += ["django_extensions"] # noqa F405 + +if DJANGO_DEV_MODE == "production": + # SECURITY + # ------------------------------------------------------------------------------ + # https://docs.djangoproject.com/en/dev/ref/settings/#secure-proxy-ssl-header + SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") + # https://docs.djangoproject.com/en/dev/ref/settings/#secure-ssl-redirect + SECURE_SSL_REDIRECT = env.bool("VBV_DJANGO_SECURE_SSL_REDIRECT", default=True) + # https://docs.djangoproject.com/en/dev/ref/settings/#session-cookie-secure + SESSION_COOKIE_SECURE = True + # https://docs.djangoproject.com/en/dev/ref/settings/#csrf-cookie-secure + CSRF_COOKIE_SECURE = True + # https://docs.djangoproject.com/en/dev/topics/security/#ssl-https + # https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-seconds + # TODO: set this to 60 seconds first and then to 518400 once you prove the former works + SECURE_HSTS_SECONDS = 60 + # https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-include-subdomains + SECURE_HSTS_INCLUDE_SUBDOMAINS = env.bool( + "DJANGO_SECURE_HSTS_INCLUDE_SUBDOMAINS", default=True + ) + # https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-preload + SECURE_HSTS_PRELOAD = env.bool("DJANGO_SECURE_HSTS_PRELOAD", default=True) + # https://docs.djangoproject.com/en/dev/ref/middleware/#x-content-type-options-nosniff + SECURE_CONTENT_TYPE_NOSNIFF = env.bool( + "DJANGO_SECURE_CONTENT_TYPE_NOSNIFF", default=True + ) + + # STATIC + # ------------------------ + STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage" + # MEDIA + # ------------------------------------------------------------------------------ + + # EMAIL + # ------------------------------------------------------------------------------ + # https://docs.djangoproject.com/en/dev/ref/settings/#default-from-email + DEFAULT_FROM_EMAIL = env( + "DJANGO_DEFAULT_FROM_EMAIL", + default="VBV Lernwelt ", + ) + # https://docs.djangoproject.com/en/dev/ref/settings/#server-email + SERVER_EMAIL = env("VBV_DJANGO_SERVER_EMAIL", default=DEFAULT_FROM_EMAIL) + # https://docs.djangoproject.com/en/dev/ref/settings/#email-subject-prefix + EMAIL_SUBJECT_PREFIX = env( + "DJANGO_EMAIL_SUBJECT_PREFIX", + default="[VBV Lernwelt]", + ) + + # ADMIN + # ------------------------------------------------------------------------------ + # Django Admin URL regex. + ADMIN_URL = env("VBV_DJANGO_ADMIN_URL") + + # Anymail + # ------------------------------------------------------------------------------ + # https://anymail.readthedocs.io/en/stable/installation/#installing-anymail + INSTALLED_APPS += ["anymail"] # noqa F405 + # https://docs.djangoproject.com/en/dev/ref/settings/#email-backend + # https://anymail.readthedocs.io/en/stable/installation/#anymail-settings-reference + # https://anymail.readthedocs.io/en/stable/esps + EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend" + ANYMAIL = {} + + # Sentry + # ------------------------------------------------------------------------------ + import sentry_sdk + from sentry_sdk.integrations.django import DjangoIntegration + from sentry_sdk.integrations.logging import LoggingIntegration + from sentry_sdk.integrations.redis import RedisIntegration + + SENTRY_DSN = env("VBV_SENTRY_DSN") + SENTRY_LOG_LEVEL = env.int("DJANGO_SENTRY_LOG_LEVEL", logging.INFO) + + sentry_logging = LoggingIntegration( + level=SENTRY_LOG_LEVEL, # Capture info and above as breadcrumbs + event_level=logging.ERROR, # Send errors as events + ) + integrations = [sentry_logging, DjangoIntegration(), RedisIntegration()] + sentry_sdk.init( + dsn=SENTRY_DSN, + integrations=integrations, + environment=env("SENTRY_ENVIRONMENT", default="production"), + traces_sample_rate=env.float("SENTRY_TRACES_SAMPLE_RATE", default=0.0), + ) + + # Your stuff... + # ------------------------------------------------------------------------------ diff --git a/config/settings/local.py b/config/settings/local.py deleted file mode 100644 index 03a0d209..00000000 --- a/config/settings/local.py +++ /dev/null @@ -1,70 +0,0 @@ -from .base import * # noqa -from .base import env - -# GENERAL -# ------------------------------------------------------------------------------ -# https://docs.djangoproject.com/en/dev/ref/settings/#debug -DEBUG = True -# https://docs.djangoproject.com/en/dev/ref/settings/#secret-key -SECRET_KEY = env( - "VBV_DJANGO_SECRET_KEY", - default="J9FiYN31FuY7lHrmx9Mpai3GGpTVCxakEclOfCLretDe7bTf2DtTsgazJ0aIMtbq", -) -# https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts -ALLOWED_HOSTS = ["localhost", "0.0.0.0", "127.0.0.1"] - -# CACHES -# ------------------------------------------------------------------------------ -# https://docs.djangoproject.com/en/dev/ref/settings/#caches -CACHES = { - "default": { - "BACKEND": "django.core.cache.backends.locmem.LocMemCache", - "LOCATION": "", - } -} - -# EMAIL -# ------------------------------------------------------------------------------ -# https://docs.djangoproject.com/en/dev/ref/settings/#email-backend -EMAIL_BACKEND = env( - "DJANGO_EMAIL_BACKEND", default="django.core.mail.backends.console.EmailBackend" -) - -# WhiteNoise -# ------------------------------------------------------------------------------ -# http://whitenoise.evans.io/en/latest/django.html#using-whitenoise-in-development -INSTALLED_APPS = ["whitenoise.runserver_nostatic"] + INSTALLED_APPS # noqa F405 - - -# django-debug-toolbar -# ------------------------------------------------------------------------------ -# https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#prerequisites -INSTALLED_APPS += ["debug_toolbar"] # noqa F405 -# https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#middleware -MIDDLEWARE += ["debug_toolbar.middleware.DebugToolbarMiddleware"] # noqa F405 -# https://django-debug-toolbar.readthedocs.io/en/latest/configuration.html#debug-toolbar-config -DEBUG_TOOLBAR_CONFIG = { - "DISABLE_PANELS": ["debug_toolbar.panels.redirects.RedirectsPanel"], - "SHOW_TEMPLATE_CONTEXT": True, -} -# https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#internal-ips -INTERNAL_IPS = ["127.0.0.1", "10.0.2.2"] -if env("USE_DOCKER") == "yes": - import socket - - hostname, _, ips = socket.gethostbyname_ex(socket.gethostname()) - INTERNAL_IPS += [".".join(ip.split(".")[:-1] + ["1"]) for ip in ips] - try: - _, _, ips = socket.gethostbyname_ex("node") - INTERNAL_IPS.extend(ips) - except socket.gaierror: - # The node container isn't started (yet?) - pass - -# django-extensions -# ------------------------------------------------------------------------------ -# https://django-extensions.readthedocs.io/en/latest/installation_instructions.html#configuration -INSTALLED_APPS += ["django_extensions"] # noqa F405 - -# Your stuff... -# ------------------------------------------------------------------------------ diff --git a/config/settings/production.py b/config/settings/production.py deleted file mode 100644 index 896269ec..00000000 --- a/config/settings/production.py +++ /dev/null @@ -1,158 +0,0 @@ -import logging - -import sentry_sdk -from sentry_sdk.integrations.django import DjangoIntegration -from sentry_sdk.integrations.logging import LoggingIntegration -from sentry_sdk.integrations.redis import RedisIntegration - -from .base import * # noqa -from .base import env - -# GENERAL -# ------------------------------------------------------------------------------ -# https://docs.djangoproject.com/en/dev/ref/settings/#secret-key -SECRET_KEY = env("VBV_DJANGO_SECRET_KEY") -# https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts -ALLOWED_HOSTS = env.list("VBV_DJANGO_ALLOWED_HOSTS", default=["vbv-lernwelt.iterativ.ch"]) - -# DATABASES -# ------------------------------------------------------------------------------ -DATABASES["default"] = env.db("VBV_DATABASE_URL") # noqa F405 -DATABASES["default"]["ATOMIC_REQUESTS"] = True # noqa F405 -DATABASES["default"]["CONN_MAX_AGE"] = env.int("CONN_MAX_AGE", default=60) # noqa F405 - -# CACHES -# ------------------------------------------------------------------------------ -CACHES = { - "default": { - "BACKEND": "django_redis.cache.RedisCache", - "LOCATION": env("VBV_REDIS_URL"), - "OPTIONS": { - "CLIENT_CLASS": "django_redis.client.DefaultClient", - # Mimicing memcache behavior. - # https://github.com/jazzband/django-redis#memcached-exceptions-behavior - "IGNORE_EXCEPTIONS": True, - }, - } -} - -# SECURITY -# ------------------------------------------------------------------------------ -# https://docs.djangoproject.com/en/dev/ref/settings/#secure-proxy-ssl-header -SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") -# https://docs.djangoproject.com/en/dev/ref/settings/#secure-ssl-redirect -SECURE_SSL_REDIRECT = env.bool("VBV_DJANGO_SECURE_SSL_REDIRECT", default=True) -# https://docs.djangoproject.com/en/dev/ref/settings/#session-cookie-secure -SESSION_COOKIE_SECURE = True -# https://docs.djangoproject.com/en/dev/ref/settings/#csrf-cookie-secure -CSRF_COOKIE_SECURE = True -# https://docs.djangoproject.com/en/dev/topics/security/#ssl-https -# https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-seconds -# TODO: set this to 60 seconds first and then to 518400 once you prove the former works -SECURE_HSTS_SECONDS = 60 -# https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-include-subdomains -SECURE_HSTS_INCLUDE_SUBDOMAINS = env.bool( - "DJANGO_SECURE_HSTS_INCLUDE_SUBDOMAINS", default=True -) -# https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-preload -SECURE_HSTS_PRELOAD = env.bool("DJANGO_SECURE_HSTS_PRELOAD", default=True) -# https://docs.djangoproject.com/en/dev/ref/middleware/#x-content-type-options-nosniff -SECURE_CONTENT_TYPE_NOSNIFF = env.bool( - "DJANGO_SECURE_CONTENT_TYPE_NOSNIFF", default=True -) - -# STATIC -# ------------------------ -STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage" -# MEDIA -# ------------------------------------------------------------------------------ - -# EMAIL -# ------------------------------------------------------------------------------ -# https://docs.djangoproject.com/en/dev/ref/settings/#default-from-email -DEFAULT_FROM_EMAIL = env( - "DJANGO_DEFAULT_FROM_EMAIL", - default="VBV Lernwelt ", -) -# https://docs.djangoproject.com/en/dev/ref/settings/#server-email -SERVER_EMAIL = env("VBV_DJANGO_SERVER_EMAIL", default=DEFAULT_FROM_EMAIL) -# https://docs.djangoproject.com/en/dev/ref/settings/#email-subject-prefix -EMAIL_SUBJECT_PREFIX = env( - "DJANGO_EMAIL_SUBJECT_PREFIX", - default="[VBV Lernwelt]", -) - -# ADMIN -# ------------------------------------------------------------------------------ -# Django Admin URL regex. -ADMIN_URL = env("VBV_DJANGO_ADMIN_URL") - -# Anymail -# ------------------------------------------------------------------------------ -# https://anymail.readthedocs.io/en/stable/installation/#installing-anymail -INSTALLED_APPS += ["anymail"] # noqa F405 -# https://docs.djangoproject.com/en/dev/ref/settings/#email-backend -# https://anymail.readthedocs.io/en/stable/installation/#anymail-settings-reference -# https://anymail.readthedocs.io/en/stable/esps -EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend" -ANYMAIL = {} - - -# LOGGING -# ------------------------------------------------------------------------------ -# https://docs.djangoproject.com/en/dev/ref/settings/#logging -# See https://docs.djangoproject.com/en/dev/topics/logging for -# more details on how to customize your logging configuration. - -LOGGING = { - "version": 1, - "disable_existing_loggers": True, - "formatters": { - "verbose": { - "format": "%(levelname)s %(asctime)s %(module)s " - "%(process)d %(thread)d %(message)s" - } - }, - "handlers": { - "console": { - "level": "DEBUG", - "class": "logging.StreamHandler", - "formatter": "verbose", - } - }, - "root": {"level": "INFO", "handlers": ["console"]}, - "loggers": { - "django.db.backends": { - "level": "ERROR", - "handlers": ["console"], - "propagate": False, - }, - # Errors logged by the SDK itself - "sentry_sdk": {"level": "ERROR", "handlers": ["console"], "propagate": False}, - "django.security.DisallowedHost": { - "level": "ERROR", - "handlers": ["console"], - "propagate": False, - }, - }, -} - -# Sentry -# ------------------------------------------------------------------------------ -SENTRY_DSN = env("VBV_SENTRY_DSN") -SENTRY_LOG_LEVEL = env.int("DJANGO_SENTRY_LOG_LEVEL", logging.INFO) - -sentry_logging = LoggingIntegration( - level=SENTRY_LOG_LEVEL, # Capture info and above as breadcrumbs - event_level=logging.ERROR, # Send errors as events -) -integrations = [sentry_logging, DjangoIntegration(), RedisIntegration()] -sentry_sdk.init( - dsn=SENTRY_DSN, - integrations=integrations, - environment=env("SENTRY_ENVIRONMENT", default="production"), - traces_sample_rate=env.float("SENTRY_TRACES_SAMPLE_RATE", default=0.0), -) - -# Your stuff... -# ------------------------------------------------------------------------------ diff --git a/config/wsgi.py b/config/wsgi.py index 95c67755..bb428756 100644 --- a/config/wsgi.py +++ b/config/wsgi.py @@ -26,8 +26,7 @@ sys.path.append(str(ROOT_DIR / "vbv_lernwelt")) # We defer to a DJANGO_SETTINGS_MODULE already in the environment. This breaks # if running multiple sites in the same mod_wsgi process. To fix this, use # mod_wsgi daemon mode with each site in its own daemon process, or use -# os.environ["DJANGO_SETTINGS_MODULE"] = "config.settings.production" -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.production") +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.base") # This application object is used by any WSGI server configured to use this # file. This includes Django's development server, if the WSGI_APPLICATION diff --git a/env/docker_local.env b/env/docker_local.env index 7d955f97..7f067c47 100644 --- a/env/docker_local.env +++ b/env/docker_local.env @@ -8,5 +8,5 @@ VBV_POSTGRES_PASSWORD=hNqfCdG6bwCLcnfboDtNM1L2Hiwp8GuKp1DJ6t2rcKl15Vls2QbByoIZ6I # General # ------------------------------------------------------------------------------ -USE_DOCKER=yes +VBV_DJANGO_LOCAL_DOCKER=True IPYTHONDIR=/app/.ipython diff --git a/env_secrets/production.env b/env_secrets/production.env index 388376c5..7b9d29a2 100644 Binary files a/env_secrets/production.env and b/env_secrets/production.env differ diff --git a/example.env b/example.env index 4260645e..0db68299 100644 --- a/example.env +++ b/example.env @@ -1,2 +1,2 @@ export VBV_DATABASE_URL='postgres://vbv_lernwelt@localhost:5432/vbv_lernwelt' -export USE_DOCKER=false +export VBV_DJANGO_LOGGING_CONF=VBV_DJANGO_LOGGING_CONF_CONSOLE_COLOR diff --git a/local.yml b/local.yml index 354250ec..0d67a876 100644 --- a/local.yml +++ b/local.yml @@ -7,7 +7,7 @@ volumes: services: django: build: - - ./.envs/.local/.postgres + - ./env/docker_local.env context: . dockerfile: ./compose/local/django/Dockerfile image: vbv_lernwelt_local_django diff --git a/manage.py b/manage.py index e9edf539..16551f11 100755 --- a/manage.py +++ b/manage.py @@ -4,7 +4,7 @@ import sys from pathlib import Path if __name__ == "__main__": - os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local") + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.base") try: from django.core.management import execute_from_command_line diff --git a/requirements/requirements-dev.txt b/requirements/requirements-dev.txt index 662e41b8..d3de1c6a 100644 --- a/requirements/requirements-dev.txt +++ b/requirements/requirements-dev.txt @@ -45,6 +45,8 @@ click==8.0.3 # black # pip-tools # uvicorn +concurrent-log-handler==0.9.19 + # via -r requirements.in coreapi==2.3.3 # via djangorestframework-stubs coreschema==0.0.4 @@ -210,6 +212,8 @@ platformdirs==2.4.1 # virtualenv pluggy==1.0.0 # via pytest +portalocker==2.3.2 + # via concurrent-log-handler pre-commit==2.17.0 # via -r requirements-dev.in prompt-toolkit==3.0.26 @@ -257,6 +261,8 @@ python-dateutil==2.8.2 # via faker python-dotenv==0.19.2 # via uvicorn +python-json-logger==2.0.2 + # via -r requirements.in python-slugify==5.0.2 # via -r requirements.in python3-openid==3.2.0 @@ -297,6 +303,8 @@ sqlparse==0.4.2 # django-debug-toolbar stack-data==0.1.4 # via ipython +structlog==21.5.0 + # via -r requirements.in termcolor==1.1.0 # via pytest-sugar testfixtures==6.18.3 diff --git a/requirements/requirements.in b/requirements/requirements.in index 4081795d..db7b7578 100644 --- a/requirements/requirements.in +++ b/requirements/requirements.in @@ -25,3 +25,7 @@ drf-spectacular psycopg2-binary gunicorn sentry-sdk + +structlog +python-json-logger +concurrent-log-handler diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 6b9af6a5..551cf571 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -26,6 +26,8 @@ charset-normalizer==2.0.11 # via requests click==8.0.3 # via uvicorn +concurrent-log-handler==0.9.19 + # via -r requirements.in crispy-bootstrap5==0.6 # via -r requirements.in cryptography==36.0.1 @@ -84,6 +86,8 @@ packaging==21.3 # via redis pillow==9.0.0 # via -r requirements.in +portalocker==2.3.2 + # via concurrent-log-handler psycopg2-binary==2.9.3 # via -r requirements.in pycparser==2.21 @@ -96,6 +100,8 @@ pyrsistent==0.18.1 # via jsonschema python-dotenv==0.19.2 # via uvicorn +python-json-logger==2.0.2 + # via -r requirements.in python-slugify==5.0.2 # via -r requirements.in python3-openid==3.2.0 @@ -123,6 +129,8 @@ sentry-sdk==1.5.4 # via -r requirements.in sqlparse==0.4.2 # via django +structlog==21.5.0 + # via -r requirements.in text-unidecode==1.3 # via python-slugify uritemplate==4.1.1