Hello community, here is the log from the commit of package ghc-fast-logger for openSUSE:Factory checked in at 2018-12-28 12:35:08 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ghc-fast-logger (Old) and /work/SRC/openSUSE:Factory/.ghc-fast-logger.new.28833 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "ghc-fast-logger" Fri Dec 28 12:35:08 2018 rev:14 rq:661494 version:2.4.13 Changes: -------- --- /work/SRC/openSUSE:Factory/ghc-fast-logger/ghc-fast-logger.changes 2018-10-25 08:25:27.595826463 +0200 +++ /work/SRC/openSUSE:Factory/.ghc-fast-logger.new.28833/ghc-fast-logger.changes 2018-12-28 12:35:22.975960921 +0100 @@ -1,0 +2,14 @@ +Tue Dec 25 03:01:34 UTC 2018 - psimons@suse.com + +- Update fast-logger to version 2.4.13. + Upstream has not updated the file "ChangeLog.md" since the last + release. + +------------------------------------------------------------------- +Thu Dec 20 03:01:13 UTC 2018 - psimons@suse.com + +- Update fast-logger to version 2.4.12. + Upstream has not updated the file "ChangeLog.md" since the last + release. + +------------------------------------------------------------------- Old: ---- fast-logger-2.4.11.tar.gz New: ---- fast-logger-2.4.13.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ghc-fast-logger.spec ++++++ --- /var/tmp/diff_new_pack.2LcHKK/_old 2018-12-28 12:35:23.659960443 +0100 +++ /var/tmp/diff_new_pack.2LcHKK/_new 2018-12-28 12:35:23.663960440 +0100 @@ -19,7 +19,7 @@ %global pkg_name fast-logger %bcond_with tests Name: ghc-%{pkg_name} -Version: 2.4.11 +Version: 2.4.13 Release: 0 Summary: A fast logging system License: BSD-3-Clause @@ -35,7 +35,7 @@ BuildRequires: ghc-filepath-devel BuildRequires: ghc-rpm-macros BuildRequires: ghc-text-devel -BuildRequires: ghc-unix-devel +BuildRequires: ghc-unix-compat-devel BuildRequires: ghc-unix-time-devel %if %{with tests} BuildRequires: ghc-hspec-devel ++++++ fast-logger-2.4.11.tar.gz -> fast-logger-2.4.13.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fast-logger-2.4.11/System/Log/FastLogger/Date.hs new/fast-logger-2.4.13/System/Log/FastLogger/Date.hs --- old/fast-logger-2.4.11/System/Log/FastLogger/Date.hs 2018-02-05 03:01:32.000000000 +0100 +++ new/fast-logger-2.4.13/System/Log/FastLogger/Date.hs 2018-12-25 03:45:26.000000000 +0100 @@ -4,56 +4,27 @@ -- | -- Formatting time is slow. -- This package provides mechanisms to cache formatted date. -module System.Log.FastLogger.Date ( - -- * Types - TimeFormat - , FormattedTime - -- * Date cacher - , newTimeCache +module System.Log.FastLogger.Date + ( -- * Date cacher + newTimeCache , simpleTimeFormat , simpleTimeFormat' ) where import Control.AutoUpdate (mkAutoUpdate, defaultUpdateSettings, updateAction) -import Data.ByteString (ByteString) -#if WINDOWS -import qualified Data.ByteString.Char8 as BS -import Data.Time (UTCTime, formatTime, getCurrentTime, utcToLocalZonedTime) -# if MIN_VERSION_time(1,5,0) -import Data.Time (defaultTimeLocale) -# else -import System.Locale (defaultTimeLocale) -# endif -#else +import System.Log.FastLogger.Types (TimeFormat, FormattedTime) import Data.UnixTime (formatUnixTime, fromEpochTime) -import System.Posix (EpochTime, epochTime) -#endif +import System.PosixCompat.Types (EpochTime) +import System.PosixCompat.Time (epochTime) ---------------------------------------------------------------- --- | Type aliaes for date format and formatted date. -type FormattedTime = ByteString -type TimeFormat = ByteString - ----------------------------------------------------------------- - -#if WINDOWS --- | Get date using UTC. -getTime :: IO UTCTime -getTime = getCurrentTime --- | Format UTC date. -formatDate :: TimeFormat -> UTCTime -> IO FormattedTime -formatDate fmt ut = do - zt <- utcToLocalZonedTime ut - return $ BS.pack $ formatTime defaultTimeLocale (BS.unpack fmt) zt -#else -- | Get date using UnixTime. getTime :: IO EpochTime getTime = epochTime -- | Format unix EpochTime date. formatDate :: TimeFormat -> EpochTime -> IO FormattedTime formatDate fmt = formatUnixTime fmt . fromEpochTime -#endif ---------------------------------------------------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fast-logger-2.4.11/System/Log/FastLogger/File.hs new/fast-logger-2.4.13/System/Log/FastLogger/File.hs --- old/fast-logger-2.4.11/System/Log/FastLogger/File.hs 2018-02-05 03:01:32.000000000 +0100 +++ new/fast-logger-2.4.13/System/Log/FastLogger/File.hs 2018-12-25 03:45:26.000000000 +0100 @@ -1,10 +1,18 @@ {-# LANGUAGE Safe #-} -module System.Log.FastLogger.File where +module System.Log.FastLogger.File + ( FileLogSpec(..) + , TimedFileLogSpec (..) + , check + , rotate + , prefixTime + ) where import Control.Monad (unless, when) +import Data.ByteString.Char8 (unpack) import System.Directory (doesFileExist, doesDirectoryExist, getPermissions, writable, renameFile) -import System.FilePath (takeDirectory) +import System.FilePath (takeDirectory, dropFileName, takeFileName, (</>)) +import System.Log.FastLogger.Types (TimeFormat, FormattedTime) -- | The spec for logging files data FileLogSpec = FileLogSpec { @@ -13,6 +21,31 @@ , log_backup_number :: Int -- ^ Max number of rotated log files to keep around before overwriting the oldest one. } +-- | The spec for time based rotation. It supports post processing of log files. Does +-- not delete any logs. Example: +-- +-- @ +-- timeRotate fname = LogFileTimedRotate +-- (TimedFileLogSpec fname timeFormat sametime compressFile) +-- defaultBufSize +-- where +-- timeFormat = "%FT%H%M%S" +-- sametime = (==) `on` C8.takeWhile (/='T') +-- compressFile fp = void . forkIO $ +-- callProcess "tar" [ "--remove-files", "-caf", fp <> ".gz", fp ] +-- @ +data TimedFileLogSpec = TimedFileLogSpec { + timed_log_file :: FilePath -- ^ base file path + , timed_timefmt :: TimeFormat -- ^ time format to prepend + , timed_same_timeframe :: FormattedTime -> FormattedTime -> Bool + -- ^ function that compares two + -- formatted times as specified by + -- timed_timefmt and decides if a + -- new rotation is supposed to + -- begin + , timed_post_process :: FilePath -> IO () -- ^ processing function called asynchronously after a file is added to the rotation + } + -- | Checking if a log file can be written. check :: FilePath -> IO () check file = do @@ -40,3 +73,7 @@ move (src,dst) = do exist <- doesFileExist src when exist $ renameFile src dst + +-- | Prefix file name with formatted time +prefixTime :: FormattedTime -> FilePath -> FilePath +prefixTime time path = dropFileName path </> unpack time ++ "-" ++ takeFileName path diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fast-logger-2.4.11/System/Log/FastLogger/FileIO.hs new/fast-logger-2.4.13/System/Log/FastLogger/FileIO.hs --- old/fast-logger-2.4.11/System/Log/FastLogger/FileIO.hs 2018-02-05 03:01:32.000000000 +0100 +++ new/fast-logger-2.4.13/System/Log/FastLogger/FileIO.hs 2018-12-25 03:45:26.000000000 +0100 @@ -1,49 +1,10 @@ -{-# LANGUAGE CPP #-} - module System.Log.FastLogger.FileIO where -import Foreign.Ptr (Ptr) import Data.Word (Word8) - -#ifdef mingw32_HOST_OS -import System.Win32.Types (HANDLE, UINT) -import System.Win32.File -import Graphics.Win32.Misc (getStdHandle, sTD_OUTPUT_HANDLE, sTD_ERROR_HANDLE) -import Data.Bits ((.|.)) - -type FD = HANDLE -#if !MIN_VERSION_Win32(2,4,0) --- This flag is not defined in System.Win32.File -fILE_APPEND_DATA :: UINT -fILE_APPEND_DATA = 0x0004 -#endif - -closeFD :: FD -> IO () -closeFD = closeHandle - -openFileFD :: FilePath -> IO FD -openFileFD f = createFile f - fILE_APPEND_DATA - (fILE_SHARE_READ .|. fILE_SHARE_DELETE) - Nothing - oPEN_ALWAYS - fILE_ATTRIBUTE_NORMAL - Nothing - -getStderrFD :: IO FD -getStderrFD = getStdHandle sTD_ERROR_HANDLE - -getStdoutFD :: IO FD -getStdoutFD = getStdHandle sTD_OUTPUT_HANDLE - -writeRawBufferPtr2FD :: FD -> Ptr Word8 -> Int -> IO Int -writeRawBufferPtr2FD h bf len = fromIntegral `fmap` win32_WriteFile h bf (fromIntegral len) Nothing - -#else - +import Foreign.Ptr (Ptr) import GHC.IO.Device (close) -import qualified GHC.IO.FD as POSIX (FD(..)) import GHC.IO.FD (openFile, stderr, stdout, writeRawBufferPtr) +import qualified GHC.IO.FD as POSIX (FD(..)) import GHC.IO.IOMode (IOMode(..)) type FD = POSIX.FD @@ -62,5 +23,3 @@ writeRawBufferPtr2FD :: FD -> Ptr Word8 -> Int -> IO Int writeRawBufferPtr2FD fd bf len = fromIntegral `fmap` writeRawBufferPtr "write" fd bf 0 (fromIntegral len) - -#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fast-logger-2.4.11/System/Log/FastLogger/LogStr.hs new/fast-logger-2.4.13/System/Log/FastLogger/LogStr.hs --- old/fast-logger-2.4.11/System/Log/FastLogger/LogStr.hs 2018-02-05 03:01:32.000000000 +0100 +++ new/fast-logger-2.4.13/System/Log/FastLogger/LogStr.hs 2018-12-25 03:45:26.000000000 +0100 @@ -76,6 +76,8 @@ toLogStr bs = LogStr (BS.length bs) (toBuilder bs) instance ToLogStr BL.ByteString where toLogStr = toLogStr . S8.concat . BL.toChunks +instance ToLogStr Builder where + toLogStr x = let b = B.toLazyByteString x in LogStr (fromIntegral (BL.length b)) (B.lazyByteString b) instance ToLogStr String where toLogStr = toLogStr . TL.pack instance ToLogStr T.Text where diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fast-logger-2.4.11/System/Log/FastLogger/Types.hs new/fast-logger-2.4.13/System/Log/FastLogger/Types.hs --- old/fast-logger-2.4.11/System/Log/FastLogger/Types.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/fast-logger-2.4.13/System/Log/FastLogger/Types.hs 2018-12-25 03:45:26.000000000 +0100 @@ -0,0 +1,13 @@ +module System.Log.FastLogger.Types ( + -- * Types + TimeFormat + , FormattedTime + ) where + +import Data.ByteString (ByteString) + +---------------------------------------------------------------- + +-- | Type aliaes for date format and formatted date. +type FormattedTime = ByteString +type TimeFormat = ByteString diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fast-logger-2.4.11/System/Log/FastLogger.hs new/fast-logger-2.4.13/System/Log/FastLogger.hs --- old/fast-logger-2.4.11/System/Log/FastLogger.hs 2018-02-05 03:01:32.000000000 +0100 +++ new/fast-logger-2.4.13/System/Log/FastLogger.hs 2018-12-25 03:45:26.000000000 +0100 @@ -43,6 +43,8 @@ , module System.Log.FastLogger.Date -- * File rotation , module System.Log.FastLogger.File + -- * Types + , module System.Log.FastLogger.Types ) where #if __GLASGOW_HASKELL__ < 709 @@ -53,6 +55,7 @@ import Control.Exception (handle, SomeException(..), bracket) import Control.Monad (when, replicateM) import Data.Array (Array, listArray, (!), bounds) +import Data.Foldable (forM_) import Data.Maybe (isJust) import System.EasyFile (getFileSize) import System.Log.FastLogger.File @@ -62,6 +65,7 @@ import System.Log.FastLogger.LogStr import System.Log.FastLogger.Logger import System.Log.FastLogger.Date +import System.Log.FastLogger.Types ---------------------------------------------------------------- @@ -175,6 +179,15 @@ type FastLogger = LogStr -> IO () -- | 'TimedFastLogger' pass 'FormattedTime' to callback and simply log its result. -- this can be used to customize how to log timestamp. +-- +-- Usually, one would write a wrapper on top of 'TimedFastLogger', for example: +-- +-- @ +-- {-# LANGUAGE OverloadedStrings #-} +-- +-- log :: TimedFastLogger -> LogStr -> IO () +-- log logger msg = logger (\time -> toLogStr (show time) <> " " <> msg <> "\n") +-- @ type TimedFastLogger = (FormattedTime -> LogStr) -> IO () -- | Logger Type. @@ -194,6 +207,11 @@ -- 'BufSize' is a buffer size -- for each capability. -- File rotation is done on-demand. + | LogFileTimedRotate TimedFileLogSpec BufSize -- ^ Logging to a file. + -- 'BufSize' is a buffer size + -- for each capability. + -- Rotation happens based on check specified + -- in 'TimedFileLogSpec'. | LogCallback (LogStr -> IO ()) (IO ()) -- ^ Logging with a log and flush action. -- run flush after log each message. @@ -201,12 +219,13 @@ -- a tuple of logger and clean up action are returned. newFastLogger :: LogType -> IO (FastLogger, IO ()) newFastLogger typ = case typ of - LogNone -> return (const noOp, noOp) - LogStdout bsize -> newStdoutLoggerSet bsize >>= stdLoggerInit - LogStderr bsize -> newStderrLoggerSet bsize >>= stdLoggerInit - LogFileNoRotate fp bsize -> newFileLoggerSet bsize fp >>= fileLoggerInit - LogFile fspec bsize -> rotateLoggerInit fspec bsize - LogCallback cb flush -> return (\str -> cb str >> flush, noOp) + LogNone -> return (const noOp, noOp) + LogStdout bsize -> newStdoutLoggerSet bsize >>= stdLoggerInit + LogStderr bsize -> newStderrLoggerSet bsize >>= stdLoggerInit + LogFileNoRotate fp bsize -> newFileLoggerSet bsize fp >>= fileLoggerInit + LogFile fspec bsize -> rotateLoggerInit fspec bsize + LogFileTimedRotate fspec bsize -> timedRotateLoggerInit fspec bsize + LogCallback cb flush -> return (\str -> cb str >> flush, noOp) where stdLoggerInit lgrset = return (pushLogStr lgrset, rmLoggerSet lgrset) fileLoggerInit lgrset = return (pushLogStr lgrset, rmLoggerSet lgrset) @@ -219,6 +238,18 @@ pushLogStr lgrset str when (cnt <= 0) $ tryRotate lgrset fspec ref mvar return (logger, rmLoggerSet lgrset) + timedRotateLoggerInit fspec bsize = do + cache <- newTimeCache $ timed_timefmt fspec + now <- cache + lgrset <- newFileLoggerSet bsize $ prefixTime now $ timed_log_file fspec + ref <- newIORef now + mvar <- newMVar lgrset + let logger str = do + ct <- cache + updated <- updateTime (timed_same_timeframe fspec) ref ct + when updated $ tryTimedRotate fspec ct mvar + pushLogStr lgrset str + return (logger, rmLoggerSet lgrset) -- | 'bracket' version of 'newFastLogger' withFastLogger :: LogType -> (FastLogger -> IO a) -> IO a @@ -231,12 +262,13 @@ -- "System.Log.FastLogger.Date" provide cached formatted time. -> LogType -> IO (TimedFastLogger, IO ()) newTimedFastLogger tgetter typ = case typ of - LogNone -> return (const noOp, noOp) - LogStdout bsize -> newStdoutLoggerSet bsize >>= stdLoggerInit - LogStderr bsize -> newStderrLoggerSet bsize >>= stdLoggerInit - LogFileNoRotate fp bsize -> newFileLoggerSet bsize fp >>= fileLoggerInit - LogFile fspec bsize -> rotateLoggerInit fspec bsize - LogCallback cb flush -> return (\f -> tgetter >>= cb . f >> flush, noOp) + LogNone -> return (const noOp, noOp) + LogStdout bsize -> newStdoutLoggerSet bsize >>= stdLoggerInit + LogStderr bsize -> newStderrLoggerSet bsize >>= stdLoggerInit + LogFileNoRotate fp bsize -> newFileLoggerSet bsize fp >>= fileLoggerInit + LogFile fspec bsize -> rotateLoggerInit fspec bsize + LogFileTimedRotate fspec bsize -> timedRotateLoggerInit fspec bsize + LogCallback cb flush -> return (\f -> tgetter >>= cb . f >> flush, noOp) where stdLoggerInit lgrset = return ( \f -> tgetter >>= pushLogStr lgrset . f, rmLoggerSet lgrset) fileLoggerInit lgrset = return (\f -> tgetter >>= pushLogStr lgrset . f, rmLoggerSet lgrset) @@ -250,6 +282,19 @@ pushLogStr lgrset (f t) when (cnt <= 0) $ tryRotate lgrset fspec ref mvar return (logger, rmLoggerSet lgrset) + timedRotateLoggerInit fspec bsize = do + cache <- newTimeCache $ timed_timefmt fspec + now <- cache + lgrset <- newFileLoggerSet bsize $ prefixTime now $ timed_log_file fspec + ref <- newIORef now + mvar <- newMVar lgrset + let logger f = do + ct <- cache + updated <- updateTime (timed_same_timeframe fspec) ref ct + when updated $ tryTimedRotate fspec ct mvar + t <- tgetter + pushLogStr lgrset (f t) + return (logger, rmLoggerSet lgrset) -- | 'bracket' version of 'newTimeFastLogger' withTimedFastLogger :: IO FormattedTime -> LogType -> (TimedFastLogger -> IO a) -> IO a @@ -263,6 +308,10 @@ decrease :: IORef Int -> IO Int decrease ref = atomicModifyIORef' ref (\x -> (x - 1, x - 1)) +-- updateTime returns whether the timeframe has changed +updateTime :: (FormattedTime -> FormattedTime -> Bool) -> IORef FormattedTime -> FormattedTime -> IO Bool +updateTime cmp ref newTime = atomicModifyIORef' ref (\x -> (newTime, not $ cmp x newTime)) + tryRotate :: LoggerSet -> FileLogSpec -> IORef Int -> MVar () -> IO () tryRotate lgrset spec ref mvar = bracket lock unlock rotateFiles where @@ -292,3 +341,17 @@ Just . fromIntegral <$> getFileSize file -- 200 is an ad-hoc value for the length of log line. estimate x = fromInteger (x `div` 200) + + +tryTimedRotate :: TimedFileLogSpec -> FormattedTime -> MVar LoggerSet -> IO () +tryTimedRotate spec now mvar = bracket lock unlock rotateFiles + where + lock = tryTakeMVar mvar + unlock Nothing = return () + unlock (Just (LoggerSet current_path a b c)) = do + putMVar mvar $ LoggerSet (Just new_file_path) a b c + forM_ current_path (timed_post_process spec) + rotateFiles Nothing = return () + rotateFiles (Just (LoggerSet _ a b c)) = renewLoggerSet $ LoggerSet (Just new_file_path) a b c + new_file_path = prefixTime now $ timed_log_file spec + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fast-logger-2.4.11/fast-logger.cabal new/fast-logger-2.4.13/fast-logger.cabal --- old/fast-logger-2.4.11/fast-logger.cabal 2018-02-05 03:01:32.000000000 +0100 +++ new/fast-logger-2.4.13/fast-logger.cabal 2018-12-25 03:45:26.000000000 +0100 @@ -1,5 +1,5 @@ Name: fast-logger -Version: 2.4.11 +Version: 2.4.13 Author: Kazu Yamamoto <kazu@iij.ad.jp> Maintainer: Kazu Yamamoto <kazu@iij.ad.jp> License: BSD3 @@ -10,13 +10,15 @@ Category: System Cabal-Version: >= 1.8 Build-Type: Simple -extra-source-files: README.md ChangeLog.md +Extra-Source-Files: README.md ChangeLog.md +Tested-With: GHC ==7.8.4 || ==7.10.3 || ==8.0.2 || ==8.2.2 || ==8.4.4 || ==8.6.3 Library GHC-Options: -Wall Exposed-Modules: System.Log.FastLogger System.Log.FastLogger.File System.Log.FastLogger.Date + System.Log.FastLogger.Types Other-Modules: System.Log.FastLogger.IO System.Log.FastLogger.FileIO System.Log.FastLogger.IORef @@ -30,16 +32,10 @@ , directory , filepath , text + , unix-time >= 0.4.4 + , unix-compat if impl(ghc < 7.8) Build-Depends: bytestring-builder - if os(windows) - Cpp-Options: -DWINDOWS - Build-Depends: time - , Win32 - , old-locale - else - Build-Depends: unix - , unix-time >= 0.2.2 Test-Suite spec Main-Is: Spec.hs