Skip to content

Instantly share code, notes, and snippets.

@wheresalice
Last active September 21, 2024 09:16
Show Gist options
  • Save wheresalice/06e5653507ad7e05a80e911901f88ec8 to your computer and use it in GitHub Desktop.
Save wheresalice/06e5653507ad7e05a80e911901f88ec8 to your computer and use it in GitHub Desktop.
Playground for testing Promtail regexp expresssions and time parsing. You should only need to fiddle with the constants when running this locally, which is a lot easier and quicker feedback than updating promtail.yaml config files and waiting for logs to reach Loki
// playground for testing Promtail expressions and timestamp parsing
package main
import (
"fmt"
"time"
regexp "github.com/wasilibs/go-re2"
)
const logline = "2019-01-01T01:00:00.000000001Z stderr P i'm a log message!"
const expression = "^(?s)(?P<time>\\S+?) (?P<stream>stdout|stderr) (?P<flags>\\S+?) (?P<content>.*)$"
const timeformat = time.RFC3339Nano // other examples: https://grafana.com/docs/loki/latest/send-data/promtail/stages/timestamp/
// the rest of this you shouldn't need to edit
func main() {
matcher := regexp.MustCompile(expression)
var ts = ""
// Print logline
fmt.Println("Log line:")
fmt.Println("\t", logline)
// Print expression
fmt.Println("Expression:")
fmt.Println("\t", expression)
// Check if the logline matches the pattern
match := matcher.MatchString(logline)
fmt.Printf("Match found: %v\n", match)
// Get named matches
submatches := matcher.FindStringSubmatch(logline)
if len(submatches) > 0 {
fmt.Println("\nNamed Matches:")
for i, name := range matcher.SubexpNames() {
if name != "" && name != "0" {
fmt.Printf("\t%s: %s\n", name, submatches[i])
if name == "time" {
ts = submatches[i]
}
}
}
t, err := time.Parse(timeformat, ts)
if err != nil {
fmt.Println("Failed to parse 'time' field")
}
fmt.Println("Parsed time:", t)
} else {
fmt.Println("No matches found.")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment