所以我在 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/
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
有人知道在发布新版本的Ruby和Rails时收到电子邮件的方法吗?他们有邮件列表,RubyonRails有一个推特,但我不想听到那些随之而来的喧嚣,我只想知道什么时候发布新版本,尤其是那些有安全修复的版本。 最佳答案 从therailsblog获取提要.http://weblog.rubyonrails.org/feed/atom.xml 关于ruby-on-rails-如何在发布新的Ruby或Rails版本时收到通知?,我们在StackOverflow上找到一个类似的问题:
这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/
如何找到调用此方法的位置?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=====
在添加一些空格以使代码更具可读性时(与上面的代码对齐),我遇到了这个: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
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
在几个项目中,我希望有一个类似rakeserver的rake任务,它将通过任何需要的方式开始为该应用程序提供服务。这是一个示例:task:serverdo%x{bundleexecrackup-p1234}end这行得通,但是当我准备停止它时,按Ctrl+c并没有正常关闭;它中断了Rake任务本身,它说rakeaborted!并给出堆栈跟踪。在某些情况下,我必须执行Ctrl+c两次。我可能可以用Signal.trap写一些东西来更优雅地中断它。有没有更简单的方法? 最佳答案 trap('SIGINT'){puts"Yourmessa
在Ruby中,以毫秒为单位获取自纪元(1970)以来的当前系统时间的正确方法是什么?我试过了Time.now.to_i,好像不是我想要的结果。我需要结果显示毫秒并且使用long类型,而不是float或double。 最佳答案 (Time.now.to_f*1000).to_iTime.now.to_f显示包含十进制数字的时间。要获得毫秒数,只需将时间乘以1000。 关于ruby-以毫秒为单位获取当前系统时间,我们在StackOverflow上找到一个类似的问题:
这个问题在这里已经有了答案:HashsyntaxinRuby[duplicate](1个回答)关闭5年前。我有一个Recipe,其中包含以下未通过lint测试的代码:service'apache'dosupports:status=>true,:restart=>true,:reload=>trueend失败并出现错误:UsethenewRuby1.9hashsyntax.supports:status=>true,:restart=>true,:reload=>true不确定新语法是什么样的...有人可以帮忙吗?
我有可变数量的表格和可变数量的行,我想让它们一个接一个地显示,但如果表格不适合当前页面,请将其放在下一页,然后继续。我已将表格放入事务中,以便我可以回滚然后打印它(如果高度适合当前页面),但我如何获得表格高度?我现在有这段代码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.