Python Forum
Can I use logging in a class (without multiple messages)
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Can I use logging in a class (without multiple messages)
#1
I'm new to using classes. In the code below I'm finding with the use of
log_alt.info()
messages will appear once, as desired. However, when I use the class,
logger()
, duplicate messages appear in syslog.

This code should function on any system with syslog available.

I understand I could just use logging outside of a class and get desired results, yet I'd like to better understand why the use of a class results in the duplicate messages.

import random, datetime, time, socket, logging, logging.handlers, threading, subprocess

timer_one = 5
timer_two = 20

log_alt = logging.getLogger('logging_test')
handler = logging.handlers.SysLogHandler(address = '/dev/log')
formatter = logging.Formatter('%(name)s %(funcName)s(): %(message)s')
handler.setFormatter(formatter)
log_alt.addHandler(handler)
log_alt.setLevel(logging.INFO)

class logger:
    def __init__(self):

        self.l = logging.getLogger('logging_test')
        self.handler = logging.handlers.SysLogHandler(address = '/dev/log')
        self.formatter = logging.Formatter('%(name)s %(funcName)s(): %(message)s')
        self.handler.setFormatter(self.formatter)
        self.l.addHandler(self.handler)

        self.l.setLevel(logging.INFO)

class showme:
    def __init__(self):
      pass

    def logsomething(self):
      logger().l.info(f'logging something...')
      # log_alt.info(f'logging something here...')

class TimerThread(threading.Thread):
 def __init__(self, interval, function):
  threading.Thread.__init__(self)
  self.interval = interval
  self.function = function
  self.daemon = True

 def run(self):
  while True:
   logger().l.info(f'{str(self.function)} is sleeping for: {self.interval}')
   # log_alt.info(f'{str(self.function)} is sleeping for: {self.interval}')
   time.sleep(self.interval)
   self.function()
   if self.function == i.logsomething:
    self.interval = random.randint(7, 10)

if __name__ == '__main__':
 logger().l.info(f'Starting this thing...')
 # log_alt.info(f'Starting this thing...')
 i = showme()
 timer1 = TimerThread(timer_one, i.logsomething)
 timer1.start()

 while True:
  time.sleep(timer_two)
Reply
#2
You have two logger instances log_alt and logger().l both configured to log to the same syslog address (/dev/log).
When you log a message using log_alt and when you log a message using logger().l,
both will send messages to the syslog,resulting in duplicate log entries.

I would advise to use loguru, then get a get a much cleaner code.
See also that i added method __repr__,to avoid to log the memory address of the Showme class:
<bound method Showme.logsomething of <__main__.Showme object at 0x00000227BF57B150>> is sleeping for: 9
import random
import time
import threading
from loguru import logger
logger.add("log_info.log", level="INFO")

class Showme:
    def __init__(self):
        pass

    def logsomething(self):
        logger.info('Logging something...')

    def __repr__(self):
        return "Class Showme"

class TimerThread(threading.Thread):
    def __init__(self, interval, method):
        super().__init__()
        self.interval = interval
        self.method = method
        self.daemon = True

    def run(self):
        while True:
            logger.info(f'{self.method} is sleeping for: {self.interval}')
            time.sleep(self.interval)
            self.method()
            if self.method == show.logsomething:
                self.interval = random.randint(7, 10)

if __name__ == '__main__':
    timer_one = 5
    timer_two = 20
    logger.info('Starting this thing...')
    show = Showme()
    timer1 = TimerThread(timer_one, show.logsomething)
    timer1.start()
    while True:
        time.sleep(timer_two)
Output:
2023-10-15 01:47:58.799 | INFO | __main__:<module>:35 - Starting this thing... 2023-10-15 01:47:58.805 | INFO | __main__:run:26 - <bound method Showme.logsomething of Class Showme> is sleeping for: 5 2023-10-15 01:48:03.809 | INFO | __main__:logsomething:12 - Logging something... 2023-10-15 01:48:03.813 | INFO | __main__:run:26 - <bound method Showme.logsomething of Class Showme> is sleeping for: 9 2023-10-15 01:48:12.816 | INFO | __main__:logsomething:12 - Logging something... 2023-10-15 01:48:12.820 | INFO | __main__:run:26 - <bound method Showme.logsomething of Class Showme> is sleeping for: 8 2023-10-15 01:48:20.823 | INFO | __main__:logsomething:12 - Logging something... 2023-10-15 01:48:20.827 | INFO | __main__:run:26 - <bound method Showme.logsomething of Class Showme> is sleeping for: 9
Reply
#3
Thanks for the tip! I will check out loguru!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  How to append multiple <class 'str'> into a single List ahmedwaqas92 2 2,355 Jan-07-2021, 08:17 AM
Last Post: ahmedwaqas92
  How to left align logging messages Mekala 3 6,885 Jun-28-2020, 04:04 PM
Last Post: bowlofred
  Pythonic way to handle/spread alerts class in multiple modules psolar 11 4,633 Feb-12-2020, 04:11 PM
Last Post: psolar
  I carnt see publish/subscribe messages from the class I created. sdf1444 0 1,354 Jul-10-2019, 02:21 PM
Last Post: sdf1444
  logging messages ahead of print messages vindo 6 3,214 Jun-18-2019, 02:45 PM
Last Post: vindo
  Giving class multiple arguments AndyArsalan 1 4,568 Oct-04-2018, 11:25 PM
Last Post: ODIS
  calling a class multiple times GOB 2 4,297 Feb-02-2018, 05:10 AM
Last Post: GOB
  Multiple classes in another class Dargonoth 3 3,383 Sep-08-2017, 12:29 PM
Last Post: Dargonoth
  how to make class and instance method (multiple decorator) ? harun2525 7 6,059 May-29-2017, 04:56 PM
Last Post: harun2525
  Class method returning multiple values,dont know which is returned when.. ujjwalrathod007 4 12,877 Oct-03-2016, 08:29 PM
Last Post: ujjwalrathod007

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020