init: leveled discord logger
Signed-off-by: disqualifier <dev@disqualifier.me>
This commit is contained in:
commit
48de7d7065
15
.gitignore
vendored
Normal file
15
.gitignore
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
# claude
|
||||
CLAUDE.md
|
||||
|
||||
# python
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*.egg-info/
|
||||
build/
|
||||
dist/
|
||||
.eggs/
|
||||
|
||||
# env
|
||||
.venv/
|
||||
venv/
|
||||
.env
|
||||
101
README.md
Normal file
101
README.md
Normal file
@ -0,0 +1,101 @@
|
||||
# dpy_logger
|
||||
|
||||
Leveled Discord channel logger for discord.py. Logs to a channel via embeds at
|
||||
`debug` / `info` / `success` / `fail` / `task` / `critical` levels. Config-free:
|
||||
static identity is injected at construction; per-guild channel routing is read
|
||||
live from `bot.settings` so it can change at runtime via a command.
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
# requirements.txt
|
||||
dpy_logger @ git+ssh://git@git.rethinkstudios.io/rethink-public/dpy_logger.git@v0.1.0
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```python
|
||||
from dpy_logger import DPYLogger
|
||||
|
||||
bot.log = DPYLogger(
|
||||
bot, guild_id, channel_id,
|
||||
colors=cfg.log_colors, # optional; merged over sensible defaults
|
||||
pings=cfg.authorized_devs, # mentioned on critical()
|
||||
timezone=cfg.timezone,
|
||||
footer=cfg.bot_footer,
|
||||
avatar=cfg.bot_avatar,
|
||||
)
|
||||
await bot.log.initialize() # resolves ids -> objects, call once
|
||||
|
||||
await bot.log.info("started")
|
||||
await bot.log.success("user promoted", action="promote", actor=ctx.author)
|
||||
await bot.log.critical("db unreachable") # pings configured devs
|
||||
```
|
||||
|
||||
## Dynamic routing
|
||||
|
||||
Pass `guild=` on any call to log to that guild's configured channel
|
||||
(`bot.settings[guild.id]['channels']['logs']`) instead of the construction
|
||||
channel. Because it reads `bot.settings` at call time, a command that updates
|
||||
that setting changes routing with no restart.
|
||||
|
||||
## Construction contract
|
||||
|
||||
The host injects everything; the lib never imports `config`:
|
||||
|
||||
- `colors` (dict, optional) — per-level colors, merged over defaults
|
||||
- `pings` (list of user ids) — mentioned on `critical()`
|
||||
- `timezone`, `footer`, `avatar` — embed identity
|
||||
- `alert_here` (bool) — if no `pings` are set, `critical()` falls back to
|
||||
`@here` only when this is `True`; otherwise it sends no mention
|
||||
|
||||
It also expects `bot.settings[guild.id]['channels']['logs']` to exist for the
|
||||
dynamic-routing path. A project with a different settings shape should override
|
||||
`_get_channel`.
|
||||
|
||||
## Customizing the embed
|
||||
|
||||
Three ways, easiest first.
|
||||
|
||||
**Pass a function** — no subclass. The callable receives the logger instance
|
||||
(so it can read `self.colors`, `self.footer`, etc.) plus the call args, and
|
||||
returns a `discord.Embed`. Used for every level including `critical`:
|
||||
|
||||
```python
|
||||
def my_embed(logger, level, action, actor, details):
|
||||
em = discord.Embed(description=details, color=logger.colors[level])
|
||||
if level == "critical":
|
||||
em.set_thumbnail(url=logger.avatar)
|
||||
if actor:
|
||||
em.set_author(name=str(actor))
|
||||
return em
|
||||
|
||||
bot.log = DPYLogger(bot, guild, channel, embed_builder=my_embed)
|
||||
```
|
||||
|
||||
**Override the method** — for complex/stateful customization, subclass and
|
||||
override `build_embed(level, action, actor, details)`. Same routing: every
|
||||
level flows through it.
|
||||
|
||||
**Default** — pass neither and you get the standard fielded embed.
|
||||
|
||||
## Adding a log type
|
||||
|
||||
To add new methods (e.g. a feed), subclass and reuse `_resolve`. This base has
|
||||
no feed by design; a project that wants one adds it in its own local `libs/`:
|
||||
|
||||
```python
|
||||
class FeedLogger(DPYLogger):
|
||||
"""project-local: dpy_logger plus a feed-style announcement embed"""
|
||||
|
||||
async def feed(self, log, title, icon=None, guild=None):
|
||||
channel = await self._resolve(guild)
|
||||
embed = discord.Embed(
|
||||
description=log, color=self.colors.get("feed", self.colors["info"])
|
||||
).set_author(name=title, icon_url=icon)
|
||||
return await channel.send(embed=embed)
|
||||
```
|
||||
|
||||
## Versioning
|
||||
|
||||
Tagged `vX.Y.Z`. Pin the tag in `requirements.txt`.
|
||||
Loading…
Reference in New Issue
Block a user