[![PyPI version](https://badge.fury.io/py/python-logging-discord-handler.svg)](https://badge.fury.io/py/python-logging-discord-handler)
[![Automated test suite](https://github.com/tradingstrategy-ai/python-logging-discord-handler/actions/workflows/tests.yml/badge.svg)](https://github.com/tradingstrategy-ai/python-logging-discord-handler/actions/workflows/tests.yml)
[![Documentation Status](https://readthedocs.org/projects/python-logging-discord-handler/badge/?version=latest)](https://python-logging-discord-handler.readthedocs.io/en/latest/?badge=latest)
# Python logging handler for Discord
Redirect your Python log output to Discord using [Python logging subsystem](https://docs.python.org/3/howto/logging.html) and [Discord Webhook library](https://github.com/lovvskillz/python-discord-webhook).
![Example screenshot](https://raw.githubusercontent.com/tradingstrategy-ai/python-logging-discord-handler/master/docs/source/_static/example_screenshot.png)
# Use cases
- Easily share logs with non-technical colleagues
- Get notified on server-side errors
- Follow your batch job processes easily
- Good for businesses and communities that have their messaging set up in Discord
# Features
- Minimum or no changes to a Python application needed
- Optional color coding of messages using [Discord embeds](https://discordjs.guide/popular-topics/embeds.html#embed-preview)
- Optional emoticons on messages using Unicode
- Discord rate limiting friendly for burst of logs
- [Documentation](https://python-logging-discord-handler.readthedocs.io/)
- Special handling for long log messages like tracebacks to deal with Discord's 2000 character max message length
# Requirements
- Python 3.8+
# Installation
[With pip](https://pypi.org/project/pip/):
```shell
pip install python-logging-discord-handler
```
[With Poetry](https://python-poetry.org/):
```shell
poetry add python-logging-discord-handler
```
# Usage
This example logs both to Discord and standard output.
First you need to
```python
import logging
from discord_logging.handler import DiscordHandler
# See instructions below how to get a Webhook URL
webhook_url = # ...
logger = logging.getLogger()
stream_format = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
discord_format = logging.Formatter("%(message)s")
discord_handler = DiscordHandler(
"Hello World Bot",
webhook_url,
avatar_url="https://i0.wp.com/www.theterminatorfans.com/wp-content/uploads/2012/09/the-terminator3.jpg?resize=900%2C450&ssl=1")
#discord_handler = DiscordHandler("Happy Bot", webhook_url, emojis={})
discord_handler.setFormatter(discord_format)
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(stream_format)
# Add the handlers to the Logger
logger.addHandler(discord_handler)
logger.addHandler(stream_handler)
logger.setLevel(logging.DEBUG)
logger.info("This is an info message")
logger.debug("A debug message - usually not that interesting")
logger.error("Very nasty error messgae!")
```
[Find more examples in the examples.py source code](https://github.com/tradingstrategy-ai/python-logging-discord-handler/blob/master/discord_logging/examples.py).
# How to get Discord webhook URL
1. Go to *Edit channel* (gear) in Discord
2. Choose *Integrations*
3. Choose *View webhooks* -> *New*
4. Copy URL
## Webhook URL security
It is recommend that you store the webhook URL outside your source code to avoid damage in hacks or similar security incidents.
In Linux/macOS shell you can do on the command line:
```shell
export DISCORD_TEST_WEBHOOK_URL=<your webhook URL here>
```
For long term configuration, you can create a file storing environment variables outside your source code tree, like in your home directory. Store the `export` commands there.
```shell
# Text editor for a secrets.env file in your home directory on Linux
nano ~/secrets.env
```
In your Linux shell session, you can then read this file and make environment variables effective using [source](https://superuser.com/a/46149) command in your shell:
```shell
# Reads secrets.env and executes all commands there and makes them effective
# in the current shell session
source ~/secrets.env
```
Then you can read the environment variable in your Python code:
```python
import os
webhook_url = os.environ["DISCORD_TEST_WEBHOOK_URL"]
```
# Discord limitations
- Max 2000 characters per message. See API documentation how to work around this limitation with different options. By default the bottom most lines of the log message, like a traceback, are shown.
- Discord embeds, those that give you a logging level color bar on the left, have very hard time to deal with long lines. Embeds are disabled for long lines by default.
## Log output formatting logic
The log message are converted to Discord embeds with the following logic
- Single line log messsages are converted to embed titles
- For multi line log messages, the first line is the embed title and the following lines are the embed description
- Long lines or long messages cannot be convert to embeds, instead they use [Discord Markdown code formattiong](https://support.discord.com/hc/en-us/articles/210298617-Markdown-Text-101-Chat-Formatting-Bold-Italic-Underline-) to preserve the readability of the output
- A special `message_break_char` can be assigned to manually split long messages
# Colours and emoticons
Logging messages can be decorated with colours and emoticons.
![Emoji screenshot](https://raw.githubusercontent.com/tradingstrategy-ai/python-logging-discord-handler/master/docs/source/_static/emoji_example.png)
Here are the defaults:
```python
#: The default log level colors as hexacimal, converted int
DEFAULT_COLOURS = {
None: 2040357, # Unknown log level
logging.CRITICAL: 14362664, # Red
logging.ERROR: 14362664, # Red
logging.WARNING: 16497928, # Yellow
logging.INFO: 2196944, # Blue
logging.DEBUG: 8947848, # Gray
}
#: The default log emojis as
DEFAULT_EMOJIS = {
None: "", # Unknown log level
logging.CRITICAL: "🆘",
logging.ERROR: "❌",
logging.WARNING: "⚠️",
logging.INFO: "",
logging.DEBUG: "",
}
```
Emoticons are disabled by default as they often make the output a bit too colourful and harder to read.
# Testing and development
## Manual tests
Inspect how logging output looks in Discord.
- Checkout this Git repository
- Set up a dummy Discord channel
- Get its webhook URL
```shell
poetry install -E docs
export DISCORD_TEST_WEBHOOK_URL=...
python discord_logging/examples.py
```
This will dump some messages to your Discord.
## Automated tests
Run:
```shell
pytest
```
# History
[Originally created for Trading Strategy](https://tradingstrategy.ai) to follow trading bot activity.
# License
MIT
Raw data
{
"_id": null,
"home_page": "https://tradingstrategy.ai",
"name": "python-logging-discord-handler",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.8,<4.0",
"maintainer_email": "",
"keywords": "discord,logger,logging",
"author": "Mikko Ohtamaa",
"author_email": "mikko@opensourcehacker.com",
"download_url": "https://files.pythonhosted.org/packages/a2/94/c67d7d1bd268ed3f3dd6775905ea8523ef38a6ecd599d563367e947e75fb/python_logging_discord_handler-0.1.4.tar.gz",
"platform": null,
"description": "[![PyPI version](https://badge.fury.io/py/python-logging-discord-handler.svg)](https://badge.fury.io/py/python-logging-discord-handler)\n\n[![Automated test suite](https://github.com/tradingstrategy-ai/python-logging-discord-handler/actions/workflows/tests.yml/badge.svg)](https://github.com/tradingstrategy-ai/python-logging-discord-handler/actions/workflows/tests.yml)\n\n[![Documentation Status](https://readthedocs.org/projects/python-logging-discord-handler/badge/?version=latest)](https://python-logging-discord-handler.readthedocs.io/en/latest/?badge=latest)\n\n# Python logging handler for Discord\n\nRedirect your Python log output to Discord using [Python logging subsystem](https://docs.python.org/3/howto/logging.html) and [Discord Webhook library](https://github.com/lovvskillz/python-discord-webhook).\n\n![Example screenshot](https://raw.githubusercontent.com/tradingstrategy-ai/python-logging-discord-handler/master/docs/source/_static/example_screenshot.png)\n\n# Use cases\n\n- Easily share logs with non-technical colleagues\n- Get notified on server-side errors\n- Follow your batch job processes easily\n- Good for businesses and communities that have their messaging set up in Discord \n\n# Features\n\n- Minimum or no changes to a Python application needed\n- Optional color coding of messages using [Discord embeds](https://discordjs.guide/popular-topics/embeds.html#embed-preview)\n- Optional emoticons on messages using Unicode\n- Discord rate limiting friendly for burst of logs\n- [Documentation](https://python-logging-discord-handler.readthedocs.io/)\n- Special handling for long log messages like tracebacks to deal with Discord's 2000 character max message length\n\n# Requirements\n\n- Python 3.8+\n\n# Installation \n\n[With pip](https://pypi.org/project/pip/):\n\n```shell\npip install python-logging-discord-handler\n```\n\n[With Poetry](https://python-poetry.org/):\n\n```shell\npoetry add python-logging-discord-handler\n```\n\n# Usage\n\nThis example logs both to Discord and standard output. \n\nFirst you need to \n\n```python\nimport logging\n\nfrom discord_logging.handler import DiscordHandler\n\n# See instructions below how to get a Webhook URL\nwebhook_url = # ...\nlogger = logging.getLogger()\n\nstream_format = logging.Formatter(\"%(asctime)s - %(name)s - %(levelname)s - %(message)s\")\ndiscord_format = logging.Formatter(\"%(message)s\")\n\ndiscord_handler = DiscordHandler(\n \"Hello World Bot\", \n webhook_url, \n avatar_url=\"https://i0.wp.com/www.theterminatorfans.com/wp-content/uploads/2012/09/the-terminator3.jpg?resize=900%2C450&ssl=1\")\n\n#discord_handler = DiscordHandler(\"Happy Bot\", webhook_url, emojis={})\ndiscord_handler.setFormatter(discord_format)\nstream_handler = logging.StreamHandler()\nstream_handler.setFormatter(stream_format)\n\n# Add the handlers to the Logger\nlogger.addHandler(discord_handler)\nlogger.addHandler(stream_handler)\nlogger.setLevel(logging.DEBUG)\n\nlogger.info(\"This is an info message\")\nlogger.debug(\"A debug message - usually not that interesting\")\nlogger.error(\"Very nasty error messgae!\")\n```\n\n[Find more examples in the examples.py source code](https://github.com/tradingstrategy-ai/python-logging-discord-handler/blob/master/discord_logging/examples.py).\n\n# How to get Discord webhook URL\n\n1. Go to *Edit channel* (gear) in Discord\n2. Choose *Integrations*\n3. Choose *View webhooks* -> *New*\n4. Copy URL\n\n## Webhook URL security\n\nIt is recommend that you store the webhook URL outside your source code to avoid damage in hacks or similar security incidents.\n\nIn Linux/macOS shell you can do on the command line:\n\n```shell\nexport DISCORD_TEST_WEBHOOK_URL=<your webhook URL here>\n```\n\nFor long term configuration, you can create a file storing environment variables outside your source code tree, like in your home directory. Store the `export` commands there.\n\n```shell\n# Text editor for a secrets.env file in your home directory on Linux\nnano ~/secrets.env \n```\n\nIn your Linux shell session, you can then read this file and make environment variables effective using [source](https://superuser.com/a/46149) command in your shell:\n\n```shell\n# Reads secrets.env and executes all commands there and makes them effective\n# in the current shell session\nsource ~/secrets.env\n```\n\nThen you can read the environment variable in your Python code: \n\n```python\nimport os\n\nwebhook_url = os.environ[\"DISCORD_TEST_WEBHOOK_URL\"]\n```\n\n# Discord limitations\n\n- Max 2000 characters per message. See API documentation how to work around this limitation with different options. By default the bottom most lines of the log message, like a traceback, are shown.\n- Discord embeds, those that give you a logging level color bar on the left, have very hard time to deal with long lines. Embeds are disabled for long lines by default.\n\n## Log output formatting logic\n\nThe log message are converted to Discord embeds with the following logic\n\n- Single line log messsages are converted to embed titles\n- For multi line log messages, the first line is the embed title and the following lines are the embed description\n- Long lines or long messages cannot be convert to embeds, instead they use [Discord Markdown code formattiong](https://support.discord.com/hc/en-us/articles/210298617-Markdown-Text-101-Chat-Formatting-Bold-Italic-Underline-) to preserve the readability of the output\n- A special `message_break_char` can be assigned to manually split long messages \n\n# Colours and emoticons\n\nLogging messages can be decorated with colours and emoticons.\n\n![Emoji screenshot](https://raw.githubusercontent.com/tradingstrategy-ai/python-logging-discord-handler/master/docs/source/_static/emoji_example.png)\n\n\nHere are the defaults:\n\n```python\n#: The default log level colors as hexacimal, converted int\nDEFAULT_COLOURS = {\n None: 2040357, # Unknown log level\n logging.CRITICAL: 14362664, # Red\n logging.ERROR: 14362664, # Red\n logging.WARNING: 16497928, # Yellow\n logging.INFO: 2196944, # Blue\n logging.DEBUG: 8947848, # Gray\n}\n\n\n#: The default log emojis as\nDEFAULT_EMOJIS = {\n None: \"\", # Unknown log level\n logging.CRITICAL: \"\ud83c\udd98\",\n logging.ERROR: \"\u274c\",\n logging.WARNING: \"\u26a0\ufe0f\",\n logging.INFO: \"\",\n logging.DEBUG: \"\",\n}\n```\n\nEmoticons are disabled by default as they often make the output a bit too colourful and harder to read.\n\n# Testing and development\n\n## Manual tests\n\nInspect how logging output looks in Discord.\n\n- Checkout this Git repository\n- Set up a dummy Discord channel\n- Get its webhook URL\n\n```shell\npoetry install -E docs \nexport DISCORD_TEST_WEBHOOK_URL=...\npython discord_logging/examples.py\n```\n\nThis will dump some messages to your Discord.\n\n## Automated tests\n\nRun:\n\n```shell\npytest\n```\n\n# History\n\n[Originally created for Trading Strategy](https://tradingstrategy.ai) to follow trading bot activity.\n\n# License \n\nMIT\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Discord handler for Python logging framework",
"version": "0.1.4",
"split_keywords": [
"discord",
"logger",
"logging"
],
"urls": [
{
"comment_text": "",
"digests": {
"md5": "5e0f490ccb98c5022b398458a6f2c369",
"sha256": "b804b48e3f5af8c9c781a9afe8243c806f01521662e38a60fcda2c3631d27f4f"
},
"downloads": -1,
"filename": "python_logging_discord_handler-0.1.4-py3-none-any.whl",
"has_sig": false,
"md5_digest": "5e0f490ccb98c5022b398458a6f2c369",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8,<4.0",
"size": 9499,
"upload_time": "2022-12-14T00:27:35",
"upload_time_iso_8601": "2022-12-14T00:27:35.234100Z",
"url": "https://files.pythonhosted.org/packages/d1/79/669464da149b3a3b15b4f0d17e5ebd548d44c466b644a7b610ebf4987092/python_logging_discord_handler-0.1.4-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"md5": "24af6e8c6b7229fdb3b47f03b53322c9",
"sha256": "8bfa839b6503b3b87e5851dd13bc5ff80bf2fadb496ac22c338ac10bd926f75a"
},
"downloads": -1,
"filename": "python_logging_discord_handler-0.1.4.tar.gz",
"has_sig": false,
"md5_digest": "24af6e8c6b7229fdb3b47f03b53322c9",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8,<4.0",
"size": 9470,
"upload_time": "2022-12-14T00:27:37",
"upload_time_iso_8601": "2022-12-14T00:27:37.259078Z",
"url": "https://files.pythonhosted.org/packages/a2/94/c67d7d1bd268ed3f3dd6775905ea8523ef38a6ecd599d563367e947e75fb/python_logging_discord_handler-0.1.4.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2022-12-14 00:27:37",
"github": false,
"gitlab": false,
"bitbucket": false,
"lcname": "python-logging-discord-handler"
}