mirror of
https://github.com/jlengrand/bugsink.git
synced 2026-03-10 08:01:17 +00:00
WIP (midway checkin): create_example_conf.py
This commit is contained in:
0
bugsink/scripts/__init__.py
Normal file
0
bugsink/scripts/__init__.py
Normal file
83
bugsink/scripts/create_example_conf.py
Normal file
83
bugsink/scripts/create_example_conf.py
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from django.core.management.utils import get_random_secret_key
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description="Create a configuration file for the example")
|
||||||
|
parser.add_argument("--output-file", "-o", help="Output file", default="bugsink_conf.py")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if os.path.exists(args.output_file):
|
||||||
|
print("Output file already exists; please remove it first")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
secret_key = get_random_secret_key()
|
||||||
|
|
||||||
|
with open(args.output_file, "w") as f:
|
||||||
|
f.write('''# auto-generated example bugsink_conf.py
|
||||||
|
|
||||||
|
# SECURITY WARNING: keep the secret key used in production secret!
|
||||||
|
SECRET_KEY = "''' + secret_key + '''"
|
||||||
|
|
||||||
|
# Alternatively, pass the SECRET_KEY as an environment variable. (although that has security implications too!)
|
||||||
|
# i.e. those may leak in shared server setups.
|
||||||
|
#
|
||||||
|
# SECRET_KEY = os.getenv("SECRET_KEY")
|
||||||
|
|
||||||
|
|
||||||
|
# See TODO in the docs
|
||||||
|
SNAPPEA = {
|
||||||
|
"TASK_ALWAYS_EAGER": True,
|
||||||
|
"NUM_WORKERS": 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# EMAIL_HOST = ...
|
||||||
|
# EMAIL_HOST_USER = ...
|
||||||
|
# EMAIL_HOST_PASSWORD = ...
|
||||||
|
# EMAIL_PORT = ...
|
||||||
|
# EMAIL_USE_TLS = ...
|
||||||
|
|
||||||
|
SERVER_EMAIL = DEFAULT_FROM_EMAIL = "Bugsink <bugsink@example.org>"
|
||||||
|
|
||||||
|
BUGSINK = {
|
||||||
|
# See TODO in the docs
|
||||||
|
# "DIGEST_IMMEDIATELY": False,
|
||||||
|
|
||||||
|
# "MAX_EVENT_SIZE": _MEBIBYTE,
|
||||||
|
# "MAX_EVENT_COMPRESSED_SIZE": 200 * _KIBIBYTE,
|
||||||
|
# "MAX_ENVELOPE_SIZE": 100 * _MEBIBYTE,
|
||||||
|
# "MAX_ENVELOPE_COMPRESSED_SIZE": 20 * _MEBIBYTE,
|
||||||
|
|
||||||
|
# "BASE_URL": "http://bugsink:9000", # no trailing slash
|
||||||
|
# "SITE_TITLE": "Bugsink", # you can customize this as e.g. "My Bugsink" or "Bugsink for My Company"
|
||||||
|
}
|
||||||
|
|
||||||
|
''')
|
||||||
|
|
||||||
|
|
||||||
|
# some thoughts that I haven't been able to squish into a short comment yet:
|
||||||
|
|
||||||
|
# 1. regarding env-variables v.s. just using a conf file: we're not religious about Twelve Factor at all, but even if we
|
||||||
|
# were 12-factor says the following (which is basically what we do):
|
||||||
|
|
||||||
|
# > Another approach to config is the use of config files which are not checked into revision control, such as
|
||||||
|
# > config/database.yml in Rails. This is a huge improvement over using constants which are checked into the code repo,
|
||||||
|
# > but still has weaknesses: it’s easy to mistakenly check in a config file to the repo; there is a tendency for config
|
||||||
|
# > files to be scattered about in different places and different formats, making it hard to see and manage all the
|
||||||
|
# > config in one place. Further, these formats tend to be language- or framework-specific.
|
||||||
|
|
||||||
|
# regarding the mentioned drawbacks: check-in is unlikely (this conf is owned by end-users, not bugsink-programmers) and
|
||||||
|
# scattering is not what we do: we have just a single file for the bugsink conf (though there are separate ones for e.g.
|
||||||
|
# gunicorn and nginx, but I'd argue that's a good thing)
|
||||||
|
#
|
||||||
|
# 2. when comparing with the auto-generated django settings, the SECRET_KEY that we generate here is less likely to be
|
||||||
|
# "automatically exposed", because it is not automatically part of the source code (checked into version control) of
|
||||||
|
# some piece of software. Still, people could check this file in, and you'd have an exposed key in that case.
|
||||||
|
#
|
||||||
|
# 3. regarding the sensitivity of this key, and storing it in the file system: I'd argue that if the server you're
|
||||||
|
# running bugsink on is compromised (and the file can be read) you have bigger problems (since the DB is also on that
|
||||||
|
# server)
|
||||||
0
bugsink/settings/__init__.py
Normal file
0
bugsink/settings/__init__.py
Normal file
@@ -4,13 +4,24 @@ import sys
|
|||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import sentry_sdk
|
|
||||||
from sentry_sdk.integrations.django import DjangoIntegration
|
|
||||||
|
|
||||||
from django.utils.log import DEFAULT_LOGGING
|
from django.utils.log import DEFAULT_LOGGING
|
||||||
|
|
||||||
from debug_toolbar.middleware import show_toolbar
|
from debug_toolbar.middleware import show_toolbar
|
||||||
|
|
||||||
|
|
||||||
|
# We have a single file for our default settings, and expect (if they use the recommended setup) the end-users to
|
||||||
|
# configure their setup using a single bugsink_conf.py also. To be able to have (slightly) different settings for e.g.
|
||||||
|
# logging for various commands, we expose a variable I_AM_RUNNING that can be used to determine what command is being
|
||||||
|
# run. We use (potentially fragile) sys.argv checks to determine what command is being run. For now "it works, don't
|
||||||
|
# fix it"
|
||||||
|
if sys.argv[1:2] == ['runsnappea']:
|
||||||
|
I_AM_RUNNING = "SNAPPEA"
|
||||||
|
elif sys.argv[1:2] == ['test']:
|
||||||
|
I_AM_RUNNING = "TEST"
|
||||||
|
else:
|
||||||
|
I_AM_RUNNING = "OTHER"
|
||||||
|
|
||||||
|
|
||||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||||
|
|
||||||
@@ -18,8 +29,7 @@ BASE_DIR = Path(__file__).resolve().parent.parent
|
|||||||
# SECURITY WARNING: keep the secret key used in production secret!
|
# SECURITY WARNING: keep the secret key used in production secret!
|
||||||
SECRET_KEY = 'django-insecure-$@clhhieazwnxnha-_zah&(bieq%yux7#^07&xsvhn58t)8@xw'
|
SECRET_KEY = 'django-insecure-$@clhhieazwnxnha-_zah&(bieq%yux7#^07&xsvhn58t)8@xw'
|
||||||
|
|
||||||
# SECURITY WARNING: don't run with debug turned on in production!
|
DEBUG = False
|
||||||
DEBUG = True
|
|
||||||
|
|
||||||
ALLOWED_HOSTS = ["*"] # SECURITY WARNING: also make production-worthy
|
ALLOWED_HOSTS = ["*"] # SECURITY WARNING: also make production-worthy
|
||||||
|
|
||||||
@@ -193,6 +203,7 @@ DEBUG_TOOLBAR_CONFIG = {
|
|||||||
|
|
||||||
LOGGING = deepcopy(DEFAULT_LOGGING)
|
LOGGING = deepcopy(DEFAULT_LOGGING)
|
||||||
|
|
||||||
|
if I_AM_RUNNING != "TEST":
|
||||||
# Django's standard logging has LOGGING['handlers']['console']['filters'] = ['require_debug_true']; our app is
|
# Django's standard logging has LOGGING['handlers']['console']['filters'] = ['require_debug_true']; our app is
|
||||||
# configured (by default at least) to just spit everything on stdout, even in production. stdout is picked up by
|
# configured (by default at least) to just spit everything on stdout, even in production. stdout is picked up by
|
||||||
# gunicorn, and we can "take it from there".
|
# gunicorn, and we can "take it from there".
|
||||||
@@ -210,7 +221,7 @@ LOGGING["formatters"]["snappea"] = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LOGGING["handlers"]["snappea"] = {
|
LOGGING["handlers"]["snappea"] = {
|
||||||
"level": "DEBUG" if DEBUG else "INFO",
|
"level": "DEBUG" if DEBUG else "INFO", # TODO this won't work either. but this I can do more classically (development.py)
|
||||||
"class": "logging.StreamHandler"
|
"class": "logging.StreamHandler"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,51 +232,9 @@ LOGGING['loggers']['snappea'] = {
|
|||||||
"handlers": ["snappea"],
|
"handlers": ["snappea"],
|
||||||
}
|
}
|
||||||
|
|
||||||
# TODO sys.argv checking: how do I want to deal with it in my final config setup?
|
|
||||||
if sys.argv[1:2] == ['runsnappea']:
|
if I_AM_RUNNING == "SNAPPEA":
|
||||||
|
# We set all handlers to the snappea handler in this case: this way the things that are logged inside individual
|
||||||
|
# workers show up with the relevant worker-annotations (i.e. threadName).
|
||||||
for logger in LOGGING['loggers'].values():
|
for logger in LOGGING['loggers'].values():
|
||||||
logger["handlers"] = ["snappea"]
|
logger["handlers"] = ["snappea"]
|
||||||
|
|
||||||
|
|
||||||
# ###################### MOST PER-SITE CONFIG BELOW THIS LINE ###################
|
|
||||||
|
|
||||||
|
|
||||||
# {PROTOCOL}://{PUBLIC_KEY}:{DEPRECATED_SECRET_KEY}@{HOST}{PATH}/{PROJECT_ID}
|
|
||||||
SENTRY_DSN = os.getenv("SENTRY_DSN")
|
|
||||||
|
|
||||||
|
|
||||||
if SENTRY_DSN is not None:
|
|
||||||
sentry_sdk.init(
|
|
||||||
dsn=SENTRY_DSN,
|
|
||||||
integrations=[DjangoIntegration()],
|
|
||||||
auto_session_tracking=False,
|
|
||||||
traces_sample_rate=0,
|
|
||||||
send_default_pii=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
SNAPPEA = {
|
|
||||||
"TASK_ALWAYS_EAGER": True,
|
|
||||||
"NUM_WORKERS": 1,
|
|
||||||
}
|
|
||||||
|
|
||||||
POSTMARK_API_KEY = os.getenv('POSTMARK_API_KEY')
|
|
||||||
|
|
||||||
EMAIL_HOST = 'smtp.postmarkapp.com'
|
|
||||||
EMAIL_HOST_USER = POSTMARK_API_KEY
|
|
||||||
EMAIL_HOST_PASSWORD = POSTMARK_API_KEY
|
|
||||||
EMAIL_PORT = 587
|
|
||||||
EMAIL_USE_TLS = True
|
|
||||||
|
|
||||||
SERVER_EMAIL = DEFAULT_FROM_EMAIL = 'Klaas van Schelven <klaas@vanschelven.com>'
|
|
||||||
|
|
||||||
BUGSINK = {
|
|
||||||
"DIGEST_IMMEDIATELY": False,
|
|
||||||
|
|
||||||
# "MAX_EVENT_SIZE": _MEBIBYTE,
|
|
||||||
# "MAX_EVENT_COMPRESSED_SIZE": 200 * _KIBIBYTE,
|
|
||||||
# "MAX_ENVELOPE_SIZE": 100 * _MEBIBYTE,
|
|
||||||
# "MAX_ENVELOPE_COMPRESSED_SIZE": 20 * _MEBIBYTE,
|
|
||||||
|
|
||||||
"BASE_URL": "http://bugsink:9000", # no trailing slash
|
|
||||||
"SITE_TITLE": "Bugsink", # you can customize this as e.g. "My Bugsink" or "Bugsink for My Company"
|
|
||||||
}
|
|
||||||
49
bugsink/settings/development.py
Normal file
49
bugsink/settings/development.py
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
from .default import * # noqa
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
import sentry_sdk
|
||||||
|
from sentry_sdk.integrations.django import DjangoIntegration
|
||||||
|
|
||||||
|
|
||||||
|
DEBUG = True
|
||||||
|
|
||||||
|
# {PROTOCOL}://{PUBLIC_KEY}:{DEPRECATED_SECRET_KEY}@{HOST}{PATH}/{PROJECT_ID}
|
||||||
|
SENTRY_DSN = os.getenv("SENTRY_DSN")
|
||||||
|
|
||||||
|
|
||||||
|
if SENTRY_DSN is not None:
|
||||||
|
sentry_sdk.init(
|
||||||
|
dsn=SENTRY_DSN,
|
||||||
|
integrations=[DjangoIntegration()],
|
||||||
|
auto_session_tracking=False,
|
||||||
|
traces_sample_rate=0,
|
||||||
|
send_default_pii=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
SNAPPEA = {
|
||||||
|
"TASK_ALWAYS_EAGER": True,
|
||||||
|
"NUM_WORKERS": 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
POSTMARK_API_KEY = os.getenv('POSTMARK_API_KEY')
|
||||||
|
|
||||||
|
EMAIL_HOST = 'smtp.postmarkapp.com'
|
||||||
|
EMAIL_HOST_USER = POSTMARK_API_KEY
|
||||||
|
EMAIL_HOST_PASSWORD = POSTMARK_API_KEY
|
||||||
|
EMAIL_PORT = 587
|
||||||
|
EMAIL_USE_TLS = True
|
||||||
|
|
||||||
|
SERVER_EMAIL = DEFAULT_FROM_EMAIL = 'Klaas van Schelven <klaas@vanschelven.com>'
|
||||||
|
|
||||||
|
BUGSINK = {
|
||||||
|
"DIGEST_IMMEDIATELY": False,
|
||||||
|
|
||||||
|
# "MAX_EVENT_SIZE": _MEBIBYTE,
|
||||||
|
# "MAX_EVENT_COMPRESSED_SIZE": 200 * _KIBIBYTE,
|
||||||
|
# "MAX_ENVELOPE_SIZE": 100 * _MEBIBYTE,
|
||||||
|
# "MAX_ENVELOPE_COMPRESSED_SIZE": 20 * _MEBIBYTE,
|
||||||
|
|
||||||
|
"BASE_URL": "http://bugsink:9000", # no trailing slash
|
||||||
|
"SITE_TITLE": "Bugsink", # you can customize this as e.g. "My Bugsink" or "Bugsink for My Company"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user