0

I am trying to write custom handler for logging that would send logs to netcat

I can see on the receiving end that the connection is established and then closes, however, no messages are received and i can see no errors.

here is the code i am running

import socket
import time
import logging


hostname = '127.0.0.1'
port = '1234'
message = 'hello world!\n'

class Nc_handler(logging.Handler):
    def __init__(self, hostname, port):
        logging.Handler.__init__(self)
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.connect((hostname, int(port)))

    def emit(self, content):
        log_entry = self.format(content)
        print("Checking if emit is run")
        self.socket.send(log_entry.encode())




logger = logging.getLogger(__name__)

# set format
nc_format = logging.Formatter('%(name)s - %(levelname)s - %(message)s')

# create nc handler
nc_handler = Nc_handler(hostname, port)

# set handler's level
nc_handler.setLevel(logging.INFO)

# set handler's format
nc_handler.setFormatter(nc_format)

logger.addHandler(nc_handler)
logger.info(message)

If i use nc_handler.emit('Hello') it throws an error:

  File "handler.py", line 35, in <module>
    nc_handler.emit(message)
  File "handler.py", line 17, in emit
    log_entry = self.format(content)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/logging/__init__.py", line 869, in format
    return fmt.format(record)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/logging/__init__.py", line 608, in format
    record.message = record.getMessage()
AttributeError: 'str' object has no attribute 'getMessage'

So i suspect i don't use Formatter correctly but I can't figure out what exactly I am doing wrong.

I would really appreciate any help or advice.

1 Answer 1

1

Method emit has a wrong signature: its argument must be a LogRecord object. Not a string.

That is because format method needs a LogRecord object.

That is the cause of the AttributeError exception.

I see also a confusion I don't understand: why using message as argument for logging.info?

message is an attribute of the LogRecord object too and is taken from what you logged explicitly.

Use a hard-coded string:

logging.info("Hello")

Or use a different variable:

myvar = "Hello"
logging.info(myvar)

Does it help?

Sign up to request clarification or add additional context in comments.

3 Comments

Sorry: didn't see the global variable message at the beginning of your script. Forget my second remark.
Thanks a lot. Yes, after I changed it def emit(self, record): everything worked!
Although, it only works when I use basicConfig. Doesn't work with logging.Formatter

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.