Files
kata-containers/src/tools/log-parser/display.go
Snir Sheriber c7dacb1211 log-parser: move the kata-log-parser from the tests repo
to the kata-containers repo under the src/tools/log-parser folder
and vendor the modules

Fixes: #4100
Signed-off-by: Snir Sheriber <ssheribe@redhat.com>
2022-05-10 13:23:25 +03:00

154 lines
3.6 KiB
Go

//
// Copyright (c) 2017-2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
package main
import (
"fmt"
"io"
"os"
"sort"
"strings"
"text/template"
)
// headerTemplate is used by addCommentHeader().
const headerTemplate = `
#----------------------------------------
# Name: {{.name}}
# Version: {{.version}}
# Commit: {{.commit}}
# Fields: {{.fields}}
# Format Version: {{.formatVersion}}
#----------------------------------------
`
var (
// displayPrefix specifies a display prefix value
displayPrefix = ""
// displayIndentValue specifies a space-indent value
displayIndentValue = strings.Repeat(" ", 4)
)
// displayHandler is an interface that all output display handlers
// (formatters) must implement.
type displayHandler interface {
// Display must write the log entries to the specified file. If the
// format supports it, fieldNames can be added to the output.
Display(entries *LogEntries, fieldNames []string, file *os.File) error
}
// DisplayHandlers encapsulates the list of available display handlers.
type DisplayHandlers struct {
handlers map[string]displayHandler
}
// handlers is a map of the available output format display handling
// implementations.
var handlers = map[string]displayHandler{
"csv": &displayCSV{},
"json": &displayJSON{},
"text": &displayText{},
"toml": &displayTOML{},
"xml": &displayXML{},
"yaml": &displayYAML{},
}
// NewDisplayHandlers create a new displayHandler.
func NewDisplayHandlers() *DisplayHandlers {
h := &DisplayHandlers{
handlers: handlers,
}
return h
}
// find looks for a display handler corresponding to the specified format
func (d *DisplayHandlers) find(format string) displayHandler {
for f, handler := range d.handlers {
if f == format {
return handler
}
}
return nil
}
// supplementEntries sets extra fields in the list of log entries
func (d *DisplayHandlers) supplementEntries(entries *LogEntries) {
records := uint64(len(entries.Entries))
var i uint64
for i = 0; i < records; i++ {
this := &entries.Entries[i]
this.Count = 1 + i
if i > 0 {
// only calculate time difference for 2nd and
// subsequent records as the first record doesn't have
// a record before it :)
prev := &entries.Entries[i-1]
this.TimeDelta = NewTimeDelta(this.Time.Sub(prev.Time))
}
}
}
// Handle adds the record count and timedeltas to the records and then calls
// the display handler.
//
// Note: The LogEntries are assumed to have already been sorted by
// LogEntry.Time.
func (d *DisplayHandlers) Handle(entries *LogEntries, format string, file *os.File) (err error) {
handler := d.find(format)
if handler == nil {
return fmt.Errorf("no display handler for %v", format)
}
d.supplementEntries(entries)
le := LogEntry{}
fieldNames := le.Fields()
return handler.Display(entries, fieldNames, file)
}
// Get returns a list of the available formatters (display handler names).
func (d *DisplayHandlers) Get() []string {
var formats []string
for f := range d.handlers {
formats = append(formats, f)
}
sort.Strings(formats)
return formats
}
// addCommentHeader can be used to add a header containing some metadata
// for those format that support "#" comments.
func addCommentHeader(fieldNames []string, writer io.Writer) error {
t := template.New("")
t, err := t.Parse(headerTemplate)
if err != nil {
return err
}
args := map[string]string{
"name": name,
"version": version,
"commit": commit,
"fields": strings.Join(fieldNames, ","),
"formatVersion": logEntryFormatVersion,
}
return t.Execute(writer, args)
}