草庐IT

go - 中断当前的尾部并开始新的尾部

coder 2024-07-10 原文

所以我在 golang 中创建了一些日志分析器,我需要的是新创建文件的实时 tail -f。

我正在使用 tail 包和 fsnotify 包,但我不太熟悉 go 中的 channel 和例程,所以我需要一些帮助。

目前程序是这样的:

package main

import(
    "fmt"
    "github.com/hpcloud/tail"
    "strings"
    "log"
    "net/smtp"
    "time"
    "github.com/fsnotify/fsnotify"
)

//this function needs to monitor for new files in directory
func newFileCheck() (newFilename chan string, err error) {
    watcher, err := fsnotify.NewWatcher()
    if err != nil {
        return
    }

    err = watcher.Add("myDir")
    if err != nil {
        return
    }

    newFilename = make(chan string)

    // Process events
    go func() {
        for {
            select {
            case ev := <-watcher.Events:
                log.Println("event:", ev)
                newFilename <- ev.Name // Relative path to the file
                //t.Stop() //if I pass reference to t THIS IS NOT HAPPENING ?
            case err := <-watcher.Errors:
                log.Println("error:", err)
            }
        }
    }()

    return
}

func main() {
    newFileName = "mylog_0000.log.txt"

    fmt.Println("Processing log: ",newFileName)

    newFilenameChan, err := newFileCheck()
    if err != nil {
        fmt.Println("ERR: ",err)
    }

    t := tailLog(newFileName)

    go func() {
        for {
            select {
                case name := <-newFilenameChan:
                    fmt.Println("New file created: ",name) //this will be printed only once and then on new events nothing is printed ?

                //NONE of the lines abowe doesn't work
                t.Stop()
                t.Dead()
                t.Done()

                t = tailLog(name)
            }
        }
    }()
}

func tailLog(fileName string) *tail.Tail{
    var count = 0
    // close the old one and read new file
    t, err := tail.TailFile("/mydir/"+fileName, tail.Config{Follow: true, ReOpen: true})

    for line := range t.Lines {
        //fmt.Println("Line is:", line.Text)

        //check do we have what we need
        if strings.Contains(strings.ToLower(line.Text), "mfc"){

            count++
            //do other stuff
        }
    }

    fmt.Println(err)

    return t
}

所以我不明白为什么 newFileCheck 函数只在第一次打印事件,而且我也不知道如何在新事件发生时取消事件尾部,然后在该事件发生后再次开始尾部?

最佳答案

考虑一下:

When the function main returns, the program exits. It does not wait for other (non-main) goroutines to complete.

然后查看您的代码块:

func main() {
    newFileName = "mylog_0000.log.txt"

    fmt.Println("Processing log: ",newFileName)

    newFilenameChan, err := newFileCheck()
    if err != nil {
        fmt.Println("ERR: ",err)
    }

    t := tailLog(newFileName)

    go func() {
        for {
            select {
                case name := <-newFilenameChan:
                    fmt.Println("New file created: ",name) //this will be printed only once and then on new events nothing is printed ?

                //NONE of the lines abowe doesn't work
                t.Stop()
                t.Dead()
                t.Done()

                t = tailLog(name)
            }
        }
    }()
}

要优雅地处理这项工作,您应该了解更多关于 Golang 中的并发性。如果您对执行/完成任务的顺序感兴趣,请使用 channel 来控制 goroutine,例如停止/启动/等和 WaitGroup。当无法控制您的程序流程时,goroutines 可以过自己的生活,这是不好的做法。

关于go - 中断当前的尾部并开始新的尾部,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41243206/

