haskell - 如何(有效地)使用 Haskell 跟踪/跟踪文件,包括检测文件旋转? (尾-F)

标签 haskell

本质上我想知道如何实现tail -F Haskell 中的 Linux 命令功能。我的目标是跟踪一个日志文件,例如一个 Web 服务器日志文件,并通过解析输入来计算各种实时统计数据。理想情况下,如果日志文件使用 logrotate 进行轮换,则不会出现中断。或类似的服务。

我对如何解决这个问题以及在存在惰性 I/O 的情况下应该考虑什么性能感到有些不知所措。任何流媒体库都与这里相关吗?

最佳答案

这是部分答案,因为它不处理 logrotate 的文件截断。 .它避免了惰性 I/O 并使用 bytestring , streaming , streaming-bytestringhinotify包。

一些初步进口:

{-# language OverloadedStrings #-}
module Main where

import qualified Data.ByteString
import Data.ByteString.Lazy.Internal (defaultChunkSize)
import qualified Data.ByteString.Streaming as B
import Streaming
import qualified Streaming.Prelude as S
import Control.Concurrent.QSem
import System.INotify
import System.IO (withFile,IOMode(ReadMode))
import System.Environment (getArgs)

这是“拖尾”功能:
tailing :: FilePath -> (B.ByteString IO () -> IO r) -> IO r
tailing filepath continuation = withINotify $ \i -> do
    sem <- newQSem 1
    addWatch i [Modify] filepath (\_ -> signalQSem sem)
    withFile filepath ReadMode (\h -> continuation (handleToStream sem h))
    where
    handleToStream sem h = B.concat . Streaming.repeats $ do
        lift (waitQSem sem)
        readWithoutClosing h
    -- Can't use B.fromHandle here because annoyingly it closes handle on EOF
    -- instead of just returning, and this causes problems on new appends.
    readWithoutClosing h = do
        c <- lift (Data.ByteString.hGetSome h defaultChunkSize)
        if Data.ByteString.null c
           then return ()
           else do B.chunk c
                   readWithoutClosing h

它需要一个文件路径和一个使用流式字节串的回调。

这个想法是,每次从句柄读取直到 EOF 之前,我们都会减少一个信号量,该信号量仅由文件修改时调用的回调增加。

我们可以像这样测试函数:
main :: IO ()
main = do
    filepath : _ <- getArgs
    tailing filepath B.stdout

关于haskell - 如何(有效地)使用 Haskell 跟踪/跟踪文件,包括检测文件旋转? (尾-F),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41230293/

相关文章:

haskell - 数据种类的问题

haskell - 在 Haskell 中检查 3 个列表中的公共(public)整数的最有效方法

macos - Haskell 中 OpenGL+GLUT 的 Hello World 不适用于 OSX Lion

haskell - 报告所有错误的类序列函数

haskell - 无法使用 "foreign"指针使 C2HS 工作

haskell - 如何在 Haskell 中比较非 'Eq' 类型?

haskell - haskell 中的类型类依赖和 OOP 中的子类型有什么区别?

performance - 创建集合中所有元素对的 Data.Set 的最有效方法是什么?

haskell - 不能在 IO 上下文中使用 state monad

haskell - 如何正确关闭与网络管道的网络连接?