Add: merge by directory, Simplified: timeline merges

This commit is contained in:
Yoann La Cancellera
2023-09-01 16:58:41 +02:00
parent e03fe1801c
commit 5bbb11df17
2 changed files with 36 additions and 25 deletions

View File

@@ -32,6 +32,7 @@ var CLI struct {
Verbosity types.Verbosity `type:"counter" short:"v" default:"1" help:"-v: Detailed (default), -vv: DebugMySQL (add every mysql info the tool used), -vvv: Debug (internal tool debug)"` Verbosity types.Verbosity `type:"counter" short:"v" default:"1" help:"-v: Detailed (default), -vv: DebugMySQL (add every mysql info the tool used), -vvv: Debug (internal tool debug)"`
PxcOperator bool `default:"false" help:"Analyze logs from Percona PXC operator. Off by default because it negatively impacts performance for non-k8s setups"` PxcOperator bool `default:"false" help:"Analyze logs from Percona PXC operator. Off by default because it negatively impacts performance for non-k8s setups"`
ExcludeRegexes []string `help:"Remove regexes from analysis. List regexes using 'pt-galera-log-explainer regex-list'"` ExcludeRegexes []string `help:"Remove regexes from analysis. List regexes using 'pt-galera-log-explainer regex-list'"`
MergeByDirectory bool `help:"Instead of relying on identification, merge contexts and columns by base directory. Very useful when dealing with many small logs organized per directories."`
List list `cmd:""` List list `cmd:""`
Whois whois `cmd:""` Whois whois `cmd:""`
@@ -92,29 +93,17 @@ func timelineFromPaths(paths []string, toCheck types.RegexMap, since, until *tim
found = true found = true
extr.logger.Debug().Str("path", path).Msg("Finished searching") extr.logger.Debug().Str("path", path).Msg("Finished searching")
// identify the node with the easiest to read information
// this is critical part to aggregate logs: this is what enable to merge logs
// ultimately the "identifier" will be used for columns header
var node string
if CLI.PxcOperator {
node = path
} else {
// Why it should not just identify using the file path: // Why it should not just identify using the file path:
// so that we are able to merge files that belong to the same nodes // so that we are able to merge files that belong to the same nodes
// we wouldn't want them to be shown as from different nodes // we wouldn't want them to be shown as from different nodes
node = types.Identifier(localTimeline[len(localTimeline)-1].Ctx) if CLI.PxcOperator {
if t, ok := timeline[node]; ok { timeline[path] = localTimeline
} else if CLI.MergeByDirectory {
extr.logger.Debug().Str("path", path).Str("node", node).Msg("Merging with existing timeline") timeline.MergeByDirectory(path, localTimeline)
localTimeline = types.MergeTimeline(t, localTimeline) } else {
timeline.MergeByIdentifier(localTimeline)
} }
} }
extr.logger.Debug().Str("path", path).Str("node", node).Msg("Storing timeline")
timeline[node] = localTimeline
}
if !found { if !found {
return nil, errors.New("Could not find data") return nil, errors.New("Could not find data")
} }

View File

@@ -2,6 +2,7 @@ package types
import ( import (
"math" "math"
"path/filepath"
"time" "time"
) )
@@ -26,6 +27,27 @@ func (lt LocalTimeline) Add(li LogInfo) LocalTimeline {
// "string" key is a node IP // "string" key is a node IP
type Timeline map[string]LocalTimeline type Timeline map[string]LocalTimeline
func (timeline Timeline) MergeByIdentifier(lt LocalTimeline) {
// identify the node with the easiest to read information
// this is critical part to aggregate logs: this is what enable to merge logs
// ultimately the "identifier" will be used for columns header
node := Identifier(lt[len(lt)-1].Ctx)
if lt2, ok := timeline[node]; ok {
lt = MergeTimeline(lt2, lt)
}
timeline[node] = lt
}
func (timeline Timeline) MergeByDirectory(path string, lt LocalTimeline) {
node := filepath.Base(filepath.Dir(path))
for _, lt2 := range timeline {
if len(lt2) > 0 && node == filepath.Base(filepath.Dir(lt2[0].Ctx.FilePath)) {
lt = MergeTimeline(lt2, lt)
}
}
timeline[node] = lt
}
// MergeTimeline is helpful when log files are split by date, it can be useful to be able to merge content // MergeTimeline is helpful when log files are split by date, it can be useful to be able to merge content
// a "timeline" come from a log file. Log files that came from some node should not never have overlapping dates // a "timeline" come from a log file. Log files that came from some node should not never have overlapping dates
func MergeTimeline(t1, t2 LocalTimeline) LocalTimeline { func MergeTimeline(t1, t2 LocalTimeline) LocalTimeline {