GoLang 追踪 UTF16LE 格式的 Windows 日志文件。

huangapple go评论68阅读模式
英文:

GoLang tailing UTF16LE windows log file

问题

我可以帮你将这两个 Golang 脚本合并起来以追踪一个 UTF16LEBOM 编码的活动日志。以下是你提供的代码的翻译:

// 编辑:几乎可以工作。看起来 utfutil 没有延迟关闭。

package main

import (
	"bufio"
	"fmt"
	"io"
	"time"

	"github.com/TomOnTime/utfutil"
)

func main() {
	logfilefile := "C:/Users/user/Documents/EVE/logs/Chatlogs/chat_20220709_022129_1006197774.txt"
	file, err := utfutil.OpenFile(logfilefile, utfutil.WINDOWS)
	if err != nil {
		return
	}

	defer file.Close()

	reader := bufio.NewReader(file)
	for {
		line, err := reader.ReadString('\n')
		if err != nil {
			if err == io.EOF {
				// 如果没有这个 sleep,会占用 CPU
				time.Sleep(500 * time.Millisecond)
				continue
			}

			break
		}

		fmt.Printf(string(line))
	}
}

这是一个结合了两个示例的代码。第一个示例是用于追踪文件的代码,你可以在这里找到:https://medium.com/@arunprabhu.1/tailing-a-file-in-golang-72944204f22b

第二个示例是用于读取文件并使其可读且没有额外字符的代码,你可以在这里找到:https://github.com/TomOnTime/utfutil/

你可以将这两个示例的代码合并起来,以便追踪一个 UTF16LEBOM 编码的活动日志,并在关键字 "die" 和 "prepare to die scumsucker!" 出现时进行标记。希望这可以帮到你!

英文:

How can I combine these two golang scripts to tail an active log that is UTF16LEBOM?

I am working on a log parser for a game (Eve Online). In the game chat logs can be saved, and I would like to use GoLang to read the running log and flag on keywords "die" in "prepare to die scumsucker!"

I've found two examples that work separately. Combining them is a challenge I've been unable to figure out. First tail equivalent here:
https://medium.com/@arunprabhu.1/tailing-a-file-in-golang-72944204f22b

Second reading the file so that is legible and doesn't have extra characters:
https://github.com/TomOnTime/utfutil/

I have been trying to replace the code from utfutil with the "equivalent" but it seems it is missing several functions.

// EDIT Almost working. It doesn't look like utfutil is defering the close.

package main

import (
	"bufio"
	"fmt"
	"io"
	"time"
	
    "github.com/TomOnTime/utfutil"
)

func main() {
	logfilefile := "C:/Users/user/Documents/EVE/logs/Chatlogs/chat_20220709_022129_1006197774.txt"
	file, err := utfutil.OpenFile(logfilefile, utfutil.WINDOWS)
	if err != nil {
		return
	}

	defer file.Close()

	reader := bufio.NewReader(file)
	for {
		line, err := reader.ReadString('\n')
		if err != nil {
			if err == io.EOF {
				// without this sleep you would hogg the CPU
				time.Sleep(500 * time.Millisecond)
				continue
			}

			break
		}

		fmt.Printf(string(line))
	}
}
<cut white space>
        ---------------------------------------------------------------

          Channel ID:      local
          Channel Name:    Local
          Listener:        Steve
          Session started: 2022.07.07 16:18:21
        ---------------------------------------------------------------

[ 2022.07.07 17:11:44 ] Steve > hello world
[ 2022.07.07 17:11:48 ] John > hello world
[ 2022.07.07 17:11:51 ] James > hello world
[ 2022.07.07 19:36:53 ] Bob > hello world

答案1

得分: 1

你可以通过删除github.com/TomOnTime/utfutil来简化你的代码(这只是对golang.org/x/text/encoding/unicode的一个非常薄的封装)。此外,通常将任务链接起来比尝试一次性完成所有任务更简单;在这里,我从这个答案中借用了tailReader(稍作修改)。

注意:我只是快速测试了下面的代码(并且手头没有一个“Eve Online”日志文件)

package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"time"

	"golang.org/x/text/encoding/unicode"
)

func main() {
	file, err := newTailReader("./Local_20220707_170827_1006197774.txt")
	if err != nil {
		return
	}
	defer file.Close()

	utf := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM)
	reader := bufio.NewReader(utf.NewDecoder().Reader(file))

	for {
		line, err := reader.ReadString('\n')
		if err != nil {
			fmt.Println(err)
			break
		}

		fmt.Printf(string(line))
	}

}

// 从 https://stackoverflow.com/a/31122253/11810946 复制的代码
// 并修改为在开始“tail”之前输出文件内容
type tailReader struct {
	io.ReadCloser
}

func (t tailReader) Read(b []byte) (int, error) {
	for {
		n, err := t.ReadCloser.Read(b)
		if n > 0 {
			return n, nil
		} else if err != io.EOF {
			return n, err
		}
		time.Sleep(10 * time.Millisecond)
	}
}

func newTailReader(fileName string) (tailReader, error) {
	f, err := os.Open(fileName)
	if err != nil {
		return tailReader{}, err
	}
	return tailReader{f}, nil
}
英文:

You can simplify your code by removing github.com/TomOnTime/utfutil (this is a very thin wrapper over golang.org/x/text/encoding/unicode). It's also often simpler to chain tasks rather than trying to do everything at once; here I'm borrowing tailReader (with a minor change) from this answer.

Note: I have only tested the below very quickly (and don't have an "Eve Online" logfile to hand).

package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"time"

	"golang.org/x/text/encoding/unicode"
)

func main() {
	file, err := newTailReader("./Local_20220707_170827_1006197774.txt")
	if err != nil {
		return
	}
	defer file.Close()

	utf := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM)
	reader := bufio.NewReader(utf.NewDecoder().Reader(file))

	for {
		line, err := reader.ReadString('\n')
		if err != nil {
			fmt.Println(err)
			break
		}

		fmt.Printf(string(line))
	}

}

// Code copied from https://stackoverflow.com/a/31122253/11810946
// and modified to output contents of file before beginning to 'tail'
type tailReader struct {
	io.ReadCloser
}

func (t tailReader) Read(b []byte) (int, error) {
	for {
		n, err := t.ReadCloser.Read(b)
		if n > 0 {
			return n, nil
		} else if err != io.EOF {
			return n, err
		}
		time.Sleep(10 * time.Millisecond)
	}
}

func newTailReader(fileName string) (tailReader, error) {
	f, err := os.Open(fileName)
	if err != nil {
		return tailReader{}, err
	}
	return tailReader{f}, nil
}

huangapple
  • 本文由 发表于 2022年7月8日 12:41:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/72906721.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定