SoFunction
Updated on 2025-03-03

golang uses tail to track file changes

Introduction

With the help of/hpcloud/tail, can track file changes in real time, and achieve shell commands similar totail -feffect.

Sample code

The following sample code is used to read nginx in real timeLog files are output to the console after reading. If nginx logs are formatted with json, they can also parse the read content and process the logs more, such as writing log content to the database, making log alerts, etc. For systems with smaller visits, this does not require a lot of resources to build special log monitoring systems such as ELK and Loki.

package main
import (
	"flag"
	"fmt"
	"io"
	"os"
	"/hpcloud/tail"
)
var (
	logfile = ("f", "", "Log file path")
)
func main() {
	()
	// Determine whether the file exists	if _, err := (*logfile); (err) {
		("Error! %s not found\n", *logfile)
		(1)
	}
	// Don't start reading from the file, but start reading from the current end of the file	// It is recommended to use Go 1.20, the old version may need to be changed to os.SEEK_END	seek := &{Offset: 0, Whence: }
	t, err := (*logfile, {
		Follow:   true,
		Location: seek,
	})
	if err != nil {
		(err)
	}
	for line := range  {
		()
	}
}

Knowledge Supplement

1.Official Documentation

/hpcloud/tail usage introduction

address:/hpcloud/tail

The purpose of the tail command in Linux is to output the last part of the specified file to a standard device according to the requirements. It is usually a terminal. In layman's terms, it means displaying the last few lines of a certain archive file on the terminal. Assuming that the file is updated, tail will automatically refresh it to ensure that you see the latest archive content.

This package implements similar functionality.

t, err := ("/var/log/", {Follow: true})
if err != nil {
    (err)  //If the file does not exist, it will block and print Waiting for to appear... until the file is created}
for line := range  {
    ()
}

The () function enables goroutine to read the file and passes the contents in the channel format.

Other configuration items

type Config struct {
    // File-specifc
    Location    *SeekInfo // Specify the location to start reading    ReOpen      bool      //true, the file is deleted and blocked and waits for the new file to be created. If false, the program ends when the file is deleted, the program ends when the file is deleted.    MustExist   bool      // True, if the file is not found, the error will be reported and the end will be reported. If the file is not found, the file will be blocked and maintained. If the file is not found, the error will be blocked and maintained.    Poll        bool      // Using Linux's Poll function, the function of poll is to hang the current file pointer to the waiting queue    Pipe        bool      // Is a named pipe (mkfifo)
    RateLimiter *
    // Generic IO
    Follow      bool //true will block and listen to the specified file, false will end the program once you read it    MaxLineSize int  // If non-zero, split longer lines into multiple lines
    // Logger, when nil, is set to 
    // To disable logging: set field to 
    Logger logger
}

location similar, for example

seek := &{Offset:5,Whence:os.SEEK_CUR}
t, err := ("", {Location:seek})
offset //After Whence, then offset n characters and start reading. When the offset is greater than one line of content, the line break will continue to be calculated (the line break character\n calculation occupies two characters, but it is not printed out)SEEK_SET int = 0 // Skip to the start position of the fileSEEK_CUR int = 1 // Skip to the current location of the file (as if set to the start position)SEEK_END int = 2 // Jump to the end of the file,Do not read the original content in the file,Read from the new join

() Returns the current offset

This is the article about golang using tail to track file changes. For more related golang tail content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!