Format = logging.Formatter("%(asctime)s %(message)s")
fileName = 'invokeRestApi.log'
fileMode = 'a'
log = logging.getLogger('simple_example')
fileHandler = logging.FileHandler(fileName, 'a')
fileHandler.setLevel(logging.DEBUG)
fileHandler.setFormatter(Format)
consoleHandler = logging.StreamHandler()
consoleHandler.setLevel(logging.DEBUG)
consoleHandler.setFormatter(Format)
log.addHandler(consoleHandler)
log.addHandler(fileHandler)
log.info("Hello)
When executing the code, nothing is written to the file. If I do log.error then the message is going to the file.
You need to set the level of your logger as well.
log.setLevel(logging.DEBUG)
Related
I want to disable my script to print the INFO, DEBUG, WARNING or ERROR from logging commands and just have this inside the .log or .err. Here is the configuration I have:
def log(routine_name):
""" Logging configuration """
logger = logging.getLogger(_name_)
logger.setLevel(logging.INFO)
logging.StreamHandler(stream=None)
formatter = logging.Formatter("%(asctime)s:%(levelname)s:%(name)s:%(message)s")
file_handler = logging.FileHandler(routine_name)
file_handler.setFormatter(formatter)
error_handler = logging.FileHandler(routine_name.replace("log", "err"))
error_handler.setFormatter(formatter)
error_handler.setLevel(logging.ERROR)
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(formatter)
logger.addHandler(file_handler)
logger.addHandler(stream_handler)
logger.addHandler(error_handler)
return logger
I have tried to set logger.propagate = False from this post but didn't work, it still printing everything.
Thanks
For me this did work with module.submodule issuing the logging commands
logger = logging.getLogger("module.submodule")
fh = logging.FileHandler("logfile")
fh.setLevel(logging.DEBUG)
logger.addHandler(fh)
logger.disabled = True
I need to log data to file and also to console. I setup it like this:
# set up logging
logging.basicConfig(level = logging.INFO,
format ='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
datefmt ='%Y-%m-%d %H:%M:%S',
handlers=[logging.FileHandler(dir + '/log.log'), logging.StreamHandler()]
)
Then i add data like this: logging.info('Server started'). In console i see the text, but file is empty. If I delete tgis file python creates new one, but still it is empty.
Its just a case of setting of multiple handlers for the same error level.
Remove basicConfig line and do something similar to below
See this example of how to do this:
import logging
log_formatter = logging.Formatter('%(asctime)s %(levelname)s %(funcName)s(%(lineno)d) %(message)s',
datefmt='%d/%m/%Y %H:%M:%S')
#File to log to
logFile = 'C:\\Temp\\log'
#Setup File handler
file_handler = logging.FileHandler(logFile)
file_handler.setFormatter(log_formatter)
file_handler.setLevel(logging.INFO)
#Setup Stream Handler (i.e. console)
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(log_formatter)
stream_handler.setLevel(logging.INFO)
#Get our logger
app_log = logging.getLogger('root')
app_log.setLevel(logging.INFO)
#Add both Handlers
app_log.addHandler(file_handler)
app_log.addHandler(stream_handler)
#Write some Data
while True:
app_log.info("data")
I am already using a basic logging config where all messages across all modules are stored in a single file. However, I need a more complex solution now:
Two files: the first remains the same.
The second file should have some custom format.
I have been reading the docs for the module, bu they are very complex for me at the moment. Loggers, handlers...
So, in short:
How to log to two files in Python 3, ie:
import logging
# ...
logging.file1.info('Write this to file 1')
logging.file2.info('Write this to file 2')
You can do something like this:
import logging
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
def setup_logger(name, log_file, level=logging.INFO):
"""To setup as many loggers as you want"""
handler = logging.FileHandler(log_file)
handler.setFormatter(formatter)
logger = logging.getLogger(name)
logger.setLevel(level)
logger.addHandler(handler)
return logger
# first file logger
logger = setup_logger('first_logger', 'first_logfile.log')
logger.info('This is just info message')
# second file logger
super_logger = setup_logger('second_logger', 'second_logfile.log')
super_logger.error('This is an error message')
def another_method():
# using logger defined above also works here
logger.info('Inside method')
def setup_logger(logger_name, log_file, level=logging.INFO):
l = logging.getLogger(logger_name)
formatter = logging.Formatter('%(message)s')
fileHandler = logging.FileHandler(log_file, mode='w')
fileHandler.setFormatter(formatter)
streamHandler = logging.StreamHandler()
streamHandler.setFormatter(formatter)
l.setLevel(level)
l.addHandler(fileHandler)
l.addHandler(streamHandler)
setup_logger('log1', txtName+"txt")
setup_logger('log2', txtName+"small.txt")
logger_1 = logging.getLogger('log1')
logger_2 = logging.getLogger('log2')
logger_1.info('111messasage 1')
logger_2.info('222ersaror foo')
If I get the logger with a name and add a FileHandler it does not write to the file.
This works and writes correctly to the file:
log = logging.getLogger()
fh = logging.FileHandler(logfile)
log.addHandler(fh)
fh_fmt = logging.Formatter("%(asctime)s (%(levelname)s)\t: %(message)s")
fh.setFormatter(fh_fmt)
log.setLevel(logging.INFO)
This does not write to the file:
log = logging.getLogger(name)
fh = logging.FileHandler(logfile)
log.addHandler(fh)
fh_fmt = logging.Formatter("%(asctime)s (%(levelname)s)\t: %(message)s")
fh.setFormatter(fh_fmt)
log.setLevel(logging.INFO)
The only difference is that I get a 'named' logger.
This is a rather old question, but I believe I found the underlying problem and solution, at least with a newer version of Python.
The second code example starts with log = logging.getLogger(name), where name is presumed to be a string representing the name of the logger. Since a name is provided, this log will not be the root logger. According to Logger.setLevel(level) docs for Python 3.6+,
When a logger is created, the level is set to NOTSET (which causes all messages to be processed when the logger is the root logger, or delegation to the parent when the logger is a non-root logger).
This tells us that we have to set the level of our logger so that it will actually process the messages instead of passing it to the root logger.
This is a code example I wrote (in Python 3.7) that does not work:
from pathlib import Path
import logging
formatter = logging.Formatter('%(name)s [%(levelname)s] %(message)s')
log_file_dir = Path('./log/')
config_file = 'config_file.txt'
config_file_path = log_file_dir / config_file
logger = logging.getLogger('example_logger')
fh = logging.FileHandler(config_file_path, mode='w')
fh.setLevel(logging.INFO)
fh.setFormatter(formatter)
logger.addHandler(fh)
logger.info('Start Configuration Log')
And this one works by adding one line:
from pathlib import Path
import logging
formatter = logging.Formatter('%(name)s [%(levelname)s] %(message)s')
log_file_dir = Path('./log/')
config_file = 'config_file_2.txt'
config_file_path = log_file_dir / config_file
logger = logging.getLogger('example_logger')
logger.setLevel(logging.INFO) # <------ Or the applicable level for your use-case
fh = logging.FileHandler(config_file_path, mode='w')
fh.setLevel(logging.INFO)
fh.setFormatter(formatter)
logger.addHandler(fh)
logger.info('Start Configuration Log')
Note: The first code example does create the chosen log file, but does not write 'Start Configuration Log' to the file.
I'm using the following code to initialize logging in my application:
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
# log to a file
directory = '/reserved/DYPE/logfiles'
now = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = os.path.join(directory, 'dype_%s.log' % now)
file_handler = logging.FileHandler(filename)
file_handler.setLevel(logging.DEBUG)
formatter = logging.Formatter("%(asctime)s %(filename)s, %(lineno)d, %(funcName)s: %(message)s")
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
# log to the console
console_handler = logging.StreamHandler()
level = logging.INFO
console_handler.setLevel(level)
logger.addHandler(console_handler)
logging.debug('logging initialized')
How can I close the current logging file and restart logging to a new file?
Note: I don't want to use RotatingFileHandler, because I want full control over all the filenames.
You can manually re-assign the handler if you want using the removeHandler and addHandler OR, you can access logger.handlers[index_of_handler_here].stream and replace the stream manually, but I'd recommend the former over the latter.
logger.handlers[0].stream.close()
logger.removeHandler(logger.handlers[0])
file_handler = logging.FileHandler(filename)
file_handler.setLevel(logging.DEBUG)
formatter = logging.Formatter("%(asctime)s %(filename)s, %(lineno)d, %(funcName)s: %(message)s")
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
Here is what I do:
def initLogging(filename):
global logger
if logger == None:
logger = logging.getLogger()
else: # wish there was a logger.close()
for handler in logger.handlers[:]: # make a copy of the list
logger.removeHandler(handler)
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter(fmt='%(asctime)s: %(message)s', datefmt='%I:%M:%S')
fh = logging.FileHandler(filename)
fh.setFormatter(formatter)
logger.addHandler(fh)
sh = logging.StreamHandler(sys.stdout)
sh.setFormatter(formatter)
logger.addHandler(sh)