Skip to content

Commit

Permalink
docs: add some explanations
Browse files Browse the repository at this point in the history
Signed-off-by: GRBurst <[email protected]>
  • Loading branch information
GRBurst committed Jul 30, 2023
1 parent 420f213 commit d96e4bf
Showing 1 changed file with 98 additions and 20 deletions.
118 changes: 98 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Slack Python Logger
# Slack Logger Python - A Slack Logger for Python Logging

[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
[![Linting: Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
Expand All @@ -7,18 +7,18 @@

A python logging implementation to send messages to Slack.
Design goals:
1. Python logging interface to be used with the standard logging tools
1. Use Python logging interface such that it can be integrated with standard logging tools.
2. Fully customizable messages with full control over message layout and design.
3. Simple authentication via webhook.
4. Powerful filtering to filter e.g. for environments or particular values only known at runtime.
5. Easy usage to cover most use cases when slack is used for basic alerting.
5. Easy usage to cover most use cases when slack is used for basic alerting and automatic traceback visualization.

To achive aforementioned goals, a handler and a formatter is provided.
To achieve aforementioned goals, the library provides logging handler, formatter and filter implementations.

## Getting Started

1. Install with `pip install slack-logger-python`.
2. Now, you can use the `slack_logger` logger in your python code.
2. Now, you can use the `slack_logger` module in your python code.


### Basic Example with Plain Messages
Expand Down Expand Up @@ -46,6 +46,7 @@ logger.error("Mee too.")

You can use the `SlackFormatter.minimal()` and `SlackFormatter.default()` formatter for more visually appealing log messages.
For now, those require a configuration to show e.g. the header.
Extra fields are shown in blocks at the bottom of the message and can be dynamically added at runtime.
Everything else stays the same:

```python
Expand All @@ -66,16 +67,76 @@ logger.warning("I will show up.")
logger.error("Mee too.")
```

Adding extra fields on single log message is achieved by just putting it in the extra fields of the logging interface:
```python
logger.warning("I will show up.", extra = {"extra_fields": {"foo": "baba"}})
```

## Customization

To do basic customizations, you can provide a configuration to the `SlackFormatter`:

```python
service: Optional[str] = None
environment: Optional[str] = None
context: List[str] = []
emojis: Dict[int, str] = DEFAULT_EMOJIS
extra_fields: Dict[str, str] = {}
```

Let's look at an example error log from a division by zero error.
Given the following code snippet with a configuration and the default formatter:

```python
import os
from slack_logger import Configuration, SlackFormatter, SlackHandler
service_config = Configuration(
service="testrunner", environment="test", extra_fields={"foo": "bar", "raven": "caw"}
)
slack_handler = SlackHandler.from_webhook(os.environ["SLACK_WEBHOOK"])
formatter = SlackFormatter.default(service_config)
slack_handler.setFormatter(formatter)
log.addHandler(slack_handler)
try:
1/0
except Exception:
log.exception("Something terrible happened!")
```

## Design Message - Design Principal (3)
We will get the following error message in slack:
![error_log](https://raw.githubusercontent.com/GRBurst/slack-logger-python/assets/docs/images/error_log.png)

It contains a header, a context, a body and a section containing extra fields.
Let's identify those in the image above.

The header is composed of:
1. Log level emoji: ❌
2. Log level name: ERROR
3. Service name: testrunner

The context contains:
1. Environment: test
2. Service name: testrunner

The body includes:
1. The log error message: "Something terrible happened!"
2. The Traceback error

Extra fields:
1. Field "foo" with value "bar"
2. Field "raven" with value "caw"

### Design Message - Design Principal (3)

Messages are fully customizable using slacks block layout, see [Creating rich message layouts](https://api.slack.com/messaging/composing/layouts) and [Reference: Layout blocks](https://api.slack.com/reference/block-kit/blocks).
By implementing the `MessageDesign` interface, you can fully control in the message design.
By implementing the `MessageDesign` interface, you can fully control in the message design, which requires you to implement a function `format_blocks(record: LogRecord) -> Sequence[Optional[Block]]` to transform a `LogRecord` into a sequence of slack message blocks.
Of course, you can add configurations and helper functions as well.

Let's create our own warning message.
This demonstrates the usage and the implementation of design goal (2).
Let's create our own warning message:

```python
import attrs # for convenience, but required
import attrs # for convenience, but not required
from slack_sdk.models.blocks import Block, DividerBlock, HeaderBlock, SectionBlock
from slack_logger import SlackFormatter

Expand All @@ -97,30 +158,45 @@ formatter = SlackFormatter(design=CustomDesign())
```


### Provide your own set of emojis
#### Provide your own set of emojis

To the default emoji set is a defined by the following dict:
```python
DEFAULT_EMOJIS = {
logging.CRITICAL: ":fire:", # πŸ”₯
logging.ERROR: ":x:", # ❌
logging.FATAL: ":x:", # ❌
logging.WARNING: ":warning:", # ⚠️
logging.WARN: ":warning:", # ⚠️
logging.INFO: ":bell:", # πŸ””
logging.DEBUG: ":microscope:", # πŸ”¬
logging.NOTSET: ":mega:", # πŸ“£
}
```

To the default formatter:
You can import and overwrite it partially, or define a complete new set of emoji.
The following example demonstrates how you can add the emoji set to the `SlackFormatter`:

```python
from slack_logger import Configuration, SlackFormatter

my_emojis = {
logging.CRITICAL: ":x:",
logging.ERROR: ":x:",
logging.FATAL: ":x:",
logging.WARNING: ":bell:",
logging.WARN: ":bell:",
logging.INFO: ":mega:",
logging.DEBUG: ":mega:",
logging.NOTSET: ":mega:",
logging.CRITICAL: ":x:", # ❌
logging.ERROR: ":x:", # ❌
logging.FATAL: ":x:", # ❌
logging.WARNING: ":bell:", # πŸ””
logging.WARN: ":bell:", # πŸ””
logging.INFO: ":mega:", # πŸ“£
logging.DEBUG: ":mega:", # πŸ“£
logging.NOTSET: ":mega:", # πŸ“£
}

config = Configuration(service="testrunner", environment="test", emojis=my_emojis)
formatter = SlackFormatter.default(config)
```


## Filter Message
### Filter Message

Filters implement the logging interface of `Filters`.
Design goal (4) and (5) are partially demonstrated.
Expand All @@ -147,3 +223,5 @@ logger.warning(f"{log_msg} in dev environment and whitelisted prod", extra={"fil
# Will be send
logger.warning(f"{log_msg} in dev environment and whitelisted prod", extra={"filter": {"environment": "prod"}})
```

The composition of configurations, filters and dynamic extra fields allow for a flexible way of specifying your message content and filter unwanted messages.

0 comments on commit d96e4bf

Please sign in to comment.