twfx
twfx

Reputation: 1694

webpy logging to separate log files

I am using webpy to host a simple web service with 2 sub-services. I would like to log information of each sub-service into different log file using python logging package. The below shows test_logging.py (the main function that runs webpy), and test_classC.py (the function that does back-end service).

# test_logging.py

import web
from test_classC import classC

urls = (
    '/nw1', 'nw1',
    '/nw2', 'nw2',
)

class nw1:
    cc = classC('subtype1')

    def POST(self):
        self.cc.logsomething()

class nw2:
    cc = classC('subtype2')

    def POST(self):
        self.cc.logsomething()

if __name__ == "__main__":
    app = web.application(urls, globals())
    app.run()

# test_classC.py

import logging

class classC:

    def __init__(self, subtype):
        self.nw_type = subtype
        logfile = subtype + '.log'

        self._log = logging.getLogger()
        self._log.setLevel(logging.INFO)
        handler = logging.FileHandler(logfile)
        self._log.addHandler(handler)


    def logsomething(self):
        self._log.info("This is network type: %s" %self.nw_type)

Apparently I didnt write the logging correctly. When I test with the following web command using curl...

$ curl localhost:8081/nw1 --data-binary "hello"
$ curl localhost:8081/nw2 --data-binary "hello"

I get the same logging information in subtype1.log and subtype2.log. The first curl command generates the first two lines, and the second curl command generates the third and fourth lines.

This is network type: subtype1
This is network type: subtype1
This is network type: subtype2
This is network type: subtype2

How can I log the information such that

I get the following in subtype1.log following the first curl command

This is network type: subtype1

and I get the following in subtype2.log following the second curl command

This is network type: subtype2

[This is optional, but I'm curious] Also, since this is a web service, how can I make sure the information is properly logged when two users access the same web service in parallel. Eg. send the following command in parallel

$ curl localhost:8081/nw1 --data-binary "request_a_very_heavy_load_serv"
$ curl localhost:8081/nw1 --data-binary "request_a_very_heavy_load_serv"

Upvotes: 2

Views: 445

Answers (1)

Marlon Abeykoon
Marlon Abeykoon

Reputation: 12465

There are two issues in your code.

You said,

I get the same logging information in subtype1.log and subtype2.log

The reason is you need to create two separate, completely different logging objects. You can do it with logging.getLogger() by passing the name you want.

In your case it should be self._log = logging.getLogger(self.logfile)

  1. The logs get duplicated when you call them multiple times. (You have not noticed it but that issue is there in your code.)

The reason is logging.getLogger() is a singleton. So every time you create an instance of Class C it adds another handler to the instance which causes the duplication of logs. So I have checked if not len(self._log.handlers): before adding the handler.

So your final test_classC.py is as follows,

# test_classC.py
import logging

class classC:

    def __init__(self, subtype):

        self.nw_type = subtype
        self.logfile = subtype + '.log'
        self._log = logging.getLogger(self.logfile)
        if not len(self._log.handlers):
            self._log.setLevel(logging.INFO)
            self.handler = logging.FileHandler(self.logfile)
            self._log.addHandler(self.handler)

    def logsomething(self):
        self._log.info("This is network type: %s" %self.nw_type)

To test the parallel requests you can use jmeter

Upvotes: 1

Related Questions