Skip to content

Commit

Permalink
add special_setting CONFIGURE_LOGGING to auto configure python logging
Browse files Browse the repository at this point in the history
  • Loading branch information
drgarcia1986 committed Feb 18, 2017
1 parent 4f822fd commit af5a6d2
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 3 deletions.
3 changes: 1 addition & 2 deletions ROADMAP.md
Expand Up @@ -6,8 +6,7 @@ Available for testing

Use `pip install git+https://github.com/drgarcia1986/simple-settings.git` to test this features

* Update settings in storages of dynamic readers
* Auto casting settings values in read and write of dynamic settings
* Autoconfigure python logging with `CONFIGURE_LOGGING` _special setting_.

Read the [documentation](http://simple-settings.readthedocs.org/en/latest/) for more informations.

Expand Down
52 changes: 52 additions & 0 deletions docs/index.md
Expand Up @@ -157,6 +157,7 @@ This _special settings_ are specified using a `SIMPLE_SETTINGS` dict in the sett
```python
SIMPLE_SETTINGS = {
'OVERRIDE_BY_ENV': True,
'CONFIGURE_LOGGING': True,
'REQUIRED_SETTINGS': ('API_TOKEN', 'DB_USER'),
'DYNAMIC_SETTINGS': {
'backend': 'redis',
Expand All @@ -168,6 +169,55 @@ SIMPLE_SETTINGS = {
```
_Note: special settings may only be specified in python settings files (not ini, yaml, etc.)._

### Configure logging
If you set the _special setting_ `CONFIGURE_LOGGING` with `True`, _simple-settings_ will configure python logging for you.
You just need to define your logging configuration with
[Python dictConfig format](https://docs.python.org/3.5/library/logging.config.html#configuration-dictionary-schema>)
and place in `LOGGING` setting, e.g.
```python
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'default': {
'format': '%(asctime)s %(levelname)s %(name)s %(message)s'
},
},
'handlers': {
'logfile': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler',
'filename': 'my_log.log',
'maxBytes': 50 * 1024 * 1024,
'backupCount': 10,
'formatter': 'default'
},
},
'loggers': {
'': {
'handlers': ['logfile'],
'level': 'ERROR'
},
'my_project': {
'level': 'INFO',
'propagate': True,
},
}
}
```
To use just get logger with `logging.getLogger()`, e.g.

```python
import logging
logger = logging.getLogger('my_project')


logger.info('Hello')
```

> Don't forget, _simple-settings_ is lazy and it only configures logging after runs `setup()` method
> or after reads some setting.
### Override settings value
You can override the values of your settings module with environment variables.
You just need set the _special setting_ `OVERRIDE_BY_ENV` with `True` as value.
Expand Down Expand Up @@ -285,6 +335,8 @@ assert settings.SOME_SETTING == 'bar'
```

## Changelog
### [NEXT_RELEASE]
* Autoconfigure python logging with `CONFIGURE_LOGGING` _special setting_.

### [0.10.0] - 2016-10-28
* Support configuring dynamic backends with an optional _prefix_.
Expand Down
12 changes: 11 additions & 1 deletion simple_settings/special_settings.py
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
import logging.config
import os

from .constants import SPECIAL_SETTINGS_KEY
Expand Down Expand Up @@ -27,9 +28,18 @@ def override_settings_by_env(settings_dict):
settings_dict[key] = os.environ.get(key, value)


def configure_logging(settings_dict):
if not settings_dict[SPECIAL_SETTINGS_KEY]['CONFIGURE_LOGGING']:
return
cfg = settings_dict.get('LOGGING')
if cfg and isinstance(cfg, dict):
logging.config.dictConfig(cfg)


SPECIAL_SETTINGS_MAPPING = {
'OVERRIDE_BY_ENV': override_settings_by_env,
'REQUIRED_SETTINGS': required_settings
'REQUIRED_SETTINGS': required_settings,
'CONFIGURE_LOGGING': configure_logging
}


Expand Down
21 changes: 21 additions & 0 deletions tests/test_special_settings.py
Expand Up @@ -4,6 +4,7 @@

from simple_settings.special_settings import (
SPECIAL_SETTINGS_MAPPING,
configure_logging,
override_settings_by_env,
process_special_settings,
required_settings
Expand All @@ -26,6 +27,26 @@ def settings_dict_required(self):
'REQUIRED_SETTINGS': ('SIMPLE_STRING', 'LOST_SETTING')
}}

@pytest.fixture
def settings_dict_logging(self):
return {
'SIMPLE_SETTINGS': {'CONFIGURE_LOGGING': True},
'LOGGING': {'dummy': 'dict'}
}

def test_should_autoconfig_python_logging(self, settings_dict_logging):
with patch('logging.config.dictConfig') as mock:
configure_logging(settings_dict_logging)
mock.assert_called_once_with(settings_dict_logging['LOGGING'])

def test_should_dont_autoconfig_python_logging_if_dont_have_special_key(
self, settings_dict_logging
):
settings_dict_logging['SIMPLE_SETTINGS']['CONFIGURE_LOGGING'] = False
with patch('logging.config.dictConfig') as mock:
configure_logging(settings_dict_logging)
assert not mock.called

def test_should_override_by_env(self, settings_dict_to_override):
def mock_env_side_effect(k, d=None):
return u'simple from env' if k == 'SIMPLE_STRING' else d
Expand Down

0 comments on commit af5a6d2

Please sign in to comment.