NameError: global name 'logger' is not defined
Asked Answered
T

4

14

I wrote a logging.json file from where the logging configuration is setup after which i created a class in which all my methods will be there but for logging when i use logger inside the class it is throwing error NameError: global name 'logger' is not defined

app.py

#/usr/bin/python

import sys
import logging
import time
import json
import os
import logging.config

def setup_logging(default_path='logging.json',default_level=logging.INFO,env_key='LOG_CFG'):
    """Setup logging configuration"""
    path = default_path
    value = os.getenv(env_key, None)
    if value:
        path = value
    if os.path.exists(path):
        with open(path, 'rt') as f:
            config = json.load(f)
        logging.config.dictConfig(config)
    else:
        logging.basicConfig(level=default_level)

class Generic:

        def __init__(self , file_path):
                self.file_path = file_path

        def check_mime(self):
                logger.info('Generic on file {} starts at {}'.format(file_path , time.time()))


print 'File path is {}'.format(sys.argv[1])
file_path = sys.argv[1]

def parser():
        parser = Generic(file_path)
        parser.check_mime()
def main():
        print 'This is intended for module purpose only'
        setup_logging()
        parser()

if __name__ == '__main__':
        main()

logging.json

{
    "version": 1,
    "disable_existing_loggers": false,
    "formatters": {
        "simple": {
            "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
        }
    },

    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "level": "DEBUG",
            "formatter": "simple",
            "stream": "ext://sys.stdout"
        },

        "info_file_handler": {
            "class": "logging.handlers.RotatingFileHandler",
            "level": "INFO",
            "formatter": "simple",
            "filename": "logs/gp.log",
            "maxBytes": 10485760,
            "backupCount": 20,
            "encoding": "utf8"
        },

        "error_file_handler": {
            "class": "logging.handlers.RotatingFileHandler",
            "level": "ERROR",
            "formatter": "simple",
            "filename": "logs/errors.log",
            "maxBytes": 10485760,
            "backupCount": 20,
            "encoding": "utf8"
        }
    },

    "loggers": {
        "my_module": {
            "level": "ERROR",
            "handlers": ["console"],
            "propagate": "no"
        }
    },

    "root": {
        "level": "INFO",
        "handlers": ["console", "info_file_handler", "error_file_handler"]
    }
}

Problem :

When i run the program error

$ python app.py /home/default/domain.txt
File path is /home/default/domain.txt
This is intended for module purpose only
Traceback (most recent call last):
  File "app.py", line 44, in <module>
    main()
  File "app.py", line 41, in main
    parser()
  File "app.py", line 37, in parser
    parser.check_mime()
  File "app.py", line 29, in check_mime
    logger.info('GenericParser
NameError: global name 'logger' is not defined

Iam using the logging example following in this link [ https://fangpenlin.com/posts/2012/08/26/good-logging-practice-in-python/ ]

Any suggestions on how to solve this as logger is not global, any way to make it global.?

Tut answered 5/9, 2017 at 15:1 Comment(2)
No need to make it global. Put logger = logging.getLogger(__name__) at the top of every module that uses logging.Callan
Also each log info is printing to stdout? Any fix?Tut
A
27

The example you link to has:

import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__) #<<<<<<<<<<<<<<<<<<<<

you missed the logger definition.

You can either put a self.logger = logging.getLogger(__name__) in your Generic.__init__() function, or define a global logger right after the import as in the example.

Admiralty answered 5/9, 2017 at 15:3 Comment(5)
No need for global here, since you don't reassign logger within the method.Fluoridation
Good point. I'm always rather unsure when to use the global keyword and when to leave it out, although in this case I think it's beneficial in making it clear where that logger comes fromAdmiralty
creat_app factory pattern how to set global logger ?British
If I define logger=logging.getLogger(__name__) in my __init__.py, would I use logger or logging in subsequent calls?Distraint
logger is your variable, so you should use that one.Admiralty
N
9

This below should be added to your code

logger=None
def setup():
   logger.debug('put some text')
   return 0

def main():
   global logger
   logger = logging.getLogger('give_some_logger_name')
   logger.setLevel(logging.DEBUG)

   ret = setup()
Nix answered 5/9, 2017 at 15:8 Comment(0)
M
2

In your class you are using logger but you have not defined it. Either set logger like:

    logger = logging.getLogger(__name__)

or use logging instead:

    logging.info('Generic on file {} starts at {}'.format(file_path , time.time()))
Meatiness answered 5/9, 2017 at 15:53 Comment(0)
L
0

I had to delete the .venv (virtual environment) file of my python project and create a new .venv by running command virtualenv .venv to fix the problem.

Litt answered 24/3 at 11:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.