Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Send log messages with async function #119

Closed
wpmjones opened this issue Jul 24, 2019 · 5 comments
Closed

Send log messages with async function #119

wpmjones opened this issue Jul 24, 2019 · 5 comments
Labels
question Further information is requested

Comments

@wpmjones
Copy link

I am writing a bot for Discord and using the discord.py library which is async. I want to send some log messages to Discord using the bot.

Essentially, all of the bot activity happens inside a class. I am having a lot of trouble figuring out where to put the logger.add and whether the sink function should be inside the class or outside the class. If it's outside, then the bot can't be accessed from the function (critical to send the message). If it's inside, then I don't know where to put logger.add.

Here is where I am at the moment, but I get errors that Push.send_log was never awaited.

from discord.ext import commands, tasks
from config import settings
from loguru import logger

class Push(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.test_loop.start()
        logger.add(self.send_log, level="WARNING")

    def cog_unload(self):
        self.test_loop.cancel()

    @tasks.loop(seconds=15)
    async def test_loop(self):
        print("success")
        self.logger.warning("Yes!")

    async def send_log(self, message):
        await self.bot.get_channel(settings['pushChannels']['pushLog']).send(message)

def setup(bot):
    bot.add_cog(Push(bot))

Any help would be appreciated.

@Delgan
Copy link
Owner

Delgan commented Jul 24, 2019

Hi @wpmjones. 🙂

I don't know very well async programming in Python. While providing a function to logger.add(func), Loguru will try to call it as a basic normal function: func(). I suppose async functions are not callable this way, hence the "Push.send_log was never awaited" error. Is there a way to wrap the send_log() async method in a normal one?

Also, I never developed any Discord bot. Is it possible for you to give me a minimal example where I could just replace token / server / channel and start debugging this, please?

@wpmjones
Copy link
Author

wpmjones commented Jul 24, 2019

Actually, with the help of a few friends, I got it working.

import asyncio
from discord.ext import commands
from loguru import logger
from config import settings


class LogTest(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        logger.add(self.send_log)

    @commands.command(name="log_test")
    async def log_test(self, ctx):
        logger.info("Logging is working")

    def send_log(self, message):
        print("inside send_log")
        asyncio.ensure_future(self.send_message(message))

    async def send_message(self, message):
        print("inside send_message")
        record = message.record
        await self.bot.get_channel(settings['logChannels']['push']).send(record)


def setup(bot):
    bot.add_cog(LogTest(bot))

Essentially, loguru calls the regular function which then uses asyncio to call the async function. It's an extra step, but it works. Now I just have to work on formatting so that it's a gorgeous as it is in the console! :)

@Delgan
Copy link
Owner

Delgan commented Jul 26, 2019

Ok, I'm not so sure on why and how it works, but if you say so, great then. 😁

Also to answer you initial question, I usually call logger.add() outside of any class, actually near to the entry point to my program where the configuration generally occurs. I guess it will works fine as you did, but be careful with multi-instantiation of LogTest() objects (logs sent from the first one may also appear in the channel of the second one). 😉

@Delgan Delgan added the question Further information is requested label Jul 28, 2019
@t-mart
Copy link
Contributor

t-mart commented Nov 21, 2019

--Moved to separate issue--

@Delgan Delgan mentioned this issue Nov 22, 2019
@Delgan
Copy link
Owner

Delgan commented Dec 1, 2019

Using Loguru v0.4.0, using the send_log() asynchronous method as a sink should work out-of-the-box. 👍

Make sure to await complete() before leaving the event loop.

@Delgan Delgan closed this as completed Dec 1, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants