
Hello Haskellers! I have developed a very simple logging library to be extendable and easy-to-use. You can see the current release at http://hackage.haskell.org/package/hlogger/. The SimpleHLogger module is an example of what a HLogger implementation could look like. It could be used like this: import System.Log.SimpleHLogger main = do logger<- simpleLogger "test" loggerLog logger (Just ("LoggerTest", "main")) Debug "Test" loggerStop logger As I have now implemented everything that I could think of, I would like to ask the Haskell community to give some feedback on HLogger so that I can continuing improving it. Some questions: 1. Do you have any general/architectural thoughts on things I might be doing wrong? 2. Is the ease-of-use goal contradicting making this library useful in more complex applications? 3. Do I want to redesign HLogger to allow loggers to have a mutable state, and if so, how can I do that? 4. Is there a nice way to provide the module and the function than using (Just ("LoggerTest, "main)) (shortening it somehow, I guess)? Thanks! Warm regards, Jon Kristensen

On Tue, Apr 12, 2011 at 6:40 PM, Jon Kristensen
Hello Haskellers!
As I have now implemented everything that I could think of, I would like to ask the Haskell community to give some feedback on HLogger so that I can continuing improving it. Some questions:
Do you have any general/architectural thoughts on things I might be doing wrong?
1) Use "Text" as the string type, not "String" 2) Re: SimpleLogger: writing to and flushing the log file upon receiving each message is absolutely the wrong thing to do in high-performance code. Each write() is a context switch into the kernel, and doing it this way will kill your throughput (in messages per second). What we do in our webserver (which relies on high-throughput access logging) is to buffer messages to the log channel in memory, and perform the actual writes in a separate worker thread no more often than once every N seconds.
Is the ease-of-use goal contradicting making this library useful in more complex applications?
"Easy to use" and "high performance" don't have to be contradictory,
but you shouldn't neglect the latter.
G
--
Gregory Collins

On Tue, 12 Apr 2011 19:10:09 +0200, Gregory Collins
On Tue, Apr 12, 2011 at 6:40 PM, Jon Kristensen
wrote: Hello Haskellers!
As I have now implemented everything that I could think of, I would like to ask the Haskell community to give some feedback on HLogger so that I can continuing improving it. Some questions:
Do you have any general/architectural thoughts on things I might be doing wrong?
1) Use "Text" as the string type, not "String"
2) Re: SimpleLogger: writing to and flushing the log file upon receiving each message is absolutely the wrong thing to do in high-performance code. Each write() is a context switch into the kernel, and doing it this way will kill your throughput (in messages per second). What we do in our webserver (which relies on high-throughput access logging) is to buffer messages to the log channel in memory, and perform the actual writes in a separate worker thread no more often than once every N seconds.
If you want to know what the last thing was that your application was doing, before it crashed (e.g. at the customers site), you better write every message immediately to disk. Regards, Henk-Jan van Tuyl -- http://Van.Tuyl.eu/ http://members.chello.nl/hjgtuyl/tourdemonad.html --

Jon, thanks for HLogger! For my (small) needs I was looking for a
simple logging solution, and I couldn't get HSLogger to do what I
wanted, whereas your simpleLogger fitted the bill perfectly.
I suppose a good thing would be conditional buffering, as other noted:
in development mode I want to get my log entries flushed to disk
immediately, while in production I don't want to impact the
performance of my running application by waiting for the logs.
I didn't think that the invocations needed to be made easier: I just
used "logNotice logger message", hard to do shorter.
JP
On Tue, Apr 12, 2011 at 11:45 PM, Henk-Jan van Tuyl
On Tue, 12 Apr 2011 19:10:09 +0200, Gregory Collins
wrote: On Tue, Apr 12, 2011 at 6:40 PM, Jon Kristensen
wrote: Hello Haskellers!
As I have now implemented everything that I could think of, I would like to ask the Haskell community to give some feedback on HLogger so that I can continuing improving it. Some questions:
Do you have any general/architectural thoughts on things I might be doing wrong?
1) Use "Text" as the string type, not "String"
2) Re: SimpleLogger: writing to and flushing the log file upon receiving each message is absolutely the wrong thing to do in high-performance code. Each write() is a context switch into the kernel, and doing it this way will kill your throughput (in messages per second). What we do in our webserver (which relies on high-throughput access logging) is to buffer messages to the log channel in memory, and perform the actual writes in a separate worker thread no more often than once every N seconds.
If you want to know what the last thing was that your application was doing, before it crashed (e.g. at the customers site), you better write every message immediately to disk.
Regards, Henk-Jan van Tuyl
-- http://Van.Tuyl.eu/ http://members.chello.nl/hjgtuyl/tourdemonad.html --
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- JP Moresmau http://jpmoresmau.blogspot.com/

On Tue, Apr 12, 2011 at 11:45 PM, Henk-Jan van Tuyl
If you want to know what the last thing was that your application was doing, before it crashed (e.g. at the customers site), you better write every message immediately to disk.
Yes, I suppose it would depend on your use case whether you wanted to
optimize for throughput or for latency to secondary storage. I just
know from experience that for high-throughput server applications,
writing each message to disk is going to introduce unacceptable
context-switching overhead.
G
--
Gregory Collins

On Tue, Apr 12, 2011 at 11:40 AM, Jon Kristensen
Hello Haskellers!
I have developed a very simple logging library to be extendable and easy-to-use. You can see the current release at http://hackage.haskell.org/package/hlogger/. The SimpleHLogger module is an example of what a HLogger implementation could look like. It could be used like this:
import System.Log.SimpleHLogger
main = do
logger <- simpleLogger "test"
loggerLog logger (Just ("LoggerTest", "main")) Debug "Test"
loggerStop logger
As I have now implemented everything that I could think of, I would like to ask the Haskell community to give some feedback on HLogger so that I can continuing improving it. Some questions:
It looks very simple, which is nice. Just about the only things I would add: * A standard-out/standard-error logger * A monoid instance for the Logger type * Convinience functions for logging without context and logging at a specific error level:
logError myLogger "Oh no!" logDebug myLogger "a thing happened"
These might be in a separate module, so I can define them for myslef based on some logContext function, so that in my module I can define:
logError msg = logContext "Module.Name" LogLevelError msg
You might even be able to offer a separate package with TemplateHaskell splices to build these helpers. Maybe I'm going off the deep-end it terms of complexity. Have you looked into HsLogger at all? This project has a confusingly similar name - so much so I thought that your email was about HsLogger! Take care, Antoine
Do you have any general/architectural thoughts on things I might be doing wrong? Is the ease-of-use goal contradicting making this library useful in more complex applications? Do I want to redesign HLogger to allow loggers to have a mutable state, and if so, how can I do that? Is there a nice way to provide the module and the function than using (Just ("LoggerTest, "main)) (shortening it somehow, I guess)?
Thanks!
Warm regards, Jon Kristensen
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (5)
-
Antoine Latter
-
Gregory Collins
-
Henk-Jan van Tuyl
-
Jon Kristensen
-
JP Moresmau