mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
Source available metrics (#24879)
* Expose metrics under a source available license
* do not assume Cluster()
* allow metrics if licensed or dev
* temporary vet override
* simplify BULID_TAGS handling
* auto clean old imports.go
* fix license listener
* e2e test metrics & license semantics
* update from enterprise
* switch back to mattermost-govet/v2@new now
* update metrics from upstream
* Update license_spec.js
Co-authored-by: Saturnino Abril <saturnino.abril@gmail.com>
* Update license_spec.js
Co-authored-by: Saturnino Abril <saturnino.abril@gmail.com>
* Update e2e-tests/cypress/tests/integration/channels/enterprise/metrics/license_spec.js
Co-authored-by: Saturnino Abril <saturnino.abril@gmail.com>
* Update e2e-tests/cypress/tests/integration/channels/enterprise/metrics/license_spec.js
* split up specs
* require/delete license earlier in e2e test
* expanded expect to debug failures
* more logging
* Revert "more logging"
This reverts commit 0bc513fd92
.
* e2e: try deleting license first
* update from enterprise
* toggleMetricsOn to work around license delete
* eslint
* ensure admin before deleting license
* update from enterprise
* updates from enterprise
* fix cypress logging
* temp: log at DEBUG for Cypress tests
---------
Co-authored-by: Saturnino Abril <saturnino.abril@gmail.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
This commit is contained in:
parent
6184c36e0b
commit
b05093d508
1
LICENSE.enterprise
Symbolic link
1
LICENSE.enterprise
Symbolic link
@ -0,0 +1 @@
|
||||
server/enterprise/LICENSE
|
@ -0,0 +1,37 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
export const checkMetrics = (expectedStatusCode) => {
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
const baseURL = new URL(Cypress.config('baseUrl'));
|
||||
baseURL.port = config.MetricsSettings.ListenAddress.replace(/^.*:/, '');
|
||||
baseURL.pathname = '/metrics';
|
||||
|
||||
cy.log({name: 'Metrics License', message: `Checking metrics at ${baseURL.toString()}`});
|
||||
cy.request({
|
||||
headers: {'X-Requested-With': 'XMLHttpRequest'},
|
||||
url: baseURL.toString(),
|
||||
method: 'GET',
|
||||
failOnStatusCode: false,
|
||||
}).then((response) => {
|
||||
expect(response.headers['Content-Type'], 'should not hit webapp').not.to.equal('text/html');
|
||||
expect(response.status, 'should match expected status code').to.equal(expectedStatusCode);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// toggleMetricsOn turns metrics off and back on, forcing it to be tested against the current
|
||||
// license. When, in the future, the product detects license removal and does this automatically,
|
||||
// this helper won't be required.
|
||||
export const toggleMetricsOn = () => {
|
||||
cy.apiUpdateConfig({
|
||||
MetricsSettings: {
|
||||
Enable: false,
|
||||
},
|
||||
});
|
||||
cy.apiUpdateConfig({
|
||||
MetricsSettings: {
|
||||
Enable: true,
|
||||
},
|
||||
});
|
||||
};
|
@ -0,0 +1,44 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @enterprise @metrics @not_cloud @license_removal
|
||||
|
||||
import {checkMetrics, toggleMetricsOn} from './helper';
|
||||
|
||||
describe('Metrics > No license', () => {
|
||||
before(() => {
|
||||
cy.shouldNotRunOnCloudEdition();
|
||||
cy.apiAdminLogin();
|
||||
cy.apiDeleteLicense();
|
||||
toggleMetricsOn();
|
||||
});
|
||||
|
||||
it('should enable metrics in BUILD_NUMBER == dev environments', () => {
|
||||
cy.apiGetConfig(true).then(({config}) => {
|
||||
if (config.BuildNumber !== 'dev') {
|
||||
Cypress.log({name: 'Metrics License', message: `Skipping test since BUILD_NUMBER = ${config.BuildNumber}`});
|
||||
return;
|
||||
}
|
||||
|
||||
checkMetrics(200);
|
||||
});
|
||||
});
|
||||
|
||||
it('should disable metrics in BUILD_NUMBER != dev environments', () => {
|
||||
cy.apiGetConfig(true).then(({config}) => {
|
||||
if (config.BuildNumber === 'dev') {
|
||||
Cypress.log({name: 'Metrics License', message: `Skipping test since BUILD_NUMBER = ${config.BuildNumber}`});
|
||||
return;
|
||||
}
|
||||
|
||||
checkMetrics(404);
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,43 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @enterprise @metrics @not_cloud
|
||||
|
||||
import {checkMetrics, toggleMetricsOn} from './helper';
|
||||
|
||||
describe('Metrics > License', () => {
|
||||
before(() => {
|
||||
cy.shouldNotRunOnCloudEdition();
|
||||
cy.apiRequireLicense();
|
||||
toggleMetricsOn();
|
||||
});
|
||||
|
||||
it('should enable metrics in BUILD_NUMBER == dev environments', () => {
|
||||
cy.apiGetConfig(true).then(({config}) => {
|
||||
if (config.BuildNumber !== 'dev') {
|
||||
Cypress.log({name: 'Metrics License', message: `Skipping test since BUILD_NUMBER = ${config.BuildNumber}`});
|
||||
return;
|
||||
}
|
||||
|
||||
checkMetrics(200);
|
||||
});
|
||||
});
|
||||
|
||||
it('should enable metrics in BUILD_NUMBER != dev environments', () => {
|
||||
cy.apiGetConfig(true).then(({config}) => {
|
||||
if (config.BuildNumber === 'dev') {
|
||||
Cypress.log({name: 'Metrics License', message: `Skipping test since BUILD_NUMBER = ${config.BuildNumber}`});
|
||||
return;
|
||||
}
|
||||
|
||||
checkMetrics(200);
|
||||
});
|
||||
});
|
||||
});
|
@ -162,7 +162,7 @@
|
||||
"ConsoleJson": true,
|
||||
"EnableColor": false,
|
||||
"EnableFile": true,
|
||||
"FileLevel": "INFO",
|
||||
"FileLevel": "DEBUG",
|
||||
"FileJson": true,
|
||||
"FileLocation": "",
|
||||
"EnableWebhookDebugging": true,
|
||||
|
5
server/.gitignore
vendored
5
server/.gitignore
vendored
@ -21,9 +21,6 @@ config/active.dat
|
||||
config/logging.json
|
||||
/plugins
|
||||
|
||||
# Enterprise & products imports files
|
||||
channels/imports/imports.go
|
||||
|
||||
# go.work file
|
||||
go.work
|
||||
go.work.sum
|
||||
@ -104,8 +101,6 @@ api/data/*
|
||||
api4/data/*
|
||||
app/data/*
|
||||
|
||||
/enterprise
|
||||
|
||||
cover.out
|
||||
ecover.out
|
||||
mmctlcover.out
|
||||
|
@ -33,6 +33,7 @@ IS_CI ?= false
|
||||
BUILD_NUMBER ?= $(BUILD_NUMBER:)
|
||||
BUILD_DATE = $(shell date -u)
|
||||
BUILD_HASH = $(shell git rev-parse HEAD)
|
||||
BUILD_TAGS =
|
||||
|
||||
|
||||
# Docker
|
||||
@ -73,6 +74,7 @@ ifneq ($(wildcard $(BUILD_ENTERPRISE_DIR)/.),)
|
||||
BUILD_ENTERPRISE_READY = true
|
||||
BUILD_TYPE_NAME = enterprise
|
||||
BUILD_HASH_ENTERPRISE = $(shell cd $(BUILD_ENTERPRISE_DIR) && git rev-parse HEAD)
|
||||
BUILD_TAGS += enterprise
|
||||
else
|
||||
BUILD_ENTERPRISE_READY = false
|
||||
BUILD_TYPE_NAME = team
|
||||
@ -82,6 +84,16 @@ else
|
||||
BUILD_TYPE_NAME = team
|
||||
endif
|
||||
|
||||
# Clean up the old means of importing enterprise source, if it exists
|
||||
ifneq ($(wildcard channels/imports/imports.go),)
|
||||
IGNORE := $(shell rm -f channels/imports/imports.go)
|
||||
endif
|
||||
|
||||
# Source available, already included with enterprise but also available during development.
|
||||
ifeq ($(BUILD_NUMBER),dev)
|
||||
BUILD_TAGS += sourceavailable
|
||||
endif
|
||||
|
||||
# Webapp
|
||||
BUILD_WEBAPP_DIR ?= ../webapp
|
||||
|
||||
@ -156,16 +168,6 @@ PLUGIN_PACKAGES += mattermost-plugin-zoom-v1.6.2
|
||||
PLUGIN_PACKAGES += mattermost-plugin-apps-v1.2.2
|
||||
PLUGIN_PACKAGES += focalboard-v7.11.4
|
||||
|
||||
# Prepares the enterprise build if exists. The IGNORE stuff is a hack to get the Makefile to execute the commands outside a target
|
||||
ifeq ($(BUILD_ENTERPRISE_READY),true)
|
||||
IGNORE:=$(shell echo Enterprise build selected, preparing)
|
||||
IGNORE:=$(shell rm -f channels/imports/imports.go)
|
||||
IGNORE:=$(shell cp $(BUILD_ENTERPRISE_DIR)/imports/imports.go channels/imports/)
|
||||
IGNORE:=$(shell rm -f enterprise)
|
||||
else
|
||||
IGNORE:=$(shell rm -f channels/imports/imports.go)
|
||||
endif
|
||||
|
||||
EE_PACKAGES=$(shell $(GO) list $(BUILD_ENTERPRISE_DIR)/...)
|
||||
|
||||
ifeq ($(BUILD_ENTERPRISE_READY),true)
|
||||
@ -422,14 +424,10 @@ test-compile: gotestsum ## Compile tests.
|
||||
done
|
||||
|
||||
modules-tidy:
|
||||
@if [ -f "channels/imports/imports.go" ]; then \
|
||||
mv channels/imports/imports.go channels/imports/imports.go.orig; \
|
||||
fi;
|
||||
mv enterprise/external_imports.go enterprise/external_imports.go.orig
|
||||
-$(GO) mod tidy
|
||||
-cd public && $(GO) mod tidy
|
||||
@if [ -f "channels/imports/imports.go.orig" ]; then \
|
||||
mv channels/imports/imports.go.orig channels/imports/imports.go; \
|
||||
fi;
|
||||
mv enterprise/external_imports.go.orig enterprise/external_imports.go
|
||||
|
||||
test-server-pre: check-prereqs-enterprise start-docker gotestsum ## Runs tests.
|
||||
ifeq ($(BUILD_ENTERPRISE_READY),true)
|
||||
@ -580,7 +578,7 @@ run-server: setup-go-work prepackaged-binaries validate-go-version start-docker
|
||||
@echo Running mattermost for development
|
||||
|
||||
mkdir -p $(BUILD_WEBAPP_DIR)/channels/dist/files
|
||||
$(GO) run $(GOFLAGS) -ldflags '$(LDFLAGS)' $(PLATFORM_FILES) $(RUN_IN_BACKGROUND)
|
||||
$(GO) run $(GOFLAGS) -ldflags '$(LDFLAGS)' -tags '$(BUILD_TAGS)' $(PLATFORM_FILES) $(RUN_IN_BACKGROUND)
|
||||
|
||||
debug-server: start-docker ## Compile and start server using delve.
|
||||
mkdir -p $(BUILD_WEBAPP_DIR)/channels/dist/files
|
||||
@ -589,7 +587,8 @@ debug-server: start-docker ## Compile and start server using delve.
|
||||
-X \"github.com/mattermost/mattermost/server/public/model.BuildDate=$(BUILD_DATE)\"\
|
||||
-X github.com/mattermost/mattermost/server/public/model.BuildHash=$(BUILD_HASH)\
|
||||
-X github.com/mattermost/mattermost/server/public/model.BuildHashEnterprise=$(BUILD_HASH_ENTERPRISE)\
|
||||
-X github.com/mattermost/mattermost/server/public/model.BuildEnterpriseReady=$(BUILD_ENTERPRISE_READY)'"
|
||||
-X github.com/mattermost/mattermost/server/public/model.BuildEnterpriseReady=$(BUILD_ENTERPRISE_READY)'\
|
||||
-tags '$(BUILD_TAGS)'"
|
||||
|
||||
debug-server-headless: start-docker ## Debug server from within an IDE like VSCode or IntelliJ.
|
||||
mkdir -p $(BUILD_WEBAPP_DIR)/channels/dist/files
|
||||
@ -598,13 +597,14 @@ debug-server-headless: start-docker ## Debug server from within an IDE like VSCo
|
||||
-X \"github.com/mattermost/mattermost/server/public/model.BuildDate=$(BUILD_DATE)\"\
|
||||
-X github.com/mattermost/mattermost/server/public/model.BuildHash=$(BUILD_HASH)\
|
||||
-X github.com/mattermost/mattermost/server/public/model.BuildHashEnterprise=$(BUILD_HASH_ENTERPRISE)\
|
||||
-X github.com/mattermost/mattermost/server/public/model.BuildEnterpriseReady=$(BUILD_ENTERPRISE_READY)'"
|
||||
-X github.com/mattermost/mattermost/server/public/model.BuildEnterpriseReady=$(BUILD_ENTERPRISE_READY)'\
|
||||
-tags '$(BUILD_TAGS)'"
|
||||
|
||||
run-cli: start-docker ## Runs CLI.
|
||||
@echo Running mattermost for development
|
||||
@echo Example should be like 'make ARGS="-version" run-cli'
|
||||
|
||||
$(GO) run $(GOFLAGS) -ldflags '$(LDFLAGS)' $(PLATFORM_FILES) ${ARGS}
|
||||
$(GO) run $(GOFLAGS) -ldflags '$(LDFLAGS)' -tags '$(BUILD_TAGS)' $(PLATFORM_FILES) ${ARGS}
|
||||
|
||||
run-client: client ## Runs the webapp.
|
||||
@echo Running mattermost client for development
|
||||
@ -664,7 +664,7 @@ restart-client: | stop-client run-client ## Restarts the webapp.
|
||||
|
||||
run-job-server: ## Runs the background job server.
|
||||
@echo Running job server for development
|
||||
$(GO) run $(GOFLAGS) -ldflags '$(LDFLAGS)' $(PLATFORM_FILES) jobserver &
|
||||
$(GO) run $(GOFLAGS) -ldflags '$(LDFLAGS)' -tags '$(BUILD_TAGS)' $(PLATFORM_FILES) jobserver &
|
||||
|
||||
config-ldap: ## Configures LDAP.
|
||||
@echo Setting up configuration for local LDAP
|
||||
@ -730,8 +730,8 @@ update-dependencies: ## Uses go get -u to update all the dependencies while hold
|
||||
@echo Updating Dependencies
|
||||
|
||||
ifeq ($(BUILD_ENTERPRISE_READY),true)
|
||||
@echo Enterprise repository detected, temporarily removing imports.go
|
||||
rm -f channels/imports/imports.go
|
||||
@echo Enterprise repository detected, temporarily removing external_imports.go
|
||||
mv enterprise/external_imports.go enterprise/external_imports.go.orig
|
||||
endif
|
||||
|
||||
# Update all dependencies (does not update across major versions)
|
||||
@ -741,7 +741,7 @@ endif
|
||||
$(GO) mod tidy
|
||||
|
||||
ifeq ($(BUILD_ENTERPRISE_READY),true)
|
||||
cp $(BUILD_ENTERPRISE_DIR)/imports/imports.go channels/imports/
|
||||
mv enterprise/external_imports.go.orig enterprise/external_imports.go
|
||||
endif
|
||||
|
||||
vet: ## Run mattermost go vet specific checks
|
||||
|
@ -5,85 +5,85 @@ build-linux: build-linux-amd64 build-linux-arm64
|
||||
build-linux-amd64:
|
||||
@echo Build Linux amd64
|
||||
ifeq ($(BUILDER_GOOS_GOARCH),"linux_amd64")
|
||||
env GOOS=linux GOARCH=amd64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./...
|
||||
env GOOS=linux GOARCH=amd64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags '$(BUILD_TAGS) production' -ldflags '$(LDFLAGS)' ./...
|
||||
else
|
||||
mkdir -p $(GOBIN)/linux_amd64
|
||||
env GOOS=linux GOARCH=amd64 $(GO) build -o $(GOBIN)/linux_amd64 $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./...
|
||||
env GOOS=linux GOARCH=amd64 $(GO) build -o $(GOBIN)/linux_amd64 $(GOFLAGS) -trimpath -tags '$(BUILD_TAGS) production' -ldflags '$(LDFLAGS)' ./...
|
||||
endif
|
||||
|
||||
build-linux-arm64:
|
||||
@echo Build Linux arm64
|
||||
ifeq ($(BUILDER_GOOS_GOARCH),"linux_arm64")
|
||||
env GOOS=linux GOARCH=arm64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./...
|
||||
env GOOS=linux GOARCH=arm64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags '$(BUILD_TAGS) production' -ldflags '$(LDFLAGS)' ./...
|
||||
else
|
||||
mkdir -p $(GOBIN)/linux_arm64
|
||||
env GOOS=linux GOARCH=arm64 $(GO) build -o $(GOBIN)/linux_arm64 $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./...
|
||||
env GOOS=linux GOARCH=arm64 $(GO) build -o $(GOBIN)/linux_arm64 $(GOFLAGS) -trimpath -tags '$(BUILD_TAGS) production' -ldflags '$(LDFLAGS)' ./...
|
||||
endif
|
||||
|
||||
build-osx:
|
||||
@echo Build OSX amd64
|
||||
ifeq ($(BUILDER_GOOS_GOARCH),"darwin_amd64")
|
||||
env GOOS=darwin GOARCH=amd64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./...
|
||||
env GOOS=darwin GOARCH=amd64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags '$(BUILD_TAGS) production' -ldflags '$(LDFLAGS)' ./...
|
||||
else
|
||||
mkdir -p $(GOBIN)/darwin_amd64
|
||||
env GOOS=darwin GOARCH=amd64 $(GO) build -o $(GOBIN)/darwin_amd64 $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./...
|
||||
env GOOS=darwin GOARCH=amd64 $(GO) build -o $(GOBIN)/darwin_amd64 $(GOFLAGS) -trimpath -tags '$(BUILD_TAGS) production' -ldflags '$(LDFLAGS)' ./...
|
||||
endif
|
||||
@echo Build OSX arm64
|
||||
ifeq ($(BUILDER_GOOS_GOARCH),"darwin_arm64")
|
||||
env GOOS=darwin GOARCH=arm64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./...
|
||||
env GOOS=darwin GOARCH=arm64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags '$(BUILD_TAGS) production' -ldflags '$(LDFLAGS)' ./...
|
||||
else
|
||||
mkdir -p $(GOBIN)/darwin_arm64
|
||||
env GOOS=darwin GOARCH=arm64 $(GO) build -o $(GOBIN)/darwin_arm64 $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./...
|
||||
env GOOS=darwin GOARCH=arm64 $(GO) build -o $(GOBIN)/darwin_arm64 $(GOFLAGS) -trimpath -tags '$(BUILD_TAGS) production' -ldflags '$(LDFLAGS)' ./...
|
||||
endif
|
||||
|
||||
build-windows:
|
||||
@echo Build Windows amd64
|
||||
ifeq ($(BUILDER_GOOS_GOARCH),"windows_amd64")
|
||||
env GOOS=windows GOARCH=amd64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./...
|
||||
env GOOS=windows GOARCH=amd64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags '$(BUILD_TAGS) production' -ldflags '$(LDFLAGS)' ./...
|
||||
else
|
||||
mkdir -p $(GOBIN)/windows_amd64
|
||||
env GOOS=windows GOARCH=amd64 $(GO) build -o $(GOBIN)/windows_amd64 $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./...
|
||||
env GOOS=windows GOARCH=amd64 $(GO) build -o $(GOBIN)/windows_amd64 $(GOFLAGS) -trimpath -tags '$(BUILD_TAGS) production' -ldflags '$(LDFLAGS)' ./...
|
||||
endif
|
||||
|
||||
build-cmd-linux:
|
||||
@echo Build CMD Linux amd64
|
||||
ifeq ($(BUILDER_GOOS_GOARCH),"linux_amd64")
|
||||
env GOOS=linux GOARCH=amd64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./cmd/...
|
||||
env GOOS=linux GOARCH=amd64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags '$(BUILD_TAGS) production' -ldflags '$(LDFLAGS)' ./cmd/...
|
||||
else
|
||||
mkdir -p $(GOBIN)/linux_amd64
|
||||
env GOOS=linux GOARCH=amd64 $(GO) build -o $(GOBIN)/linux_amd64 $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./cmd/...
|
||||
env GOOS=linux GOARCH=amd64 $(GO) build -o $(GOBIN)/linux_amd64 $(GOFLAGS) -trimpath -tags '$(BUILD_TAGS) production' -ldflags '$(LDFLAGS)' ./cmd/...
|
||||
endif
|
||||
@echo Build CMD Linux arm64
|
||||
ifeq ($(BUILDER_GOOS_GOARCH),"linux_arm64")
|
||||
env GOOS=linux GOARCH=arm64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./cmd/...
|
||||
env GOOS=linux GOARCH=arm64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags '$(BUILD_TAGS) production' -ldflags '$(LDFLAGS)' ./cmd/...
|
||||
else
|
||||
mkdir -p $(GOBIN)/linux_arm64
|
||||
env GOOS=linux GOARCH=arm64 $(GO) build -o $(GOBIN)/linux_arm64 $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./cmd/...
|
||||
env GOOS=linux GOARCH=arm64 $(GO) build -o $(GOBIN)/linux_arm64 $(GOFLAGS) -trimpath -tags '$(BUILD_TAGS) production' -ldflags '$(LDFLAGS)' ./cmd/...
|
||||
endif
|
||||
|
||||
build-cmd-osx:
|
||||
@echo Build CMD OSX amd64
|
||||
ifeq ($(BUILDER_GOOS_GOARCH),"darwin_amd64")
|
||||
env GOOS=darwin GOARCH=amd64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./cmd/...
|
||||
env GOOS=darwin GOARCH=amd64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags '$(BUILD_TAGS) production' -ldflags '$(LDFLAGS)' ./cmd/...
|
||||
else
|
||||
mkdir -p $(GOBIN)/darwin_amd64
|
||||
env GOOS=darwin GOARCH=amd64 $(GO) build -o $(GOBIN)/darwin_amd64 $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./cmd/...
|
||||
env GOOS=darwin GOARCH=amd64 $(GO) build -o $(GOBIN)/darwin_amd64 $(GOFLAGS) -trimpath -tags '$(BUILD_TAGS) production' -ldflags '$(LDFLAGS)' ./cmd/...
|
||||
endif
|
||||
@echo Build CMD OSX arm64
|
||||
ifeq ($(BUILDER_GOOS_GOARCH),"darwin_arm64")
|
||||
env GOOS=darwin GOARCH=arm64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./cmd/...
|
||||
env GOOS=darwin GOARCH=arm64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags '$(BUILD_TAGS) production' -ldflags '$(LDFLAGS)' ./cmd/...
|
||||
else
|
||||
mkdir -p $(GOBIN)/darwin_arm64
|
||||
env GOOS=darwin GOARCH=arm64 $(GO) build -o $(GOBIN)/darwin_arm64 $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./cmd/...
|
||||
env GOOS=darwin GOARCH=arm64 $(GO) build -o $(GOBIN)/darwin_arm64 $(GOFLAGS) -trimpath -tags '$(BUILD_TAGS) production' -ldflags '$(LDFLAGS)' ./cmd/...
|
||||
endif
|
||||
|
||||
build-cmd-windows:
|
||||
@echo Build CMD Windows amd64
|
||||
ifeq ($(BUILDER_GOOS_GOARCH),"windows_amd64")
|
||||
env GOOS=windows GOARCH=amd64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./cmd/...
|
||||
env GOOS=windows GOARCH=amd64 $(GO) build -o $(GOBIN) $(GOFLAGS) -trimpath -tags '$(BUILD_TAGS) production' -ldflags '$(LDFLAGS)' ./cmd/...
|
||||
else
|
||||
mkdir -p $(GOBIN)/windows_amd64
|
||||
env GOOS=windows GOARCH=amd64 $(GO) build -o $(GOBIN)/windows_amd64 $(GOFLAGS) -trimpath -tags production -ldflags '$(LDFLAGS)' ./cmd/...
|
||||
env GOOS=windows GOARCH=amd64 $(GO) build -o $(GOBIN)/windows_amd64 $(GOFLAGS) -trimpath -tags '$(BUILD_TAGS) production' -ldflags '$(LDFLAGS)' ./cmd/...
|
||||
endif
|
||||
|
||||
build: setup-go-work build-client build-linux build-windows build-osx
|
||||
|
@ -323,11 +323,10 @@ func New(sc ServiceConfig, options ...Option) (*PlatformService, error) {
|
||||
}
|
||||
|
||||
ps.AddLicenseListener(func(oldLicense, newLicense *model.License) {
|
||||
if (oldLicense == nil && newLicense == nil) || !ps.startMetrics {
|
||||
return
|
||||
}
|
||||
wasLicensed := (oldLicense != nil && *oldLicense.Features.Metrics) || (model.BuildNumber == "dev")
|
||||
isLicensed := (newLicense != nil && *newLicense.Features.Metrics) || (model.BuildNumber == "dev")
|
||||
|
||||
if oldLicense != nil && newLicense != nil && *oldLicense.Features.Metrics == *newLicense.Features.Metrics {
|
||||
if wasLicensed == isLicensed || !ps.startMetrics {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1,8 +0,0 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// As part of the enterprise code integration machinery a go file is copied to
|
||||
// this package, this file ensure the existence of the package anyway, allowing
|
||||
// the rest of the code to import the package when enterprise code is there and
|
||||
// when is not.
|
||||
package imports
|
@ -13,7 +13,7 @@ import (
|
||||
_ "github.com/mattermost/mattermost/server/v8/channels/app/oauthproviders/gitlab"
|
||||
|
||||
// Enterprise Imports
|
||||
_ "github.com/mattermost/mattermost/server/v8/channels/imports"
|
||||
_ "github.com/mattermost/mattermost/server/v8/enterprise"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -17,8 +17,8 @@ import (
|
||||
_ "github.com/hashicorp/memberlist"
|
||||
_ "github.com/mattermost/gosaml2"
|
||||
_ "github.com/mattermost/ldap"
|
||||
_ "github.com/mattermost/mattermost/server/v8/channels/imports"
|
||||
_ "github.com/mattermost/mattermost/server/v8/channels/utils/testutils"
|
||||
_ "github.com/mattermost/mattermost/server/v8/enterprise"
|
||||
_ "github.com/mattermost/rsc/qr"
|
||||
_ "github.com/prometheus/client_golang/prometheus"
|
||||
_ "github.com/prometheus/client_golang/prometheus/collectors"
|
||||
|
39
server/enterprise/LICENSE
Normal file
39
server/enterprise/LICENSE
Normal file
@ -0,0 +1,39 @@
|
||||
The Mattermost Source Available License license (the “Source Available License”)
|
||||
Copyright (c) 2015-present Mattermost
|
||||
|
||||
With regard to the Mattermost Software:
|
||||
|
||||
This software and associated documentation files (the "Software") may only be
|
||||
used in production, if you (and any entity that you represent) have agreed to,
|
||||
and are in compliance with, the Mattermost Terms of Service, available at
|
||||
https://mattermost.com/enterprise-edition-terms/ (the “EE Terms”), or other
|
||||
agreement governing the use of the Software, as agreed by you and Mattermost,
|
||||
and otherwise have a valid Mattermost Enterprise E20 subscription for the
|
||||
correct number of user seats. Subject to the foregoing sentence, you are free
|
||||
to modify this Software and publish patches to the Software. You agree that
|
||||
Mattermost and/or its licensors (as applicable) retain all right, title and
|
||||
interest in and to all such modifications and/or patches, and all such
|
||||
modifications and/or patches may only be used, copied, modified, displayed,
|
||||
distributed, or otherwise exploited with a valid Mattermost Enterprise E20
|
||||
Edition subscription for the correct number of user seats. Notwithstanding
|
||||
the foregoing, you may copy and modify the Software for development and testing
|
||||
purposes, without requiring a subscription. You agree that Mattermost and/or
|
||||
its licensors (as applicable) retain all right, title and interest in and to
|
||||
all such modifications. You are not granted any other rights beyond what is
|
||||
expressly stated herein. Subject to the foregoing, it is forbidden to copy,
|
||||
merge, publish, distribute, sublicense, and/or sell the Software.
|
||||
|
||||
The full text of this EE License shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
For all third party components incorporated into the Mattermost Software, those
|
||||
components are licensed under the original license provided by the owner of the
|
||||
applicable component.
|
17
server/enterprise/README.md
Normal file
17
server/enterprise/README.md
Normal file
@ -0,0 +1,17 @@
|
||||
# Enterprise
|
||||
|
||||
This folder contains source available enterprise code as well as import directives for closed source enterprise code.
|
||||
|
||||
## Build Information
|
||||
|
||||
The source code in this folder is only included with builds specifying the `enterprise` or `sourceavailble` build tags. If you have a copy of https://github.com/mattermost/enterprise checked out as a peer to this repository, `enterprise` will be set automatically and the imports from both [`external_imports.go`](external_imports.go) and [`local_imports.go`](local_imports.go) will apply.
|
||||
|
||||
In a development environment (when `BUILD_NUMBER` is left undefined or explicitly set to `dev`), the `sourceavailable` build tag will be set automatically and only the imports from [`local_imports.go`](local_imports.go) will apply.
|
||||
|
||||
## License
|
||||
|
||||
See the [LICENSE file](LICENSE) for license rights and limitations. See also [Mattermost Source Available License](https://docs.mattermost.com/overview/faq.html#mattermost-source-available-license) to learn more.
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions to source available enterprise code are welcome. Please see [CONTRIBUTING.md](../../CONTRIBUTING.md).
|
45
server/enterprise/external_imports.go
Normal file
45
server/enterprise/external_imports.go
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
//go:build enterprise
|
||||
|
||||
package enterprise
|
||||
|
||||
import (
|
||||
// Needed to ensure the init() method in the EE gets run
|
||||
_ "github.com/mattermost/enterprise/account_migration"
|
||||
// Needed to ensure the init() method in the EE gets run
|
||||
_ "github.com/mattermost/enterprise/cluster"
|
||||
// Needed to ensure the init() method in the EE gets run
|
||||
_ "github.com/mattermost/enterprise/compliance"
|
||||
// Needed to ensure the init() method in the EE gets run
|
||||
_ "github.com/mattermost/enterprise/data_retention"
|
||||
// Needed to ensure the init() method in the EE gets run
|
||||
_ "github.com/mattermost/enterprise/elasticsearch"
|
||||
// Needed to ensure the init() method in the EE gets run
|
||||
_ "github.com/mattermost/enterprise/ldap"
|
||||
// Needed to ensure the init() method in the EE gets run
|
||||
_ "github.com/mattermost/enterprise/message_export"
|
||||
// Needed to ensure the init() method in the EE gets run
|
||||
_ "github.com/mattermost/enterprise/cloud"
|
||||
// Needed to ensure the init() method in the EE gets run
|
||||
_ "github.com/mattermost/enterprise/message_export/actiance_export"
|
||||
// Needed to ensure the init() method in the EE gets run
|
||||
_ "github.com/mattermost/enterprise/message_export/csv_export"
|
||||
// Needed to ensure the init() method in the EE gets run
|
||||
_ "github.com/mattermost/enterprise/message_export/global_relay_export"
|
||||
// Needed to ensure the init() method in the EE gets run
|
||||
_ "github.com/mattermost/enterprise/notification"
|
||||
// Needed to ensure the init() method in the EE gets run
|
||||
_ "github.com/mattermost/enterprise/oauth/google"
|
||||
// Needed to ensure the init() method in the EE gets run
|
||||
_ "github.com/mattermost/enterprise/oauth/office365"
|
||||
// Needed to ensure the init() method in the EE gets run
|
||||
_ "github.com/mattermost/enterprise/saml"
|
||||
// Needed to ensure the init() method in the EE gets run
|
||||
_ "github.com/mattermost/enterprise/oauth/openid"
|
||||
// Needed to ensure the init() method in the EE gets run
|
||||
_ "github.com/mattermost/enterprise/license"
|
||||
// Needed to ensure the init() method in the EE gets run
|
||||
_ "github.com/mattermost/enterprise/ip_filtering"
|
||||
)
|
11
server/enterprise/local_imports.go
Normal file
11
server/enterprise/local_imports.go
Normal file
@ -0,0 +1,11 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
//go:build enterprise || sourceavailable
|
||||
|
||||
package enterprise
|
||||
|
||||
import (
|
||||
// Needed to ensure the init() method in the EE gets run
|
||||
_ "github.com/mattermost/mattermost/server/v8/enterprise/metrics"
|
||||
)
|
81
server/enterprise/metrics/dynamic.go
Normal file
81
server/enterprise/metrics/dynamic.go
Normal file
@ -0,0 +1,81 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.enterprise for license information.
|
||||
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// DynamicCounter provides a CounterVec that can create new counters via label values at runtime.
|
||||
// This allows applications to create counters at runtime without locking into Prometheus as the
|
||||
// metrics manager.
|
||||
type DynamicCounter struct {
|
||||
counter *prometheus.CounterVec
|
||||
}
|
||||
|
||||
// NewDynamicCounter creates a new dynamic counter with corresponding labels.
|
||||
func NewDynamicCounter(opts prometheus.CounterOpts, labels ...string) *DynamicCounter {
|
||||
return &DynamicCounter{
|
||||
counter: prometheus.NewCounterVec(opts, labels),
|
||||
}
|
||||
}
|
||||
|
||||
// GetCounter fetches a counter associated with the label values provided. An error is
|
||||
// returned if the number of values differs from the number of labels provided when
|
||||
// creating the DynamicCounter
|
||||
func (dc *DynamicCounter) GetCounter(values ...string) (prometheus.Counter, error) {
|
||||
return dc.counter.GetMetricWithLabelValues(values...)
|
||||
}
|
||||
|
||||
// DynamicGauge provides a GaugeVec that can create new gauges via label values at runtime.
|
||||
// This allows applications to create gauges at runtime without locking into Prometheus as the
|
||||
// metrics manager.
|
||||
type DynamicGauge struct {
|
||||
gauge *prometheus.GaugeVec
|
||||
}
|
||||
|
||||
// NewDynamicGauge creates a new dynamic gauge with corresponding labels.
|
||||
func NewDynamicGauge(opts prometheus.GaugeOpts, labels ...string) *DynamicGauge {
|
||||
return &DynamicGauge{
|
||||
gauge: prometheus.NewGaugeVec(opts, labels),
|
||||
}
|
||||
}
|
||||
|
||||
// GetGauge fetches a gauge associated with the label values provided. An error is
|
||||
// returned if the number of values differs from the number of labels provided when
|
||||
// creating the DynamicGauge
|
||||
func (dg *DynamicGauge) GetGauge(values ...string) (prometheus.Gauge, error) {
|
||||
return dg.gauge.GetMetricWithLabelValues(values...)
|
||||
}
|
||||
|
||||
// LoggerMetricsCollector provides counters for server logging.
|
||||
// Implements Logr.MetricsCollector
|
||||
type LoggerMetricsCollector struct {
|
||||
queueGauge *DynamicGauge
|
||||
loggedCounters *DynamicCounter
|
||||
errorCounters *DynamicCounter
|
||||
droppedCounters *DynamicCounter
|
||||
blockedCounters *DynamicCounter
|
||||
}
|
||||
|
||||
func (c *LoggerMetricsCollector) QueueSizeGauge(target string) (mlog.Gauge, error) {
|
||||
return c.queueGauge.GetGauge(target)
|
||||
}
|
||||
|
||||
func (c *LoggerMetricsCollector) LoggedCounter(target string) (mlog.Counter, error) {
|
||||
return c.loggedCounters.GetCounter(target)
|
||||
}
|
||||
|
||||
func (c *LoggerMetricsCollector) ErrorCounter(target string) (mlog.Counter, error) {
|
||||
return c.errorCounters.GetCounter(target)
|
||||
}
|
||||
|
||||
func (c *LoggerMetricsCollector) DroppedCounter(target string) (mlog.Counter, error) {
|
||||
return c.droppedCounters.GetCounter(target)
|
||||
}
|
||||
|
||||
func (c *LoggerMetricsCollector) BlockedCounter(target string) (mlog.Counter, error) {
|
||||
return c.blockedCounters.GetCounter(target)
|
||||
}
|
21
server/enterprise/metrics/main_test.go
Normal file
21
server/enterprise/metrics/main_test.go
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.enterprise for license information.
|
||||
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/mattermost/server/v8/channels/api4"
|
||||
"github.com/mattermost/mattermost/server/v8/channels/testlib"
|
||||
)
|
||||
|
||||
var mainHelper *testlib.MainHelper
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
mainHelper = testlib.NewMainHelper()
|
||||
defer mainHelper.Close()
|
||||
api4.SetMainHelper(mainHelper)
|
||||
|
||||
mainHelper.Main(m)
|
||||
}
|
1369
server/enterprise/metrics/metrics.go
Normal file
1369
server/enterprise/metrics/metrics.go
Normal file
File diff suppressed because it is too large
Load Diff
220
server/enterprise/metrics/metrics_test.go
Normal file
220
server/enterprise/metrics/metrics_test.go
Normal file
@ -0,0 +1,220 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.enterprise for license information.
|
||||
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/v8/channels/api4"
|
||||
"github.com/mattermost/mattermost/server/v8/channels/app"
|
||||
|
||||
"github.com/mattermost/mattermost/server/public/plugin/plugintest/mock"
|
||||
"github.com/mattermost/mattermost/server/v8/channels/store/storetest/mocks"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
prometheusModels "github.com/prometheus/client_model/go"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func configureMetrics(th *api4.TestHelper) {
|
||||
th.App.Srv().SetLicense(nil) // clear license
|
||||
th.App.UpdateConfig(func(cfg *model.Config) {
|
||||
*cfg.MetricsSettings.Enable = true
|
||||
*cfg.MetricsSettings.ListenAddress = ":0"
|
||||
})
|
||||
th.App.Srv().SetLicense(model.NewTestLicense("metrics"))
|
||||
}
|
||||
|
||||
func TestMetrics(t *testing.T) {
|
||||
th := api4.SetupEnterpriseWithStoreMock(t, app.StartMetrics)
|
||||
defer th.TearDown()
|
||||
|
||||
mockStore := th.App.Srv().Platform().Store.(*mocks.Store)
|
||||
mockUserStore := mocks.UserStore{}
|
||||
mockUserStore.On("Count", mock.Anything).Return(int64(10), nil)
|
||||
mockPostStore := mocks.PostStore{}
|
||||
mockPostStore.On("GetMaxPostSize").Return(65535, nil)
|
||||
mockSystemStore := mocks.SystemStore{}
|
||||
mockSystemStore.On("GetByName", "UpgradedFromTE").Return(&model.System{Name: "UpgradedFromTE", Value: "false"}, nil)
|
||||
mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil)
|
||||
mockStore.On("User").Return(&mockUserStore)
|
||||
mockStore.On("Post").Return(&mockPostStore)
|
||||
mockStore.On("System").Return(&mockSystemStore)
|
||||
mockStore.On("GetDBSchemaVersion").Return(1, nil)
|
||||
|
||||
configureMetrics(th)
|
||||
mi := th.App.Metrics()
|
||||
|
||||
_, ok := mi.(*MetricsInterfaceImpl)
|
||||
require.True(t, ok, fmt.Sprintf("App.Metrics is not *MetricsInterfaceImpl, but %T", mi))
|
||||
|
||||
mi.IncrementHTTPRequest()
|
||||
mi.IncrementHTTPError()
|
||||
|
||||
mi.IncrementPostFileAttachment(5)
|
||||
mi.IncrementPostCreate()
|
||||
mi.IncrementPostSentEmail()
|
||||
mi.IncrementPostSentPush()
|
||||
mi.IncrementPostBroadcast()
|
||||
|
||||
mi.IncrementLogin()
|
||||
mi.IncrementLoginFail()
|
||||
|
||||
mi.IncrementClusterRequest()
|
||||
mi.ObserveClusterRequestDuration(2.0)
|
||||
mi.IncrementClusterEventType(model.ClusterEventPublish)
|
||||
|
||||
loggerCollector := mi.GetLoggerMetricsCollector()
|
||||
g, err := loggerCollector.QueueSizeGauge("_logr")
|
||||
require.NoError(t, err)
|
||||
g.Set(59)
|
||||
|
||||
c, err := loggerCollector.LoggedCounter("_logr")
|
||||
require.NoError(t, err)
|
||||
c.Inc()
|
||||
|
||||
c, err = loggerCollector.ErrorCounter("_logr")
|
||||
require.NoError(t, err)
|
||||
c.Inc()
|
||||
|
||||
c, err = loggerCollector.DroppedCounter("_logr")
|
||||
require.NoError(t, err)
|
||||
c.Inc()
|
||||
|
||||
c, err = loggerCollector.BlockedCounter("_logr")
|
||||
require.NoError(t, err)
|
||||
c.Inc()
|
||||
}
|
||||
|
||||
func TestPluginMetrics(t *testing.T) {
|
||||
th := api4.SetupEnterprise(t, app.StartMetrics)
|
||||
defer th.TearDown()
|
||||
|
||||
configureMetrics(th)
|
||||
mi := th.App.Metrics()
|
||||
|
||||
miImpl, ok := mi.(*MetricsInterfaceImpl)
|
||||
require.True(t, ok, fmt.Sprintf("App.Metrics is not *MetricsInterfaceImpl, but %T", mi))
|
||||
|
||||
t.Run("test ObservePluginHookDuration", func(t *testing.T) {
|
||||
pluginID := "id_"
|
||||
hookName := "hook_"
|
||||
elapsed := 999.1
|
||||
m := &prometheusModels.Metric{}
|
||||
|
||||
for _, success := range []bool{true, false} {
|
||||
actualMetric, err := miImpl.PluginHookTimeHistogram.GetMetricWith(prometheus.Labels{"plugin_id": pluginID, "hook_name": hookName, "success": strconv.FormatBool(success)})
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, actualMetric.(prometheus.Histogram).Write(m))
|
||||
require.Equal(t, uint64(0), m.Histogram.GetSampleCount())
|
||||
require.Equal(t, 0.0, m.Histogram.GetSampleSum())
|
||||
|
||||
mi.ObservePluginHookDuration(pluginID, hookName, success, elapsed)
|
||||
actualMetric, err = miImpl.PluginHookTimeHistogram.GetMetricWith(prometheus.Labels{"plugin_id": pluginID, "hook_name": hookName, "success": strconv.FormatBool(success)})
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, actualMetric.(prometheus.Histogram).Write(m))
|
||||
require.Equal(t, uint64(1), m.Histogram.GetSampleCount())
|
||||
require.InDelta(t, elapsed, m.Histogram.GetSampleSum(), 0.001)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("test ObservePluginAPIDuration", func(t *testing.T) {
|
||||
pluginID := "id_"
|
||||
apiName := "api_"
|
||||
elapsed := 999.1
|
||||
m := &prometheusModels.Metric{}
|
||||
|
||||
for _, success := range []bool{true, false} {
|
||||
actualMetric, err := miImpl.PluginAPITimeHistogram.GetMetricWith(prometheus.Labels{"plugin_id": pluginID, "api_name": apiName, "success": strconv.FormatBool(success)})
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, actualMetric.(prometheus.Histogram).Write(m))
|
||||
require.Equal(t, uint64(0), m.Histogram.GetSampleCount())
|
||||
require.Equal(t, 0.0, m.Histogram.GetSampleSum())
|
||||
|
||||
mi.ObservePluginAPIDuration(pluginID, apiName, success, elapsed)
|
||||
actualMetric, err = miImpl.PluginAPITimeHistogram.GetMetricWith(prometheus.Labels{"plugin_id": pluginID, "api_name": apiName, "success": strconv.FormatBool(success)})
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, actualMetric.(prometheus.Histogram).Write(m))
|
||||
require.Equal(t, uint64(1), m.Histogram.GetSampleCount())
|
||||
require.InDelta(t, elapsed, m.Histogram.GetSampleSum(), 0.001)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("test ObservePluginMultiHookIterationDuration", func(t *testing.T) {
|
||||
pluginID := "id_"
|
||||
elapsed := 999.1
|
||||
m := &prometheusModels.Metric{}
|
||||
|
||||
actualMetric, err := miImpl.PluginMultiHookTimeHistogram.GetMetricWith(prometheus.Labels{"plugin_id": pluginID})
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, actualMetric.(prometheus.Histogram).Write(m))
|
||||
require.Equal(t, uint64(0), m.Histogram.GetSampleCount())
|
||||
require.Equal(t, 0.0, m.Histogram.GetSampleSum())
|
||||
|
||||
mi.ObservePluginMultiHookIterationDuration(pluginID, elapsed)
|
||||
actualMetric, err = miImpl.PluginMultiHookTimeHistogram.GetMetricWith(prometheus.Labels{"plugin_id": pluginID})
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, actualMetric.(prometheus.Histogram).Write(m))
|
||||
require.Equal(t, uint64(1), m.Histogram.GetSampleCount())
|
||||
require.InDelta(t, elapsed, m.Histogram.GetSampleSum(), 0.001)
|
||||
})
|
||||
|
||||
t.Run("test ObservePluginMultiHookDuration", func(t *testing.T) {
|
||||
elapsed := 50.0
|
||||
m := &prometheusModels.Metric{}
|
||||
|
||||
require.NoError(t, miImpl.PluginMultiHookServerTimeHistogram.Write(m))
|
||||
require.InDelta(t, 0.0, m.Histogram.GetSampleSum(), 0.001)
|
||||
|
||||
mi.ObservePluginMultiHookDuration(elapsed)
|
||||
require.NoError(t, miImpl.PluginMultiHookServerTimeHistogram.Write(m))
|
||||
require.InDelta(t, elapsed, m.Histogram.GetSampleSum(), 0.001)
|
||||
})
|
||||
}
|
||||
|
||||
func TestExtractDBCluster(t *testing.T) {
|
||||
testCases := []struct {
|
||||
description string
|
||||
driver string
|
||||
connectionStr string
|
||||
expectedClusterName string
|
||||
}{
|
||||
{
|
||||
description: "postgres full",
|
||||
driver: "postgres",
|
||||
connectionStr: "postgres://user1234:password1234@rds-cluster-multitenant-1234-postgres.cluster-abcd.us-east-1.rds.amazonaws.com:5432/cloud?connect_timeout=10",
|
||||
expectedClusterName: "rds-cluster-multitenant-1234-postgres",
|
||||
},
|
||||
{
|
||||
description: "postgres no credentials",
|
||||
driver: "postgres",
|
||||
connectionStr: "postgres://rds-cluster-multitenant-1234-postgres.cluster-abcd.us-east-1.rds.amazonaws.com:5432/cloud?connect_timeout=10",
|
||||
expectedClusterName: "rds-cluster-multitenant-1234-postgres",
|
||||
},
|
||||
{
|
||||
description: "mysql full",
|
||||
driver: "mysql",
|
||||
connectionStr: "mysql://user1234:password1234@tcp(rds-cluster-multitenant-1234-mysql.cluster-abcd.us-east-1.rds.amazonaws.com:3306)/cloud?charset=utf8mb4%2Cutf8&readTimeout=30s&writeTimeout=30s&tls=skip-verify",
|
||||
expectedClusterName: "rds-cluster-multitenant-1234-mysql",
|
||||
},
|
||||
{
|
||||
description: "mysql no credentials",
|
||||
driver: "mysql",
|
||||
connectionStr: "mysql://tcp(rds-cluster-multitenant-1234-mysql.cluster-abcd.us-east-1.rds.amazonaws.com:3306)/cloud?charset=utf8mb4%2Cutf8&readTimeout=30s&writeTimeout=30s&tls=skip-verify",
|
||||
expectedClusterName: "rds-cluster-multitenant-1234-mysql",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
host, err := extractDBCluster(tc.driver, tc.connectionStr)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, tc.expectedClusterName, host)
|
||||
})
|
||||
}
|
||||
}
|
5
server/enterprise/placeholder.go
Normal file
5
server/enterprise/placeholder.go
Normal file
@ -0,0 +1,5 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.enterprise for license information.
|
||||
|
||||
// Ensure this is a valid package even when build tags preclude building anything in it.
|
||||
package enterprise
|
@ -51,6 +51,7 @@ require (
|
||||
github.com/opentracing/opentracing-go v1.2.0
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.17.0
|
||||
github.com/prometheus/client_model v0.5.0
|
||||
github.com/reflog/dateconstraints v0.2.1
|
||||
github.com/rs/cors v1.10.1
|
||||
github.com/rudderlabs/analytics-go v3.3.3+incompatible
|
||||
@ -179,7 +180,6 @@ require (
|
||||
github.com/philhofer/fwd v1.1.2 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.19 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/prometheus/client_model v0.5.0 // indirect
|
||||
github.com/prometheus/common v0.45.0 // indirect
|
||||
github.com/prometheus/procfs v0.12.0 // indirect
|
||||
github.com/redis/go-redis/v9 v9.3.0 // indirect
|
||||
|
Loading…
Reference in New Issue
Block a user