forked from kata-containers/kata-containers
-
Notifications
You must be signed in to change notification settings - Fork 0
/
display.go
153 lines (124 loc) · 3.56 KB
/
display.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
//
// 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)
}