<commit_before>{- arch-tag: Logger main definition
Copyright (C) 2004 <NAME> <<EMAIL>>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-}

{- |
   Module     : MissingH.Logging.Logger
   Copyright  : Copyright (C) 2004 <NAME>
   License    : GNU GPL, version 2 or above

   Maintainer : <NAME> <<EMAIL>> 
   Stability  : provisional
   Portability: portable

Haskell Logging Framework, Primary Interface

Written by <NAME>, <EMAIL>

Welcome to the error and information logging system for Haskell.

This system is patterned after Python\'s @logging@ module,
<http://www.python.org/doc/current/lib/module-logging.html> and some of
the documentation here was based on documentation there.

To log a message, you perform operations on 'Logger's.  Each 'Logger' has a
name, and they are arranged hierarchically.  Periods serve as separators.
Therefore, a 'Logger' named \"foo\" is the parent of loggers \"foo.printing\",
\"foo.html\", and \"foo.io\".  These names can be anything you want.  They're
used to indicate the area of an application or library in which a logged
message originates.  Later you will see how you can use this concept to 
fine-tune logging behaviors based on specific application areas.

You can also tune logging behaviors based upon how important a message is.
Each message you log will have an importance associated with it.  The different
importance levels are given by the 'Priority' type.  I've also provided
some convenient functions that correspond to these importance levels:
'debugM' through 'emergencyM' log messages with the specified importance.

Now, an importance level (or 'Priority') 
is associated not just with a particular message but also
with a 'Logger'.  If the 'Priority' of a given log message is lower than
the 'Priority' configured in the 'Logger', that message is ignored.  This
way, you can globally control how verbose your logging output is.

Now, let's follow what happens under the hood when you log a message.  We'll
assume for the moment that you are logging something with a high enough
'Priority' that it passes the test in your 'Logger'.  In your code, you'll
call 'logM' or something like 'debugM' to log the message.  Your 'Logger'
decides to accept the message.  What next?

Well, we also have a notion of /handlers/ ('LogHandler's, to be precise).
A 'LogHandler' is a thing that takes a message and sends it somewhere.
That \"somewhere\" may be your screen (via standard error), your system's
logging infrastructure (via syslog), a file, or other things.  Each
'Logger' can have zero or more 'LogHandler's associated with it.  When your
'Logger' has a message to log, it passes it to every 'LogHandler' it knows
of to process.  What's more, it is also passed to /all handlers of all
ancestors of the Logger/, regardless of whether those 'Logger's would
normally have passed on the message.

To give you one extra little knob to turn, 'LogHandler's can also have
importance levels ('Priority') associated with them in the same way
that 'Logger's do.  They act just like the 'Priority' value in the
'Logger's -- as a filter.  It's useful, for instance, to make sure that
under no circumstances will a mere 'DEBUG' message show up in your syslog.

There are three built-in handlers given in two built-in modules:
"MissingH.Logging.Handler.Simple" and "MissingH.Logging.Handler.Syslog".

There is a special logger known as the /root logger/ that sits at the top
of the logger hierarchy.  It is always present, and handlers attached
there will be called for every message.  You can use 'getRootLogger' to get
it or 'rootLoggerName' to work with it by name.

Here's an example to illustrate some of these concepts:

> import MissingH.Logging.Logger
> import MissingH.Logging.Handler.Syslog
> 
> -- By default, all messages of level WARNING and above are sent to stderr.
> -- Everything else is ignored.
> 
> -- "MyApp.Component" is an arbitrary string; you can tune
> -- logging behavior based on it later.
> main = do
>        debugM "MyApp.Component"  "This is a debug message -- never to be seen"
>        warningM "MyApp.Component2" "Something Bad is about to happen."
> 
>        -- Copy everything to syslog from here on out.
>        s <- openlog "SyslogStuff" [PID] USER DEBUG
>        updateGlobalLogger rootLoggerName (addHandler s)
>       
>        errorM "MyApp.Component" "This is going to stderr and syslog."
>
>        -- Now we'd like to see everything from BuggyComponent
>        -- at DEBUG or higher go to syslog and stderr.
>        -- Also, we'd like to still ignore things less than
>        -- WARNING in other areas.
>        -- 
>        -- So, we adjust the Logger for MyApp.Component.
>
>        updateGlobalLogger "MyApp.BuggyComponent"
>                           (setLevel DEBUG)
>
>        -- This message will go to syslog -- the default
>        -- restrictions on the root logger will filter it out.
>        debugM "MyApp.BuggyComponent" "This buggy component is buggy"
> 
>        -- This message will go to syslog and stderr too.
>        warningM "MyApp.BuggyComponent" "Still Buggy"
> 
>        -- This message goes nowhere.
>        debugM "MyApp.WorkingComponent" "Hello"

-}

