This repository has been archived by the owner on Nov 14, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 33
/
gohai.go
186 lines (151 loc) · 4.25 KB
/
gohai.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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
// This file is licensed under the MIT License.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright © 2015 Kentaro Kuribayashi <kentarok@gmail.com>
// Copyright 2014-present Datadog, Inc.
// Package main contains the binary related functions,
// eg. cli parameters
package main
import (
"bytes"
"encoding/json"
"flag"
"fmt"
"os"
"sort"
"strings"
// 3p
log "github.com/cihub/seelog"
// project
"github.com/DataDog/gohai/cpu"
"github.com/DataDog/gohai/filesystem"
"github.com/DataDog/gohai/memory"
"github.com/DataDog/gohai/network"
"github.com/DataDog/gohai/platform"
"github.com/DataDog/gohai/processes"
)
// Collector represents a group of information which can be collected
type Collector interface {
Name() string
Collect() (interface{}, error)
}
// SelectedCollectors represents a set of collector names
type SelectedCollectors map[string]struct{}
var collectors = []Collector{
&cpu.Cpu{},
&filesystem.FileSystem{},
&memory.Memory{},
&network.Network{},
&platform.Platform{},
&processes.Processes{},
}
var options struct {
only SelectedCollectors
exclude SelectedCollectors
logLevel string
version bool
}
// version information filled in at build time
var (
buildDate string
gitCommit string
gitBranch string
goVersion string
)
// Collect fills the result map with the collector information under their name key
func Collect() (result map[string]interface{}, err error) {
result = make(map[string]interface{})
for _, collector := range collectors {
if shouldCollect(collector) {
c, err := collector.Collect()
if err != nil {
log.Warnf("[%s] %s", collector.Name(), err)
}
if c != nil {
result[collector.Name()] = c
}
}
}
result["gohai"] = versionMap()
return
}
func versionMap() (result map[string]interface{}) {
result = make(map[string]interface{})
result["git_hash"] = gitCommit
result["git_branch"] = gitBranch
result["build_date"] = buildDate
result["go_version"] = goVersion
return
}
func versionString() string {
var buf bytes.Buffer
if gitCommit != "" {
fmt.Fprintf(&buf, "Git hash: %s\n", gitCommit)
}
if gitBranch != "" {
fmt.Fprintf(&buf, "Git branch: %s\n", gitBranch)
}
if buildDate != "" {
fmt.Fprintf(&buf, "Build date: %s\n", buildDate)
}
if goVersion != "" {
fmt.Fprintf(&buf, "Go Version: %s\n", goVersion)
}
return buf.String()
}
// Implement the flag.Value interface
func (sc *SelectedCollectors) String() string {
collectorSlice := make([]string, 0, len(*sc))
for collectorName := range *sc {
collectorSlice = append(collectorSlice, collectorName)
}
sort.Strings(collectorSlice)
return fmt.Sprint(collectorSlice)
}
// Set adds the given comma-separated list of collector names to the selected set.
func (sc *SelectedCollectors) Set(value string) error {
for _, collectorName := range strings.Split(value, ",") {
(*sc)[collectorName] = struct{}{}
}
return nil
}
// Return whether we should collect on a given collector, depending on the parsed flags
func shouldCollect(collector Collector) bool {
if _, ok := options.only[collector.Name()]; len(options.only) > 0 && !ok {
return false
}
if _, ok := options.exclude[collector.Name()]; ok {
return false
}
return true
}
// Will be called after all the imported packages' init() have been called
// Define collector-specific flags in their packages' init() function
func init() {
options.only = make(SelectedCollectors)
options.exclude = make(SelectedCollectors)
flag.BoolVar(&options.version, "version", false, "Show version information and exit")
flag.Var(&options.only, "only", "Run only the listed collectors (comma-separated list of collector names)")
flag.Var(&options.exclude, "exclude", "Run all the collectors except those listed (comma-separated list of collector names)")
flag.StringVar(&options.logLevel, "log-level", "info", "Log level (one of 'warn', 'info', 'debug')")
}
func main() {
defer log.Flush()
flag.Parse()
err := initLogging(options.logLevel)
if err != nil {
panic(fmt.Sprintf("Unable to initialize logger: %s", err))
}
if options.version {
fmt.Printf("%s", versionString())
os.Exit(0)
}
gohai, err := Collect()
if err != nil {
panic(err)
}
buf, err := json.Marshal(gohai)
if err != nil {
panic(err)
}
os.Stdout.Write(buf)
}