fast-logger (empty) → 0.0.0
raw patch · 5 files changed
+196/−0 lines, 5 filesdep +basedep +blaze-builderdep +bytestringsetup-changed
Dependencies added: base, blaze-builder, bytestring, directory, filepath
Files
- LICENSE +29/−0
- Setup.hs +2/−0
- System/Log/FastLogger.hs +102/−0
- System/Log/FastLogger/File.hs +42/−0
- fast-logger.cabal +21/−0
+ LICENSE view
@@ -0,0 +1,29 @@+Copyright (c) 2009, IIJ Innovation Institute Inc.+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.+ * Redistributions in binary form must reproduce the above copyright+ notice, this list of conditions and the following disclaimer in+ the documentation and/or other materials provided with the+ distribution.+ * Neither the name of the copyright holders nor the names of its+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE+POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ System/Log/FastLogger.hs view
@@ -0,0 +1,102 @@+{-# LANGUAGE DoAndIfThenElse, NoImplicitPrelude, RecordWildCards #-}++-- | Fast logging system to copy log data directly to Handle buffer.++module System.Log.FastLogger (+ -- * Initialization+ initHandle+ -- * Logging+ , LogStr(..)+ , hPutLogStr+ -- * Builder+ , hPutBuilder+ -- * File rotation+ , module System.Log.FastLogger.File+ ) where++import Blaze.ByteString.Builder+import qualified Data.ByteString as BS+import Data.ByteString.Internal (ByteString(..), c2w)+import Data.List+import Data.Maybe+import Foreign+import GHC.Base+import GHC.IO.Buffer+import qualified GHC.IO.BufferedIO as Buffered+import GHC.IO.Handle.Internals+import GHC.IO.Handle.Text+import GHC.IO.Handle.Types+import GHC.IORef+import GHC.Num+import GHC.Real+import System.IO+import System.Log.FastLogger.File++{-| Setting a proper buffering to 'Handle'.+-}+initHandle :: Handle -> IO ()+initHandle hdl = hSetBuffering hdl (BlockBuffering (Just 4096))++{-| A date type to contain 'String' and 'ByteString'.+ This data is exported so that format can be defined.+ This would be replaced with 'Builder' someday when+ it can be written directly to 'Handle' buffer.+-}+data LogStr = LS !String | LB !ByteString++{-| The 'hPut' function to copy a list of 'LogStr' to the buffer+ of 'Handle' directly.+ If 'Handle' is associated with a file, 'AppendMode' must be used.+-}+hPutLogStr :: Handle -> [LogStr] -> IO ()+hPutLogStr handle bss =+ wantWritableHandle "hPutLogStr" handle $ \h_ -> bufsWrite h_ bss++bufsWrite :: Handle__-> [LogStr] -> IO ()+bufsWrite h_@Handle__{..} bss = do+ old_buf@Buffer{+ bufRaw = old_raw+ , bufR = w+ , bufSize = size+ } <- readIORef haByteBuffer+ if size - w > len then do+ withRawBuffer old_raw $ \ptr ->+ go (ptr `plusPtr` w) bss+ writeIORef haByteBuffer old_buf{ bufR = w + len }+ else do+ old_buf' <- Buffered.flushWriteBuffer haDevice old_buf+ writeIORef haByteBuffer old_buf'+ bufsWrite h_ bss+ where+ len = foldl' (\x y -> x + getLength y) 0 bss+ getLength (LB s) = BS.length s+ getLength (LS s) = length s+ go :: Ptr Word8 -> [LogStr] -> IO ()+ go _ [] = return ()+ go dst (LB b:bs) = do+ dst' <- copy dst b+ go dst' bs+ go dst (LS s:ss) = do+ dst' <- copy' dst s+ go dst' ss++copy :: Ptr Word8 -> ByteString -> IO (Ptr Word8)+copy dst (PS ptr off len) = withForeignPtr ptr $ \s -> do+ let src = s `plusPtr` off+ memcpy dst src (fromIntegral len)+ return (dst `plusPtr` len)++copy' :: Ptr Word8 -> String -> IO (Ptr Word8)+copy' dst [] = return dst+copy' dst (x:xs) = do+ poke dst (c2w x)+ copy' (dst `plusPtr` 1) xs++{-| The 'hPut' function directory to copy 'Builder' to the buffer.+ If 'Handle' is associated with a file, 'AppendMode' must be used.+ The current implementation is inefficient at this moment.+ 'initHandle' must be called once beforehand if this function is used.+ This would replace 'hPutLogStr' someday.+-}+hPutBuilder :: Handle -> Builder -> IO ()+hPutBuilder hdl = BS.hPut hdl . toByteString
+ System/Log/FastLogger/File.hs view
@@ -0,0 +1,42 @@+module System.Log.FastLogger.File where++import Control.Monad+import System.Directory+import System.FilePath++-- | The spec for logging files+data FileLogSpec = FileLogSpec {+ log_file :: String+ , log_file_size :: Integer+ , log_backup_number :: Int+ }++-- | Checking if a log file can be written.+check :: FileLogSpec -> IO ()+check spec = do+ dirExist <- doesDirectoryExist dir+ unless dirExist $ fail $ dir ++ " does not exist or is not a directory."+ dirPerm <- getPermissions dir+ unless (writable dirPerm) $ fail $ dir ++ " is not writable."+ exist <- doesFileExist file+ when exist $ do+ perm <- getPermissions file+ unless (writable perm) $ fail $ file ++ " is not writable."+ where+ file = log_file spec+ dir = takeDirectory file++-- | Rotating log files.+rotate :: FileLogSpec -> IO ()+rotate spec = mapM_ move srcdsts+ where+ path = log_file spec+ n = log_backup_number spec+ dsts' = reverse . ("":) . map (('.':). show) $ [0..n-1]+ dsts = map (path++) dsts'+ srcs = tail dsts+ srcdsts = zip srcs dsts+ move (src,dst) = do+ exist <- doesFileExist src+ when exist $ renameFile src dst+
+ fast-logger.cabal view
@@ -0,0 +1,21 @@+Name: fast-logger+Version: 0.0.0+Author: Kazu Yamamoto <kazu@iij.ad.jp>+Maintainer: Kazu Yamamoto <kazu@iij.ad.jp>+License: BSD3+License-File: LICENSE+Synopsis: A fast logging system+Description: A fast logging system+Category: System+Cabal-Version: >= 1.6+Build-Type: Simple+library+ GHC-Options: -Wall -fno-warn-unused-do-bind+ Exposed-Modules: System.Log.FastLogger+ System.Log.FastLogger.File+ Build-Depends: base >= 4 && < 5,+ filepath, directory, bytestring, blaze-builder+Source-Repository head+ Type: git+ Location: git://github.com/kazu-yamamoto/fast-logger.git+