diff --git a/micrologger.cabal b/micrologger.cabal
--- a/micrologger.cabal
+++ b/micrologger.cabal
@@ -1,5 +1,5 @@
 name:                micrologger
-version:             0.3.0.0
+version:             0.3.1.0
 synopsis:            A super simple logging module. Only for use for very simple projects.
 description:         A super simple logging module. Only for use for very simple projects.
 homepage:            https://github.com/savannidgerinel/micrologger#readme
diff --git a/src/LuminescentDreams/Logger.hs b/src/LuminescentDreams/Logger.hs
--- a/src/LuminescentDreams/Logger.hs
+++ b/src/LuminescentDreams/Logger.hs
@@ -1,9 +1,32 @@
+{- | This is the main API module for the logger. You will generally want to import this directly.
+
+Usage suggestions:
+
+
+ -}
+{-# LANGUAGE RecordWildCards  #-}
 module LuminescentDreams.Logger (
     module X
-  , LogLevel(..), Logger(..)
+  , LogConfig(..), LogLevel(..), Logger(..)
+  , withLogger
   )
   where
 
 import           LuminescentDreams.Logger.Internal
-import           LuminescentDreams.Logger.JSON       as X
-import           LuminescentDreams.Logger.Standard   as X
+import           LuminescentDreams.Logger.JSON        as X
+import           LuminescentDreams.Logger.Standard    as X
+
+import qualified Data.Text.Lazy                       as T
+import           System.IO                            (IOMode(..), hPutStrLn, withFile)
+
+{- | Ordinary configurations for a file-based logger. -}
+data LogConfig = LogConfig { path :: FilePath
+                           , level :: LogLevel
+                           }
+  deriving (Show)
+
+
+{- | Run an IO action with a log safely available. Logs will be properly closed in the case of an exception. Logging is meant to happen to a file, specified in LogConfig, so this may not be suitable if you want to log to a different resource. -}
+withLogger :: LogConfig -> (Logger -> IO a) -> IO a
+withLogger LogConfig{..} act =
+  withFile path AppendMode $ \h -> act (Logger (hPutStrLn h . T.unpack) level)
diff --git a/src/LuminescentDreams/Logger/Internal.hs b/src/LuminescentDreams/Logger/Internal.hs
--- a/src/LuminescentDreams/Logger/Internal.hs
+++ b/src/LuminescentDreams/Logger/Internal.hs
@@ -1,17 +1,25 @@
+{- | Internal definitions. Do not import directly. -}
 module LuminescentDreams.Logger.Internal where
 
 import qualified Data.Text.Buildable      as TFB
 import qualified Data.Text.Lazy           as T
 
+{- | An ordinary hierarchy of logging priorities. -}
 data LogLevel = LogDebug
               | LogInfo
               | LogWarning
               | LogError
               | LogEmergency
-              deriving (Eq, Ord)
+              deriving (Eq, Ord, Show)
 
-data Logger = Logger (T.Text -> IO ()) LogLevel
+{- | The primary data structure to contain a logger of any kind. -}
+data Logger = Logger { logCmd_ :: (T.Text -> IO ())
+                       -- ^ Any IO action that accepts the log message
+                     , lvl_ :: LogLevel
+                       -- ^ The minimum level at which a log message should be accepted
+                     }
 
+{- | Generate standard text representations of a log level. This is useful to the Standard logger but may not be interesting to any others. -}
 instance TFB.Buildable LogLevel where
   build LogDebug      = TFB.build ("DEBUG" :: String)
   build LogInfo       = TFB.build ("INFO" :: String)
diff --git a/src/LuminescentDreams/Logger/JSON.hs b/src/LuminescentDreams/Logger/JSON.hs
--- a/src/LuminescentDreams/Logger/JSON.hs
+++ b/src/LuminescentDreams/Logger/JSON.hs
@@ -1,3 +1,7 @@
+{- | Generate JSON logs compatible with LogZ.io. `logMsgJs` and `formatMsgJs` are both re-exported, so it should not be necessary to import this module directly.
+
+TODO: Rename this to LogZ since it generates fields specific to that service.
+-}
 {-# LANGUAGE OverloadedStrings  #-}
 module LuminescentDreams.Logger.JSON ( logMsgJs, formatMsgJs ) where
 
@@ -12,6 +16,7 @@
 
 import           LuminescentDreams.Logger.Internal
 
+{- | Log a message in LogZ format. This uses `formatMsgJs` to generate the actual format string. -}
 logMsgJs :: Logger -> LogLevel -> [(String, Aeson.Value)] -> IO ()
 logMsgJs (Logger writer pri) lvl msg =
   if lvl >= pri
@@ -20,6 +25,7 @@
       writer $ formatMsgJs t lvl msg
     else return ()
 
+{- | Format a message for LogZ JSON format. -}
 formatMsgJs :: Time.UTCTime -> LogLevel -> [(String, Aeson.Value)] -> T.Text
 formatMsgJs time level msg =
   let msg_ = msg <> [ ("@timestamp", fromString $ Time.formatTime Time.defaultTimeLocale "%Y-%m-%dT%H:%M:%S" time)