有关go - 中断当前的尾部并开始新的尾部的更多相关文章

  1. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  2. ruby-on-rails - 如何在发布新的 Ruby 或 Rails 版本时收到通知? - 2

    有人知道在发布新版本的Ruby和Rails时收到电子邮件的方法吗?他们有邮件列表,RubyonRails有一个推特,但我不想听到那些随之而来的喧嚣,我只想知道什么时候发布新版本,尤其是那些有安全修复的版本。 最佳答案 从therailsblog获取提要.http://weblog.rubyonrails.org/feed/atom.xml 关于ruby-on-rails-如何在发布新的Ruby或Rails版本时收到通知?,我们在StackOverflow上找到一个类似的问题:

  3. Observability:从零开始创建 Java 微服务并监控它 (二) - 2

    这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/

  4. ruby - 如何找到调用当前方法的方法 - 2

    如何找到调用此方法的位置?defto_xml(options={})binding.pryoptions=options.to_hifoptions&&options.respond_to?(:to_h)serializable_hash(options).to_xml(options)end 最佳答案 键入caller。这将返回当前调用堆栈。文档:Kernel#caller.例子[0]%rspecspec10/16|===================================================62=====

  5. ruby - ruby 乘法语句中星号中断语法前的空格 - 2

    在添加一些空格以使代码更具可读性时(与上面的代码对齐),我遇到了这个:classCdefx42endendm=C.new现在这将给出“错误数量的参数”:m.x*m.x这将给出“语法错误,意外的tSTAR,期待$end”:2/m.x*m.x这里的解析器到底发生了什么?我使用Ruby1.9.2和2.1.5进行了测试。 最佳答案 *用于运算符(42*42)和参数解包(myfun*[42,42])。当你这样做时:m.x*m.x2/m.x*m.xRuby将此解释为参数解包,而不是*运算符(即乘法)。如果您不熟悉它,参数解包(有时也称为“spl

  6. ruby - 在 ASP 页面上 Mechanize 中断 - 2

    require'mechanize'agent=Mechanize.newlogin=agent.get('http://www.schoolnet.ch/DE/HomeDE.htm')agent.clicklogin.link_withtext:/Login/然后我得到Mechanize::UnsupportedSchemeError。 最佳答案 Mechanize不支持javascript但您可以将搜索字段添加到表单并为其分配搜索词并使用mechanize提交表单form=page.forms.firstform.add_fie

  7. ruby - 可以正常中断的来自 Rake 的长时间运行的 shell 命令? - 2

    在几个项目中,我希望有一个类似rakeserver的rake任务,它将通过任何需要的方式开始为该应用程序提供服务。这是一个示例:task:serverdo%x{bundleexecrackup-p1234}end这行得通,但是当我准备停止它时,按Ctrl+c并没有正常关闭;它中断了Rake任务本身,它说rakeaborted!并给出堆栈跟踪。在某些情况下,我必须执行Ctrl+c两次。我可能可以用Signal.trap写一些东西来更优雅地中断它。有没有更简单的方法? 最佳答案 trap('SIGINT'){puts"Yourmessa

  8. ruby - 以毫秒为单位获取当前系统时间 - 2

    在Ruby中,以毫秒为单位获取自纪元(1970)以来的当前系统时间的正确方法是什么?我试过了Time.now.to_i,好像不是我想要的结果。我需要结果显示毫秒并且使用long类型,而不是float或double。 最佳答案 (Time.now.to_f*1000).to_iTime.now.to_f显示包含十进制数字的时间。要获得毫秒数,只需将时间乘以1000。 关于ruby-以毫秒为单位获取当前系统时间,我们在StackOverflow上找到一个类似的问题:

  9. ruby - 需要重构为新的 Ruby 1.9 哈希语法 - 2

    这个问题在这里已经有了答案:HashsyntaxinRuby[duplicate](1个回答)关闭5年前。我有一个Recipe,其中包含以下未通过lint测试的代码:service'apache'dosupports:status=>true,:restart=>true,:reload=>trueend失败并出现错误:UsethenewRuby1.9hashsyntax.supports:status=>true,:restart=>true,:reload=>true不确定新语法是什么样的...有人可以帮忙吗?

  10. ruby-on-rails - prawnto 显示新页面时不会中断的表格 - 2

    我有可变数量的表格和可变数量的行,我想让它们一个接一个地显示,但如果表格不适合当前页面,请将其放在下一页,然后继续。我已将表格放入事务中,以便我可以回滚然后打印它(如果高度适合当前页面),但我如何获得表格高度?我现在有这段代码pdf.transactiondopdf.table@data,:font_size=>12,:border_style=>:grid,:horizontal_padding=>10,:vertical_padding=>3,:border_width=>2,:position=>:left,:row_colors=>["FFFFFF","DDDDDD"]pdf.

随机推荐