Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tool to deserialize alertmanager state file #20

Merged
merged 2 commits into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ chunktool: cmd/chunktool/chunktool
logtool: cmd/logtool/logtool
e2ealerting: cmd/e2ealerting/e2ealerting
blockscopy: cmd/blockscopy/blockscopy
deserializer: cmd/deserializer/deserializer

benchtool-image:
$(SUDO) docker build -t $(IMAGE_PREFIX)/benchtool -f cmd/benchtool/Dockerfile .
Expand Down Expand Up @@ -63,6 +64,9 @@ cmd/rules-migrator/rules-migrator: $(APP_GO_FILES) cmd/rules-migrator/main.go
cmd/blockscopy/blockscopy: $(APP_GO_FILES) cmd/blockscopy/main.go
CGO_ENABLED=0 go build $(GO_FLAGS) -o $@ ./$(@D)

cmd/deserializer/deserializer: $(APP_GO_FILES) cmd/deserializer/main.go
CGO_ENABLED=0 go build $(GO_FLAGS) -o $@ ./$(@D)

lint:
golangci-lint run -v

Expand All @@ -76,6 +80,7 @@ cross:
CGO_ENABLED=0 gox -output="dist/{{.Dir}}-{{.OS}}-{{.Arch}}" -ldflags=${LDFLAGS} -arch="amd64" -os="linux windows darwin" -osarch="darwin/arm64" ./cmd/logtool
CGO_ENABLED=0 gox -output="dist/{{.Dir}}-{{.OS}}-{{.Arch}}" -ldflags=${LDFLAGS} -arch="amd64" -os="linux windows darwin" -osarch="darwin/arm64" ./cmd/rules-migrator
CGO_ENABLED=0 gox -output="dist/{{.Dir}}-{{.OS}}-{{.Arch}}" -ldflags=${LDFLAGS} -arch="amd64" -os="linux windows darwin" -osarch="darwin/arm64" ./cmd/sim
CGO_ENABLED=0 gox -output="dist/{{.Dir}}-{{.OS}}-{{.Arch}}" -ldflags=${LDFLAGS} -arch="amd64" -os="linux windows darwin" -osarch="darwin/arm64" ./cmd/deserializer

test:
go test -mod=vendor -p=8 ./pkg/...
Expand All @@ -87,3 +92,4 @@ clean:
rm -rf cmd/logtool/logtool
rm -rf cmd/e2ealerting/e2ealerting
rm -rf cmd/blockscopy/blockscopy
rm -rf cmd/deserializer/deserializer
142 changes: 142 additions & 0 deletions cmd/deserializer/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package main

import (
"bytes"
"encoding/json"
"flag"
"fmt"
"io"
"log"
"os"
"strings"

"github.com/cortexproject/cortex/pkg/alertmanager/alertspb"
"github.com/gogo/protobuf/proto"
"github.com/matttproud/golang_protobuf_extensions/pbutil"
"github.com/prometheus/alertmanager/nflog/nflogpb"
"github.com/prometheus/alertmanager/silence/silencepb"
)

var (
out bytes.Buffer
outputFile string
intputFile string
)

func main() {
flag.CommandLine.StringVar(&intputFile, "file", "", "path of fullstate file to deserialize")
flag.CommandLine.StringVar(&outputFile, "output", "", "file for deserialized output")

flag.Parse()

if intputFile == "" {
log.Fatalf("No full state file specified.")
}

decodeFullState(intputFile)

outputToFile(outputFile)
}

func decodeFullState(path string) {
in, err := os.ReadFile(path)
if err != nil {
log.Fatalln("Error reading file:", err)
}
fs := alertspb.FullStateDesc{}
err = proto.Unmarshal(in, &fs)
if err != nil {
log.Fatalln("Error unmarshalling full state:", err)
}

for _, part := range fs.GetState().Parts {
out.WriteString("\n----\n")
if isNfLog(part.Key) {
parseNotifications(part.Data)
} else if isSilence(part.Key) {
parseSilences(part.Data)
} else {
out.WriteString(fmt.Sprintf("Unknown part type: %s", part.Key))
}

}
}

func parseNotifications(data []byte) {
out.WriteString("Alerts:\n")
r := bytes.NewReader(data)
for {
nf := nflogpb.MeshEntry{}
n, err := pbutil.ReadDelimited(r, &nf)
if err != nil && err != io.EOF {
log.Fatalf("unable to read alert notifications, %v", err)
}
if n == 0 || err == io.EOF {
break
}
result, err := json.Marshal(nf)
if err != nil {
log.Fatalf("unable to marshal to json, %v", err)
}
_, err = out.WriteString(string(result) + "\n")
if err != nil {
log.Fatalf("unable to write output, %v", err)
}
}
}

func parseSilences(data []byte) {
out.WriteString("Silences:\n")
r := bytes.NewReader(data)
for {
silence := silencepb.MeshSilence{}
n, err := pbutil.ReadDelimited(r, &silence)
if err != nil && err != io.EOF {
log.Fatalf("unable to read silences, %v", err)
}
if n == 0 || err == io.EOF {
break
}

result, err := json.Marshal(silence)
if err != nil {
log.Fatalf("unable to marshal to json, %v", err)
}

_, err = out.WriteString(string(result) + "\n")
if err != nil {
log.Fatalf("unable to write output, %v", err)
}
}
}

func outputToFile(file string) {
if outputFile == "" {
// write to stdout if output file not specified
fmt.Print(out.String())
return
}
fo, err := os.Create(file)
if err != nil {
panic(err)
}
// close fo on exit and check for its returned error
defer func() {
if err := fo.Close(); err != nil {
panic(err)
}
}()

_, err = fo.Write(out.Bytes())
if err != nil {
log.Fatalf("Failed writing output to file: %v", err)
}
}

func isNfLog(key string) bool {
return strings.HasPrefix(key, "nfl")
}

func isSilence(key string) bool {
return strings.HasPrefix(key, "sil")
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ require (
github.com/gorilla/mux v1.8.0
github.com/grafana-tools/sdk v0.0.0-20220203092117-edae16afa87b
github.com/grafana/dskit v0.0.0-20211021180445-3bd016e9d7f1
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db
github.com/oklog/ulid v1.3.1
github.com/opentracing-contrib/go-stdlib v1.0.0
Expand Down
1 change: 1 addition & 0 deletions vendor/modules.txt
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,7 @@ github.com/mattn/go-ieproxy
# github.com/mattn/go-isatty v0.0.14
github.com/mattn/go-isatty
# github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369
## explicit
github.com/matttproud/golang_protobuf_extensions/pbutil
# github.com/miekg/dns v1.1.48
github.com/miekg/dns
Expand Down
Loading