Skip to content

Commit b6a4531

Browse files
committed
Introduce run metrics
1 parent 493f214 commit b6a4531

File tree

6 files changed

+104
-23
lines changed

6 files changed

+104
-23
lines changed

.golangci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,6 @@ linters:
4242
linters-settings:
4343
funlen:
4444
ignore-comments: true
45-
lines: 75
45+
lines: 80
4646
nestif:
4747
min-complexity: 5

internal/collection/collection.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package collection
33
import (
44
"archive/zip"
55
"bytes"
6+
"encoding/json"
67
"fmt"
78
"io"
89
"strings"
@@ -23,6 +24,7 @@ type Collection struct {
2324
JournalLoggingInterval string
2425
}
2526

27+
// New initializes new collection
2628
func New(w io.Writer) (c *Collection) {
2729
c = &Collection{
2830
Output: zip.NewWriter(w),
@@ -141,7 +143,22 @@ func (c *Collection) AddFileYAML(fileName string, data interface{}) {
141143
}
142144

143145
func (c *Collection) AddFileJSON(fileName string, data []byte) {
144-
c.AddFileDataRaw(fileName, data)
146+
var jsonData interface{}
147+
148+
err := json.Unmarshal(data, &jsonData)
149+
if err != nil {
150+
c.Log.Debugf("could not unmarshal JSON data for '%s': %s", fileName, err)
151+
}
152+
153+
prettyJSON, err := json.MarshalIndent(jsonData, "", "")
154+
if err != nil {
155+
c.Log.Debugf("could not marshal JSON data for '%s': %s", fileName, err)
156+
}
157+
158+
file := NewFile(fileName)
159+
file.Data = prettyJSON
160+
161+
_ = c.AddFileToOutput(file)
145162
}
146163

147164
func (c *Collection) AddFiles(prefix, source string) {

internal/metrics/metrics.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package metrics
2+
3+
import (
4+
"github.com/NETWAYS/support-collector/internal/obfuscate"
5+
"os"
6+
"strings"
7+
"time"
8+
)
9+
10+
type Metrics struct {
11+
Command string `json:"command"`
12+
Version string `json:"version"`
13+
Timings map[string]time.Duration `json:"timings"`
14+
}
15+
16+
// New creates new Metrics
17+
func New(version string) (m *Metrics) {
18+
return &Metrics{
19+
Command: getCommand(),
20+
Version: version,
21+
Timings: make(map[string]time.Duration),
22+
}
23+
}
24+
25+
// getCommand returns the executed command and obfusactes *--icinga2* arguments
26+
func getCommand() string {
27+
args := os.Args
28+
29+
// Obfuscate icinga 2 api user and password
30+
for i, arg := range args {
31+
if strings.Contains(arg, "--icinga2") && i+1 < len(args) {
32+
args[i+1] = obfuscate.Replacement
33+
}
34+
}
35+
36+
return strings.Join(args, " ")
37+
}

main.go

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package main
22

33
import (
4+
"encoding/json"
45
"fmt"
6+
"github.com/NETWAYS/support-collector/internal/metrics"
57
"os"
68
"path/filepath"
79
"strings"
@@ -111,6 +113,8 @@ var (
111113
outputFile string
112114
commandTimeout = 60 * time.Second
113115
noDetailedCollection bool
116+
startTime = time.Now()
117+
metric *metrics.Metrics
114118
)
115119

116120
func main() {
@@ -119,8 +123,21 @@ func main() {
119123
// set locale to C, to avoid translations in command output
120124
_ = os.Setenv("LANG", "C")
121125

122-
c, cleanup := NewCollection(outputFile)
123-
defer cleanup()
126+
c, closeCollection := NewCollection(outputFile)
127+
// close collection
128+
defer closeCollection()
129+
130+
// Initialize new metrics and defer function to save it to json
131+
metric = metrics.New(getVersion())
132+
defer func() {
133+
// Save metrics to file
134+
body, err := json.Marshal(metric)
135+
if err != nil {
136+
c.Log.Warn("cant unmarshal metrics: %w", err)
137+
}
138+
139+
c.AddFileJSON("metrics.json", body)
140+
}()
124141

125142
if noDetailedCollection {
126143
c.Detailed = false
@@ -133,38 +150,43 @@ func main() {
133150
c.Log.Warn("This tool should be run as a privileged user (root) to collect all necessary information")
134151
}
135152

136-
var (
137-
startTime = time.Now()
138-
timings = map[string]time.Duration{}
139-
)
140-
141153
// Set command Timeout from argument
142154
c.ExecTimeout = commandTimeout
143155

144-
// Call all enabled modules
156+
// Check if module is enabled / disabled and call it
145157
for _, name := range moduleOrder {
146158
switch {
147159
case util.StringInSlice(name, disabledModules):
148160
c.Log.Debugf("Module %s is disabled", name)
149161
case !util.StringInSlice(name, enabledModules):
150162
c.Log.Debugf("Module %s is not enabled", name)
151163
default:
164+
// Save current time
152165
moduleStart := time.Now()
153166

154167
c.Log.Debugf("Start collecting data for module %s", name)
155168

169+
// Register custom obfuscators
156170
for _, o := range extraObfuscators {
157171
c.Log.Debugf("Adding custom obfuscator for '%s' to module %s", o, name)
158172
c.RegisterObfuscator(obfuscate.NewAny(o))
159173
}
160174

175+
// Call collection function for module
161176
modules[name](c)
162177

163-
timings[name] = time.Since(moduleStart)
164-
c.Log.Debugf("Finished with module %s in %.3f seconds", name, timings[name].Seconds())
178+
// Save runtime of module
179+
metric.Timings[name] = time.Since(moduleStart)
180+
181+
c.Log.Debugf("Finished with module %s in %.3f seconds", name, metric.Timings[name].Seconds())
165182
}
166183
}
167184

185+
// Save overall timing
186+
metric.Timings["total"] = time.Since(startTime)
187+
188+
c.Log.Infof("Collection complete, took us %.3f seconds", metric.Timings["total"].Seconds())
189+
168190
// Collect obfuscation info
169191
var files, count uint
170192

@@ -178,12 +200,7 @@ func main() {
178200
c.Log.Infof("Obfuscation replaced %d token in %d files (%d definitions)", count, files, len(c.Obfuscators))
179201
}
180202

181-
// Save timings
182-
timings["total"] = time.Since(startTime)
183-
c.Log.Infof("Collection complete, took us %.3f seconds", timings["total"].Seconds())
184-
185-
c.AddFileYAML("timing.yml", timings)
186-
203+
// get absolute path of outputFile
187204
path, err := filepath.Abs(outputFile)
188205
if err != nil {
189206
c.Log.Debug(err)
@@ -224,7 +241,7 @@ func handleArguments() {
224241
flag.Parse()
225242

226243
if printVersion {
227-
fmt.Println(Product, "version", buildVersion()) //nolint:forbidigo
244+
fmt.Println(Product, "version", getBuildInfo()) //nolint:forbidigo
228245
os.Exit(0)
229246
}
230247

@@ -241,6 +258,9 @@ func buildFileName() string {
241258
return util.GetHostnameWithoutDomain() + "-" + FilePrefix + "-" + time.Now().Format("20060102-1504") + ".zip"
242259
}
243260

261+
// NewCollection starts a new collection. outputFile will be created.
262+
//
263+
// Collection and cleanup function to defer are returned
244264
func NewCollection(outputFile string) (*collection.Collection, func()) {
245265
file, err := os.Create(outputFile)
246266
if err != nil {
@@ -263,9 +283,8 @@ func NewCollection(outputFile string) (*collection.Collection, func()) {
263283
Level: consoleLevel,
264284
})
265285

266-
versionString := buildVersion()
286+
versionString := getBuildInfo()
267287
c.Log.Infof("Starting %s version %s", Product, versionString)
268-
c.AddFileDataRaw("version", []byte(versionString+"\n"))
269288

270289
return c, func() {
271290
// Close all open outputs in order, but only log errors

modules/icinga2/collector.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,12 @@ func Collect(c *collection.Collection) {
125125
}
126126

127127
// With Icinga 2 >= 2.14 the icinga2.debug cache is no longer built automatically on every reload. To retrieve a current state we build it manually (only possible from 2.14.0)
128+
// Needs to be done before commands are collected
128129
if icinga2version >= "2.14.0" {
129-
c.AddCommandOutput("dump-objects.txt", "icinga2", "daemon", "-C", "--dump-objects")
130+
_, err = collection.LoadCommandOutput("icinga2", "daemon", "-C", "--dump-objects")
131+
if err != nil {
132+
c.Log.Warn(err)
133+
}
130134
}
131135

132136
for name, cmd := range commands {

version.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ var (
1010
)
1111

1212
//goland:noinspection GoBoolExpressions
13-
func buildVersion() string {
13+
func getBuildInfo() string {
1414
result := version
1515

1616
if commit != "" {
@@ -23,3 +23,7 @@ func buildVersion() string {
2323

2424
return result
2525
}
26+
27+
func getVersion() string {
28+
return version
29+
}

0 commit comments

Comments
 (0)