diff --git a/cmd/acra-connector/prometheus.go b/cmd/acra-connector/prometheus.go index 76d72cb0c..bf1a1bf11 100644 --- a/cmd/acra-connector/prometheus.go +++ b/cmd/acra-connector/prometheus.go @@ -48,11 +48,11 @@ func registerMetrics() { registerLock.Do(func() { prometheus.MustRegister(connectionCounter) prometheus.MustRegister(connectionProcessingTimeHistogram) - cmd.RegisterVersionMetrics(ServiceName) version, err := utils.GetParsedVersion() if err != nil { panic(err) } - cmd.ExportVersionMetric(version) + cmd.RegisterVersionMetrics(ServiceName, version) + cmd.RegisterBuildInfoMetrics(ServiceName, utils.CommunityEdition) }) } diff --git a/cmd/acra-server/prometheus.go b/cmd/acra-server/prometheus.go index 82ba5298d..4d014d094 100644 --- a/cmd/acra-server/prometheus.go +++ b/cmd/acra-server/prometheus.go @@ -51,11 +51,11 @@ func registerMetrics() { prometheus.MustRegister(connectionProcessingTimeHistogram) base.RegisterAcraStructProcessingMetrics() base.RegisterDbProcessingMetrics() - cmd.RegisterVersionMetrics(ServiceName) version, err := utils.GetParsedVersion() if err != nil { panic(err) } - cmd.ExportVersionMetric(version) + cmd.RegisterVersionMetrics(ServiceName, version) + cmd.RegisterBuildInfoMetrics(ServiceName, utils.CommunityEdition) }) } diff --git a/cmd/acra-translator/prometheus.go b/cmd/acra-translator/prometheus.go index 8cbdc3d12..aed5476b7 100644 --- a/cmd/acra-translator/prometheus.go +++ b/cmd/acra-translator/prometheus.go @@ -52,11 +52,11 @@ func registerMetrics() { prometheus.MustRegister(connectionProcessingTimeHistogram) prometheus.MustRegister(common.RequestProcessingTimeHistogram) base.RegisterAcraStructProcessingMetrics() - cmd.RegisterVersionMetrics(ServiceName) version, err := utils.GetParsedVersion() if err != nil { panic(err) } - cmd.ExportVersionMetric(version) + cmd.RegisterVersionMetrics(ServiceName, version) + cmd.RegisterBuildInfoMetrics(ServiceName, utils.CommunityEdition) }) } diff --git a/cmd/prometheus.go b/cmd/prometheus.go index e6f764892..c79122a05 100644 --- a/cmd/prometheus.go +++ b/cmd/prometheus.go @@ -49,8 +49,6 @@ func RunPrometheusHTTPHandler(connectionString string) (net.Listener, *http.Serv return listener, server, nil } -var registerLock = sync.Once{} - // serviceNameToLabelFormat convert service name to lower case and remove all '_' // ex. Acra-Server will be changed to acraserver func serviceNameToLabelFormat(serviceName string) string { @@ -58,8 +56,19 @@ func serviceNameToLabelFormat(serviceName string) string { return strings.ToLower(strings.Replace(serviceName, "-", "", replaceAll)) } -// ExportVersionMetric set values for version metrics -func ExportVersionMetric(version *utils.Version) { +// editionToLabel convert edition value to string to use as label +func editionToLabel(edition utils.ProductEdition) string { + switch edition { + case utils.CommunityEdition: + return "ce" + case utils.EnterpriseEdition: + return "ee" + } + panic(fmt.Sprintf("undefined edition: %v", edition)) +} + +// exportVersionMetric set values for version metrics +func exportVersionMetric(version *utils.Version) { version, err := utils.GetParsedVersion() if err != nil { panic(err) @@ -83,10 +92,18 @@ var ( majorVersionGauge *prometheus.GaugeVec minorVersionGauge *prometheus.GaugeVec patchVersionGauge *prometheus.GaugeVec + buildInfoCounter *prometheus.CounterVec ) +const ( + BuildInfoEditionLabel = "edition" + BuildInfoVersionLabel = "version" +) + +var registerVersionMetricsLock = sync.Once{} + // RegisterVersionMetrics set and register metrics with current version value -func RegisterVersionMetrics(serviceName string) { +func RegisterVersionMetrics(serviceName string, version *utils.Version) { labelServiceName := serviceNameToLabelFormat(serviceName) majorVersionGauge = prometheus.NewGaugeVec( prometheus.GaugeOpts{ @@ -106,9 +123,30 @@ func RegisterVersionMetrics(serviceName string) { Help: "Patch number of version", }, []string{}) - registerLock.Do(func() { + registerVersionMetricsLock.Do(func() { prometheus.MustRegister(majorVersionGauge) prometheus.MustRegister(minorVersionGauge) prometheus.MustRegister(patchVersionGauge) + exportVersionMetric(version) + }) +} + +var registerBuildInfoLock = sync.Once{} + +// RegisterBuildInfoMetrics set and register metrics with build info +func RegisterBuildInfoMetrics(serviceName string, edition utils.ProductEdition) { + buildInfoCounter = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: fmt.Sprintf("%s_build_info", serviceNameToLabelFormat(serviceName)), + }, []string{BuildInfoEditionLabel, BuildInfoVersionLabel}) + + registerBuildInfoLock.Do(func() { + prometheus.MustRegister(buildInfoCounter) + version, err := utils.GetParsedVersion() + if err != nil { + panic(err) + } + // increment on start only once + buildInfoCounter.With(prometheus.Labels{BuildInfoEditionLabel: editionToLabel(edition), BuildInfoVersionLabel: version.String()}).Inc() }) } diff --git a/tests/test.py b/tests/test.py index 24e88cac5..52efc6810 100644 --- a/tests/test.py +++ b/tests/test.py @@ -3485,8 +3485,17 @@ def skip(need_skip): if skip(family.name): continue for sample in family.samples: - self.assertGreaterEqual(sample.value, labels[sample.name]['min_value'], - '{} - {}'.format(sample.name, sample.value)) + try: + self.assertGreaterEqual(sample.value, labels[sample.name]['min_value'], + '{} - {}'.format(sample.name, sample.value)) + except KeyError: + # python prometheus client append _total for sample names if they have type and + # have not _total suffix + if not sample.name.endswith('_total'): + raise + name = sample.name[:-len('_total')] + self.assertGreaterEqual(sample.value, labels[name]['min_value'], + '{} - {}'.format(name, sample.value)) def testAcraServer(self): # run some queries to set some values for counters @@ -3512,6 +3521,8 @@ def testAcraServer(self): 'acraserver_version_major': {'min_value': 0}, 'acraserver_version_minor': {'min_value': 0}, 'acraserver_version_patch': {'min_value': 0}, + + 'acraserver_build_info': {'min_value': 1}, } self.checkMetrics('http://127.0.0.1:{}/metrics'.format( self.ACRASERVER_PROMETHEUS_PORT), labels) @@ -3529,6 +3540,8 @@ def testAcraConnector(self): 'acraconnector_version_major': {'min_value': 0}, 'acraconnector_version_minor': {'min_value': 0}, 'acraconnector_version_patch': {'min_value': 0}, + + 'acraconnector_build_info': {'min_value': 1}, } self.checkMetrics('http://127.0.0.1:{}/metrics'.format( self.get_connector_prometheus_port(self.CONNECTOR_PORT_1)), labels) @@ -3550,6 +3563,8 @@ def testAcraTranslator(self): 'acratranslator_version_patch': {'min_value': 0}, 'acra_acrastruct_decryptions_total': {'min_value': 1}, + + 'acratranslator_build_info': {'min_value': 1}, } translator_port = 3456 metrics_port = translator_port+1 diff --git a/utils/version.go b/utils/version.go index 83d913fc1..26a773de8 100644 --- a/utils/version.go +++ b/utils/version.go @@ -35,6 +35,16 @@ type Version struct { Patch string } +// ProductEdition type for edition values +type ProductEdition int + +const ( + CommunityEdition = iota + EnterpriseEdition +) + +var Edition ProductEdition = CommunityEdition + // ComparisonStatus result of comparison versions type ComparisonStatus int