-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Logging updates #254
Logging updates #254
Conversation
* Replace PanLogger with custom `LogRecord` class * Allow logger to use either `%` or `{}` (str.format) style for actual log messages. * Log messages show correct file/lineno * Reorder log.yaml Fixes panoptes#253
Codecov Report
@@ Coverage Diff @@
## develop #254 +/- ##
===========================================
- Coverage 79.36% 79.34% -0.03%
===========================================
Files 46 46
Lines 3238 3229 -9
Branches 425 424 -1
===========================================
- Hits 2570 2562 -8
+ Misses 521 520 -1
Partials 147 147
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks so much. A few nits, but otherwise LGTM.
handlers: [error] | ||
propagate: true | ||
|
||
style: '{' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, I'd like to experiment (myself) with having separate loggers for each process, which would shorten the length of the lines. In addition, I'd like to examine the possibility of logging the thread id (a number) rather than the potentially very long thread name. Basically, I'd like to get the length of the fixed portion down so that we'd have something like:
E1217 01:23:45.679 02420 messaging.py:123
The first char is a level indicator, e.g. first letter of Fatal, Critical, Error, Warning, Info, Debug.
Then 4 digits for the date in the year (MMDD).
Next a space separator, then the time of day, down to the milliseconds.
After that a thread id (fixed length, e.g. 5 digits, with leading zeros or spaces).
Finally the source of the message (variable length) and the message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, good idea. My next step was to reduce the fixed portion and I like this suggestion.
One note, I did originally add the thread ID in but it was giving me a 12 digit string, which seemed odd. I'll play a little more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Confirmed, the thread id is a very large number. Current format with latest commit is:
I1228 10:05:01.572 logger.py:112 ****************************** Starting PanLogger ******************************
I1228 10:05:04.897 observatory.py:35 Initializing observatory
I1228 10:05:04.897 observatory.py:38 Setting up location
D1228 10:05:04.897 observatory.py:483 Setting up site details of observatory
Note that we lose time zone information by adding the msecs. Could get back in there with a little bit of work but not entirely sure how important it is.
@@ -3,26 +3,12 @@ logger: | |||
use_utc: True | |||
formatters: | |||
simple: | |||
format: '%(asctime)s UTC - %(message)s' | |||
format: '%(asctime)s - %(message)s' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for removing UTC
pocs/utils/logger.py
Outdated
def critical(self, fmt, *args, **kwargs): | ||
self.logger.critical(self._process_str(fmt, *args, **kwargs)) | ||
Even though you can select '{' as the style for the formatter class, | ||
you still can't use {} formatting for your message. The custom |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apparently I was totally incorrect when I claimed that Python could handle this. I followed your link and found this comment:
Your statement about Python 3 is incorrect. The style parameter only applies to the Formatter format string, not the individual log messages. The page you linked to explicitly says: "There would no changing this while preserving backward compatibility".
So apparently many folks have misinterpreted the description of the style parameter as applying to the formatting of the log messages, not of the line that will contain the log message. Sigh.
My apologies for sending you down the wrong path, and my gratitude that you found your way to a superior solution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No worries, I'm glad you suggested it as it forced me to dig up the correct method. I think the documents are very confusing in terms of what it allows. Honestly, I was very surprised there wasn't an existing module that would just do this, but I couldn't find anything.
And the incorrect file and line number was really starting to bother me, so it was a good time for it.
pocs/utils/logger.py
Outdated
msg = msg % self.args | ||
except (TypeError, ValueError): | ||
msg = msg.format(*self.args) | ||
return msg | ||
|
||
|
||
def get_root_logger(profile='panoptes', log_config=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please document params, especially point to https://docs.python.org/3/library/logging.config.html#configuration-dictionary-schema to explain log_config.
@@ -87,11 +70,11 @@ def get_root_logger(profile='panoptes', log_config=None): | |||
full_log_fname = '{}/{}-{}.log'.format(log_dir, log_fname, handler) | |||
log_config['handlers'][handler].setdefault('filename', full_log_fname) | |||
|
|||
# Setup the TimeedRotatingFileHandler for middle of day | |||
# Setup the TimedRotatingFileHandler for middle of day |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A TODO for the future: remove explicit reference to TimedRotatingFileHandler, and instead check for atTime being a string in the log_config, and if so parsing it with some flexibility regarding the time format.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I understand what that would get us but let's discuss in a separate Issue.
pocs/utils/logger.py
Outdated
log_config['handlers'][handler].setdefault('atTime', datetime.time(hour=11, minute=30)) | ||
|
||
if handler == 'all': | ||
# Symlink the log file to $PANDIR/logs/panoptes.log | ||
# Symlink the log file to log_symlink |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think of this as the other way around:
# Create a symlink to the log file with just the name of the script, not the date and pid,
# as this makes it easier to find the latest such log file when debugging.
* Reduced log message format via filter (see example below) * Add docstring * Fix logger on messaging * Remove unused coloredlogs module (will put `grc` info in wiki) ``` I1228 10:05:01.572 logger.py:112 ****************************** Starting PanLogger ****************************** I1228 10:05:04.897 observatory.py:35 Initializing observatory I1228 10:05:04.897 observatory.py:38 Setting up location D1228 10:05:04.897 observatory.py:483 Setting up site details of observatory ```
LogRecord
class%
or{}
(str.format) style for actuallog messages.
Fixes #253
Now you can:
For the last example we could double-interpolate it, but I don't think it is too large of an issue.
Note that this performs legacy interpolation first (via
%
) and catches exceptions and then tries thestr.format
. Might be more efficient to reverse order but I don't think the impact is large.Full log output example: