caddy-log-exporter/internal/server/tail.go

70 lines
1.4 KiB
Go
Raw Permalink Normal View History

2024-09-19 11:21:05 +02:00
package server
import (
"fmt"
"io"
"log/slog"
"github.com/VictoriaMetrics/metrics"
"github.com/nxadm/tail"
)
func (s *Server) Tail(f func(t *tail.Tail)) error {
for _, l := range s.logFiles {
t, err := tail.TailFile(l, tail.Config{
ReOpen: true,
Follow: true,
MustExist: true,
Location: &tail.SeekInfo{
Offset: 0,
Whence: io.SeekEnd, // Needed that it just uses new values
},
})
if err != nil {
return fmt.Errorf("tailing file: %w", err)
}
go f(t)
}
return nil
}
func parseFunc(t *tail.Tail) {
for line := range t.Lines {
l, err := ParseLog([]byte(line.Text))
if err != nil {
slog.Error("parsing log entry", "err", err)
continue
}
if len(l.Request.Headers.UserAgent) != 0 {
metrics.GetOrCreateCounter(
fmt.Sprintf(
`%s_http_request_total{host="%s", proto="%s", method="%s", status="%d", user_agent="%s"}`,
metricBaseName,
l.Request.Host,
l.Request.Proto,
l.Request.Method,
l.Status,
l.Request.Headers.UserAgent[0],
),
).Inc()
2024-09-19 11:21:05 +02:00
metrics.GetOrCreateHistogram(
fmt.Sprintf(
`%s_http_request_duration_seconds{host="%s", proto="%s", method="%s", status="%d"}`,
metricBaseName,
l.Request.Host,
l.Request.Proto,
l.Request.Method,
l.Status,
),
).Update(l.Duration)
} else {
slog.Warn("got empty user agent", "headers", l.Request.Headers)
}
2024-09-19 11:21:05 +02:00
}
}