module MissingH.Logging.Logger(
                               -- * Basic Types
                               Logger,
                               -- ** Re-Exported from MissingH.Logging
                               Priority(..),
                               -- * Logging Messages
                               -- ** Basic
                               logM,
                               -- ** Utility Functions
                               -- These functions are wrappers for 'logM' to
                               -- make your job easier.<commit_msg>Corrected docs in Logger example<commit_after>{- arch-tag: Logger main definition
Copyright (C) 2004-2006 <NAME> <<EMAIL>>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-}

{- |
   Module     : MissingH.Logging.Logger
   Copyright  : Copyright (C) 2004-2006 <NAME>
   License    : GNU GPL, version 2 or above

   Maintainer : <NAME> <<EMAIL>> 
   Stability  : provisional
   Portability: portable

Haskell Logging Framework, Primary Interface

Written by <NAME>, <EMAIL>

Welcome to the error and information logging system for Haskell.

This system is patterned after Python\'s @logging@ module,
<http://www.python.org/doc/current/lib/module-logging.html> and some of
the documentation here was based on documentation there.

To log a message, you perform operations on 'Logger's.  Each 'Logger' has a
name, and they are arranged hierarchically.  Periods serve as separators.
Therefore, a 'Logger' named \"foo\" is the parent of loggers \"foo.printing\",
\"foo.html\", and \"foo.io\".  These names can be anything you want.  They're
used to indicate the area of an application or library in which a logged
message originates.  Later you will see how you can use this concept to 
fine-tune logging behaviors based on specific application areas.

You can also tune logging behaviors based upon how important a message is.
Each message you log will have an importance associated with it.  The different
importance levels are given by the 'Priority' type.  I've also provided
some convenient functions that correspond to these importance levels:
'debugM' through 'emergencyM' log messages with the specified importance.

Now, an importance level (or 'Priority') 
is associated not just with a particular message but also
with a 'Logger'.  If the 'Priority' of a given log message is lower than
the 'Priority' configured in the 'Logger', that message is ignored.  This
way, you can globally control how verbose your logging output is.

Now, let's follow what happens under the hood when you log a message.  We'll
assume for the moment that you are logging something with a high enough
'Priority' that it passes the test in your 'Logger'.  In your code, you'll
call 'logM' or something like 'debugM' to log the message.  Your 'Logger'
decides to accept the message.  What next?

Well, we also have a notion of /handlers/ ('LogHandler's, to be precise).
A 'LogHandler' is a thing that takes a message and sends it somewhere.
That \"somewhere\" may be your screen (via standard error), your system's
logging infrastructure (via syslog), a file, or other things.  Each
'Logger' can have zero or more 'LogHandler's associated with it.  When your
'Logger' has a message to log, it passes it to every 'LogHandler' it knows
of to process.  What's more, it is also passed to /all handlers of all
ancestors of the Logger/, regardless of whether those 'Logger's would
normally have passed on the message.

To give you one extra little knob to turn, 'LogHandler's can also have
importance levels ('Priority') associated with them in the same way
that 'Logger's do.  They act just like the 'Priority' value in the
'Logger's -- as a filter.  It's useful, for instance, to make sure that
under no circumstances will a mere 'DEBUG' message show up in your syslog.

There are three built-in handlers given in two built-in modules:
"MissingH.Logging.Handler.Simple" and "MissingH.Logging.Handler.Syslog".

There is a special logger known as the /root logger/ that sits at the top
of the logger hierarchy.  It is always present, and handlers attached
there will be called for every message.  You can use 'getRootLogger' to get
it or 'rootLoggerName' to work with it by name.

Here's an example to illustrate some of these concepts:

> import MissingH.Logging.Logger
> import MissingH.Logging.Handler.Syslog
> 
> -- By default, all messages of level WARNING and above are sent to stderr.
> -- Everything else is ignored.
> 
> -- "MyApp.Component" is an arbitrary string; you can tune
> -- logging behavior based on it later.
> main = do
>        debugM "MyApp.Component"  "This is a debug message -- never to be seen"
>        warningM "MyApp.Component2" "Something Bad is about to happen."
> 
>        -- Copy everything to syslog from here on out.
>        s <- openlog "SyslogStuff" [PID] USER DEBUG
>        updateGlobalLogger rootLoggerName (addHandler s)
>       
>        errorM "MyApp.Component" "This is going to stderr and syslog."
>
>        -- Now we'd like to see everything from BuggyComponent
>        -- at DEBUG or higher go to syslog and stderr.
>        -- Also, we'd like to still ignore things less than
>        -- WARNING in other areas.
>        -- 
>        -- So, we adjust the Logger for MyApp.Component.
>
>        updateGlobalLogger "MyApp.BuggyComponent"
>                           (setLevel DEBUG)
>
>        -- This message will go to syslog and stderr
>        debugM "MyApp.BuggyComponent" "This buggy component is buggy"
> 
>        -- This message will go to syslog and stderr too.
>        warningM "MyApp.BuggyComponent" "Still Buggy"
> 
>        -- This message goes nowhere.
>        debugM "MyApp.WorkingComponent" "Hello"

-}

module MissingH.Logging.Logger(
                               -- * Basic Types
                               Logger,
                               -- ** Re-Exported from MissingH.Logging
                               Priority(..),
                               -- * Logging Messages
                               -- ** Basic
                               logM,
                               -- ** Utility Functions
                               -- These functions are wrappers for 'logM' to
                               -- make your job easier.
{'fraction_non_alphanumeric': 0.07021963315752185, 'fraction_numerical': 0.004565850586475636, 'mean_word_length': 2.834591005131301, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 96, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4007744', 'n_tokens_mistral': 3411, 'n_tokens_neox': 3244, 'n_words': 1704}