-
Notifications
You must be signed in to change notification settings - Fork 39
/
Copy pathcollector.go
executable file
·185 lines (160 loc) · 7.68 KB
/
collector.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
package collector
import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/common/version"
)
const (
namespace = "artifactory"
)
var (
defaultLabelNames = []string{"node_id"}
filestoreLabelNames = append([]string{"storage_type", "storage_dir"}, defaultLabelNames...)
repoLabelNames = append([]string{"name", "type", "package_type"}, defaultLabelNames...)
replicationLabelNames = append([]string{"name", "type", "url", "cron_exp", "status"}, defaultLabelNames...)
federationLabelNames = append([]string{"name", "remote_url", "remote_name"}, defaultLabelNames...)
certificateLabelNames = append([]string{"alias", "issued_by", "expires"}, defaultLabelNames...)
)
func newMetric(metricName string, subsystem string, docString string, labelNames []string) *prometheus.Desc {
return prometheus.NewDesc(prometheus.BuildFQName(namespace, subsystem, metricName), docString, labelNames, nil)
}
type metrics map[string]*prometheus.Desc
var (
replicationMetrics = metrics{
"enabled": newMetric("enabled", "replication", "Replication status for an Artifactory repository (1 = enabled).", replicationLabelNames),
}
securityMetrics = metrics{
"users": newMetric("users", "security", "Number of Artifactory users for each realm.", append([]string{"realm"}, defaultLabelNames...)),
"groups": newMetric("groups", "security", "Number of Artifactory groups", defaultLabelNames),
"certificates": newMetric("certificates", "security", "Internal SSL certificate information, seconds to expiration as value", certificateLabelNames),
}
storageMetrics = metrics{
"artifacts": newMetric("artifacts", "storage", "Total artifacts count stored in Artifactory.", defaultLabelNames),
"artifactsSize": newMetric("artifacts_size_bytes", "storage", "Total artifacts Size stored in Artifactory in bytes.", defaultLabelNames),
"binaries": newMetric("binaries", "storage", "Total binaries count stored in Artifactory.", defaultLabelNames),
"binariesSize": newMetric("binaries_size_bytes", "storage", "Total binaries Size stored in Artifactory in bytes.", defaultLabelNames),
"filestore": newMetric("filestore_bytes", "storage", "Total available space in the file store in bytes.", filestoreLabelNames),
"filestoreUsed": newMetric("filestore_used_bytes", "storage", "Used space in the file store in bytes.", filestoreLabelNames),
"filestoreFree": newMetric("filestore_free_bytes", "storage", "Free space in the file store in bytes.", filestoreLabelNames),
"repoUsed": newMetric("repo_used_bytes", "storage", "Used space by an Artifactory repository in bytes.", repoLabelNames),
"repoFolders": newMetric("repo_folders", "storage", "Number of folders in an Artifactory repository.", repoLabelNames),
"repoFiles": newMetric("repo_files", "storage", "Number files in an Artifactory repository.", repoLabelNames),
"repoItems": newMetric("repo_items", "storage", "Number Items in an Artifactory repository.", repoLabelNames),
"repoPercentage": newMetric("repo_percentage", "storage", "Percentage of space used by an Artifactory repository.", repoLabelNames),
}
systemMetrics = metrics{
"healthy": newMetric("healthy", "system", "Is Artifactory working properly (1 = healthy).", defaultLabelNames),
"version": newMetric("version", "system", "Version and revision of Artifactory as labels.", append([]string{"version", "revision"}, defaultLabelNames...)),
"license": newMetric("license", "system", "License type and expiry as labels, seconds to expiration as value", append([]string{"type", "licensed_to", "expires"}, defaultLabelNames...)),
"licenses": newMetric("licenses", "system", "License type and expiry as labels, seconds to expiration as value", append([]string{"type", "valid_through", "licensed_to", "node_url", "license_hash", "expires"}, defaultLabelNames...)),
}
artifactsMetrics = metrics{
"created1m": newMetric("created_1m", "artifacts", "Number of artifacts created in the repository in the last 1 minute.", repoLabelNames),
"created5m": newMetric("created_5m", "artifacts", "Number of artifacts created in the repository in the last 5 minutes.", repoLabelNames),
"created15m": newMetric("created_15m", "artifacts", "Number of artifacts created in the repository in the last 15 minutes.", repoLabelNames),
"downloaded1m": newMetric("downloaded_1m", "artifacts", "Number of artifacts downloaded from the repository in the last 1 minute.", repoLabelNames),
"downloaded5m": newMetric("downloaded_5m", "artifacts", "Number of artifacts downloaded from the repository in the last 5 minutes.", repoLabelNames),
"downloaded15m": newMetric("downloaded_15m", "artifacts", "Number of artifacts downloaded from the repository in the last 15 minutes.", repoLabelNames),
}
federationMetrics = metrics{
"mirrorLag": newMetric("mirror_lag", "federation", "Federation mirror lag in milliseconds.", federationLabelNames),
"unavailableMirror": newMetric("unavailable_mirror", "federation", "Unsynchronized federated mirror status", append([]string{"status"}, federationLabelNames...)),
}
openMetrics = metrics{
"openMetrics": newMetric("open_metrics", "openmetrics", "OpenMetrics proxied from JFrog Platform", defaultLabelNames),
}
)
func init() {
prometheus.MustRegister(version.NewCollector("artifactory_exporter"))
}
// Describe describes all the metrics ever exported by the Artifactory exporter. It
// implements prometheus.Collector.
func (e *Exporter) Describe(ch chan<- *prometheus.Desc) {
for _, m := range replicationMetrics {
ch <- m
}
for _, m := range securityMetrics {
ch <- m
}
for _, m := range storageMetrics {
ch <- m
}
for _, m := range systemMetrics {
ch <- m
}
if e.optionalMetrics.Artifacts {
for _, m := range artifactsMetrics {
ch <- m
}
}
if e.optionalMetrics.FederationStatus {
for _, m := range federationMetrics {
ch <- m
}
}
if e.optionalMetrics.OpenMetrics {
for _, m := range openMetrics {
ch <- m
}
}
ch <- e.up.Desc()
ch <- e.totalScrapes.Desc()
ch <- e.totalAPIErrors.Desc()
ch <- e.jsonParseFailures.Desc()
}
// Collect fetches the stats from Artifactory and delivers them
// as Prometheus metrics. It implements prometheus.Collector.
func (e *Exporter) Collect(ch chan<- prometheus.Metric) {
e.mutex.Lock() // To protect metrics from concurrent collects.
defer e.mutex.Unlock()
up := e.scrape(ch)
ch <- e.up
e.up.Set(up)
ch <- e.totalScrapes
ch <- e.totalAPIErrors
ch <- e.jsonParseFailures
}
func (e *Exporter) scrape(ch chan<- prometheus.Metric) (up float64) {
e.totalScrapes.Inc()
// Collect and export open metrics
if e.optionalMetrics.OpenMetrics {
err := e.exportOpenMetrics(ch)
if err != nil {
return 0
}
}
// Collect and export system metrics
if err := e.exportSystem(ch); err != nil {
return 0
}
// Collect and export system HA licenses metrics
if err := e.exportSystemHALicenses(ch); err != nil {
return 0
}
// Fetch Storage Info stats and register them
storageInfo, err := e.client.FetchStorageInfo()
if err != nil {
e.totalAPIErrors.Inc()
return 0
}
e.exportStorage(storageInfo, ch)
// Extract repo summaries from storageInfo and register them
repoSummaryList, err := e.extractRepo(storageInfo)
if err != nil {
return 0
}
e.exportRepo(repoSummaryList, ch)
// Get Downloaded and Created items for all repo in the last 1 and 5 minutes and add it to repoSummaryList
if e.optionalMetrics.Artifacts {
repoSummaryList, err := e.getTotalArtifacts(repoSummaryList)
if err != nil {
return 0
}
e.exportArtifacts(repoSummaryList, ch)
}
// Get Federation Mirror metrics
if e.optionalMetrics.FederationStatus && e.client.IsFederationEnabled() {
e.exportFederationMirrorLags(ch)
e.exportFederationUnavailableMirrors(ch)
}
return 1
}