Here is how I capture image with my camera
import logging
import gphoto2 as gp
def main():
def callback(level, domain, string, data=None):
print('Callback: level =', level, ', domain =', domain, ', string =', string)
if data:
print('Callback data:', data)
logging.basicConfig(
format='%(levelname)s: %(name)s: %(message)s', level=logging.WARNING)
callback_obj = gp.check_result(gp.use_python_logging())
camera = gp.Camera()
camera.init()
try:
camera_file_path = gp.check_result(camera.capture(gp.GP_CAPTURE_IMAGE))
except gp.GPhoto2Error as ex:
print("callback: ", ex, ex.code, ex.message, ex.string)
camera.exit()
if __name__ == "__main__" : exit(main())
If the camera is not able to focus it generates following error
...
WARNING: gphoto2: (ptp_usb_getresp [usb.c:466]) PTP_OC 0x90c8 receiving resp failed: Out of Focus (0xa002)
WARNING: gphoto2: (camera_nikon_capture [library.c:3153]) 'ret' failed: 'Out of Focus' (0xa002)
WARNING: gphoto2: (gp_context_error) Out of Focus
WARNING: gphoto2: (gp_camera_capture [gphoto2-camera.c:1340]) 'camera->functions->capture (camera, type, path, context)' failed: -1
('callback: ', GPhoto2Error('[-1] Unspecified error',), -1, '[-1] Unspecified error', 'Unspecified error')
The exception error code is -1 but how can I capture Out of Focus warning?
UPDATE
Filtered out unnecessary errors from logs
import logging
import gphoto2 as gp
from datetime import datetime
def main():
def callback(level, domain, string, data=None):
err_codes = ("(0x2005)", "(0x2019)")
if not string.decode().endswith(err_codes):
print("[{0}] {1}: {2}".format(datetime.utcnow(), domain.decode(), string.decode()))
if data:
print('Callback data:', data)
callback_obj = gp.check_result(gp.gp_log_add_func(gp.GP_LOG_ERROR, callback))
camera = gp.Camera()
try:
camera.init()
except gp.GPhoto2Error as err:
exit(err.code)
try:
camera_file_path = camera.capture(gp.GP_CAPTURE_IMAGE)
except gp.GPhoto2Error as err:
exit(err.code)
camera.exit()
if __name__ == "__main__" : exit(main())
You've defined a callback function, in which you could parse the error string to detect out of focus, but you haven't installed your callback so libgphoto2 isn't using it. Use gp_log_add_func to install your callback.
Also, you're passing the return value of camera.capture to gp.check_result. This is incorrect as camera.capture already checks the result and raises an exception if there's an error.
If you can figure out the name of the logger, you can add your own handler to it and do your own log processing.
Calling "getLogger" with your camera library's name would get you the logger.
Calling AddHandler on that logger with a custom handler would allow you to do your own log processing for logs coming from that logger.
Please see Python's Logging Cookbook for more info
Hope this helps
Related
Why isn't this code creating a log file? It used to work... I ran it from command line and debugger vscode...
I have logged at info and error level and still nothing.
Seems like an empty file should at least be created.. .but then again, maybe python does a lazy create.
import logging
import argparse
import datetime
import sys
import platform
def main():
print("something")
logging.error("something")
if(__name__ == '__main__'):
the_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
msg = "Start time: {}".format(the_time)
print(msg)
logging.info(msg)
parser = argparse.ArgumentParser(prog='validation')
parser.add_argument("-L", "--log", help="log level", required=False, default='INFO')
args = parser.parse_args()
numeric_level = getattr(logging, args.log.upper(), None)
print(numeric_level)
if not isinstance(numeric_level, int):
raise ValueError('Invalid log level: %s' % args.log.upper())
print("setting log level to: {} for log file validate.log".format(args.log.upper()))
logging.basicConfig(filename='validate.log', level=numeric_level, format='%(asctime)s %(levelname)-8s %(message)s', datefmt='%d-%b-%Y %H:%M:%S')
logging.info("Python version: {}".format(sys.version))
main()
The documentation of the function logging.basicConfig() says:
This function does nothing if the root logger already has handlers configured, unless the keyword argument force is set to True.
Now, does your root logger has handlers? Initially, no. However, when you call any of the log functions (debug, info, error, etc.), it creates a default handler. Therefore, calling basicConfig after these functions does nothing.
Running this program
print(logging.getLogger().hasHandlers())
logging.error('test message')
print(logging.getLogger().hasHandlers())
produces:
$ python3 test.py
False
ERROR:root:test message
True
To fix your issue, just add force=True as an argument for basicConfig.
What have I missed?
I have a project with lots of files and modules. I want each module, and some classes, to have their own log file. For the most part I want just INFO and ERROR logged, but occasionally I'll want DEBUG.
However, I only want ERROR sent to the screen (iPython on Spyder via Anaconda). This is high speed code getting network updates several times each millisecond and printing all the INFO messages is not only very annoying but crashes Spyder.
In short, I want only ERROR sent to the screen. Everything else goes to a file. Below is my code for creating a separate log file for each class. It is called in the __init__ method of each class that should log items. The name argument is typically __class__.__name__. The fname argument is set as well. Typically, the lvl and formatter args are left with the defaults. The files are being created and they look more or less correct.
My searches are not turning up useful items and I'm missing something when I read the Logging Cookbook.
Code:
import logging, traceback
import time, datetime
import collections
standard_formatter = logging.Formatter('[{}|%(levelname)s]::%(funcName)s-%(message)s\n'.format(datetime.datetime.utcnow()))
standard_formatter.converter = time.gmtime
logging.basicConfig(level=logging.ERROR,
filemode='w')
err_handler = logging.StreamHandler()
err_handler.setLevel(logging.ERROR)
err_handler.setFormatter(standard_formatter)
Log = collections.namedtuple(
'LogLvls',
[
'info',
'debug',
'error',
'exception'
]
)
def setup_logger(
name: str,
fname: [str, None]=None,
lvl=logging.INFO,
formatter: logging.Formatter=standard_formatter
) -> Log:
logger = logging.getLogger(name)
if fname is None:
handler = logging.StreamHandler()
else:
handler = logging.FileHandler(fname, mode='a')
handler.setFormatter(formatter)
logger.setLevel(lvl)
logger.addHandler(handler)
logger.addHandler(err_handler)
return Log(
debug=lambda msg: logger.debug('{}::{}'.format(name, msg)),
info=lambda msg: logger.info('{}::{}'.format(name, msg)),
error=lambda msg: logger.error('{}::{}'.format(name, msg)),
exception=lambda e: logger.error('{}::{}: {}\n{}'.format(name, type(e), e, repr(traceback.format_stack()))),
)
You cannot have
logging.basicConfig(level=logging.ERROR,
filemode='w')
and specialized config same time. Comment it out or remove, then using
if __name__ == '__main__':
setup_logger('spam', "/tmp/spaaam")
logging.getLogger('spam').info('eggs')
logging.getLogger('spam').error('eggs')
logging.getLogger('spam').info('eggs')
You'll have only ERROR level messages on console, and both in file.
Trying to run robot code in python.
When running the following code, on the output console I get 'No handlers could be found for logger "RobotFramework"'
How do I log/print to console the raise AssertionError from another module?
Or log all logs sent to logger "RobotFramework"
from ExtendedSelenium2Library import ExtendedSelenium2Library
from robot.api import logger
class firsttest():
def googleit(self):
self.use_url = 'https://google.ca'
self.use_browser = 'chrome'
s2l = ExtendedSelenium2Library()
s2l.open_browser(self.use_url, self.use_browser)
s2l.maximize_browser_window()
try:
s2l.page_should_contain('this text does not exist on page')
except:
logger.console('failed')
runit = firsttest()
runit.googleit()
Get following console output:
failed
No handlers could be found for logger "RobotFramework"
I am using Python's https://github.com/pulseenergy/airbrakepy Which is a synonym to Ruby's Airbrake gem. Now, i have installed https://github.com/errbit/errbit at my end. Now, i want to send all error notices to errbit.
I have something similar to,
import logging
import ConfigParser
import os
import time
from airbrakepy.logging.handlers import AirbrakeHandler
def method_three():
raise StandardError('bam, pow')
def method_two():
method_three()
def method_one():
method_two()
if __name__=='__main__':
configFilePath = os.path.join(os.path.expanduser("~"), ".airbrakepy")
print(configFilePath)
parser = ConfigParser.SafeConfigParser()
parser.read(configFilePath)
api_key = parser.get("airbrake", "api_key")
url = parser.get("airbrake", "app_url")
logging.basicConfig(level=logging.ERROR)
logger = logging.getLogger("test-logger")
handler = AirbrakeHandler(api_key, environment='dev', component_name='integration-test', node_name='server', airbrake_url=url, use_ssl=False, timeout_in_ms=10000000)
logger.addHandler(handler)
logger.error("before exception")
try:
method_one()
except StandardError:
logger.error("test with exception", exc_info=True)
logger.error("test without exception", exc_info=False)
logger.error("after exception")
logging.shutdown()
I also have .airbrakepy which has api_key and errbit_url.
Anybody knows where am i making mistake.
I am not able to send notices to errbit through this method.
Please use https://github.com/aashish-pathak/airbrakepy
There is some issue with airbrakepy. I'll soon send pull request to main airbrakepy repo.
I want to check for errors in a particular background file, but the standard error stream is being controlled by the program in the foreground and the errors in the file in the question are not being displayed. I can use the logging module and write output to a file, though. I was wondering how I can use this to log all exceptions, errors and their tracebacks.
It's probably a bad idea to log any exception thrown within the program, since Python uses exceptions also for normal control flow.
Therefore you should only log uncaught exceptions. You can easily do this using a logger's exception() method, once you have an exception object.
To handle all uncaught exceptions, you can either wrap your script's entry point in a try...except block, or by installing a custom exception handler by re-assigning sys.excepthook():
import logging
import sys
logger = logging.getLogger('mylogger')
# Configure logger to write to a file...
def my_handler(type, value, tb):
logger.exception("Uncaught exception: {0}".format(str(value)))
# Install exception handler
sys.excepthook = my_handler
# Run your main script here:
if __name__ == '__main__':
main()
import sys
import logging
import traceback
# log uncaught exceptions
def log_exceptions(type, value, tb):
for line in traceback.TracebackException(type, value, tb).format(chain=True):
logging.exception(line)
logging.exception(value)
sys.__excepthook__(type, value, tb) # calls default excepthook
sys.excepthook = log_exceptions
Inspired of the main answer + How to write to a file, using the logging Python module? + Print original exception in excepthook, here is how to write the full traceback into a file test.log, like it would be printed in the console:
import logging, sys, traceback
logger = logging.getLogger('logger')
fh = logging.FileHandler('test.log')
logger.addHandler(fh)
def exc_handler(exctype, value, tb):
logger.exception(''.join(traceback.format_exception(exctype, value, tb)))
sys.excepthook = exc_handler
print("hello")
1/0