4 ms·
Slightly off topic: in an effort to become a better programmer, and to improve the Python ecosystem, I've tried to write a "for Humans" style logging library. W
by peter_l_downs 14y ago
Slightly off topic: in an effort to become a better programmer, and to improve the Python ecosystem, I've tried to write a "for Humans" style logging library. Would anyone mind giving me feedback?
http://peterdowns.com/lggr/ http://peterdowns.com/lggr/
- Goopplesoft 14y agoLooks great. Can't get to testing it today but I will get back to you soon.
- peter_l_downs 14y agoThanks! Is the API simple enough?
- jwpeddle 14y agoSome feedback from reading this page: - Why is your example logger named d? It might seem nitpicky but it's hard to read an example with a meaningless single character variable. - "d.close() # stop logging" - what is this? What does it mean to "stop logging" and why do I want to? - "Add a coroutine" - I would wager the lay Python developer doesn't even know what this word means. - lggr.Lggr() - Why not just name the class Logger? - The default format variables are inconsistent about when words are separated with an underscore. - I can't make sense of the example logging calls. In one you pass a dictionary as the second argument, in another you pass three strings as separate arguments. Why would anyone pass a message like this instead of just using standard string formatting? Especially when there's other legit arguments like extra. It's not even really clear why you'd want to pass something in extra instead of in the message. I fully support your goal, but at a glance this seems like a confusing alternative to logging. EDIT: hot dang it's hard to format a bulleted list on HN
- peter_l_downs 14y agoHi jwpeddle, thanks for all of the feedback! All of the changes I've made are on a branch called 'hn-fix' (https://github.com/peterldowns/lggr/tree/hn-fix https://github.com/peterldowns/lggr/tree/hn-fix) if you'd like to take a look. > Why is your example logger named d? It might seem nitpicky but > it's hard to read an example with a meaningless single character variable. No particular reason -- you're right, I will change this now. > "d.close() # stop logging" - what is this? What does it mean to "stop logging" > and why do I want to? This is a way to "close" the logger and clean up all of its associated coroutines. An example of when you might want to is upon catching a fatal error to your program, you might want to log the error and then safely clean up all open files or network sockets to which the logger is writing. The method name is clearly confusing -- what do you think of using "shutdown" instead? > "Add a coroutine" - I would wager the lay Python developer doesn't > even know what this word means. Maybe not, but they should! The readme now includes a link to dabeaz's coroutines page, and I'll add a quick overview in a couple of minutes. > lggr.Lggr() - Why not just name the class Logger? For consistency's sake. Maybe if I had to start again I would call the project `logger`, but I decided to be "hip" and use a vowel-less name instead :) > The default format variables are inconsistent about when words are separated > with an underscore. The initial idea was to mimic the variable names from the default logging module (http://docs.python.org/2/library/logging.html#logrecord-attributes http://docs.python.org/2/library/logging.html#logrecord-attr...). You're right that it is confusing though! I think I will rename everything to be lower case, one word, instead of the default module's mix of camelCase and underscore_separated names. Thoughts? > I can't make sense of the example logging calls. In one you pass a > dictionary as the second argument, in another you pass three strings > as separate arguments. Why would anyone pass a message like this > instead of just using standard string formatting? Especially when > there's other legit arguments like extra. It's not even really clear > why you'd want to pass something in extra instead of in the message. I should definitely clarify what formats are allowed and aren't. The log message format is using standard string formatting -- string.format(), to be exact. The 'extra' argument is a result of trying to imitate the default library (see http://docs.python.org/2/library/logging.html#logging.Logger.debug http://docs.python.org/2/library/logging.html#logging.Logger... for a description of the 'extra' kwarg), and can be useful when you'd like to pass information to every single log message.
- scott_s 14y agoI think "close()" is the appropriate name, as it's analogous to closing a file.
- aiiane 14y agoWhy not just add an atexit trap that automatically cleans up open logs? http://docs.python.org/2/library/atexit.html http://docs.python.org/2/library/atexit.html
- LeafStorm 14y agoI am fairly sure that most of the streams and sockets would get closed when the interpreter exited regardless. Also, in accordance to the principle of "explicit is better than implicit," it's generally better to avoid messing with global state (such as atexit) behind the scenes, and to provide a way to shut down the logs manually.
- peter_l_downs 14y agoLeafStorm got to it before me :)
- Leszek 14y agoMaybe you want to support python's with statement instead of a close() method?
- ColinWright 14y agoIt's trivial to format a bullet list on HN: * Leave blank lines between bullet points, * Start each line with <splat> <space> * Bob's your parent's brother. Hope that helps. See also: http://news.ycombinator.com/formatdoc http://news.ycombinator.com/formatdoc
- unshift 14y agoyour library has no tests! it's a good effort but I honestly wouldn't use it yet. a few nit picks: i can't imagine a scenario where i'd want my logger to close stdout (or any other file descriptor) for me. there is a lot of missing error handling, which is really important for something critical like a logger. what happens when disk space runs out? no timeouts on network operations? also your SMTP and Gmail loggers don't form valid MIME messages (I can't log non-ascii?). you also seem to just swallow exceptions which is totally not what I would want or expect from a logging library. keep at it though, the logging module's API (inspired by log4j) is fairly painful.
- peter_l_downs 14y ago> your library has no tests! it's a good effort but I > honestly wouldn't use it yet. You're right, and I'd love to have you help me add them! > i can't imagine a scenario where i'd want my logger to > close stdout (or any other file descriptor) for me. By default it won't -- see https://github.com/peterldowns/lggr/blob/master/lggr/__init__.py#L297 https://github.com/peterldowns/lggr/blob/master/lggr/__init_.... > there is a lot of missing error handling, which is really > important for something critical like a logger. what > happens when disk space runs out? no timeouts on > network operations? > [...] > you also seem to just swallow exceptions which is totally > not what I would want or expect from a logging library. Lggr will fail silently by default, because your logging library shouldn't cause your code to crash. If you'd like, it's quite easy to stop it from suppressing errors. For more complex error handling, I think users should write their own coroutines for handling log messages -- the default file printing and network sending coroutines are merely the most basic case. > also your SMTP and Gmail loggers don't form valid MIME messages > (I can't log non-ascii?). Please help me and add loggers that do format valid MIME message! The included loggers/coroutines are just a few examples I came up with, but I'd love if other people were to contribute more :) > keep at it though, the logging module's API (inspired by log4j) > is fairly painful. Thank you, and thanks for your feedback :)
- mercurial 14y agoI like the idea of delegating logging to its own process in theory (in practice, it would depend on your configuration, I guess, it may mean a lot of context switching), but your built-in coroutines seem to rely on yield instead. Have you experimented with all three styles? A big feature missing, IMHO, is file-based configuration. You definitely want this for larger projects.
- antihero 14y agoInteresting. This is weird as fuck, though: d.critical("Someone {} us {} the {}!", "set", "up", "bomb") See that seems ambiguous - does it actually use the string formating mini-lanaguage?
- Evbn 14y agoMost unpythonic module name ever. Change it to logger.