mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
[MM-23882] Include database server version in telemetry (#14258)
* Add database server version to telemetry Also added a new query in the store to retrieve the database version * Add test for the GetDbVersion function * More drivers in the tests Co-authored-by: mattermod <mattermod@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
f6f025aeaa
commit
698b4b6934
@@ -802,6 +802,10 @@ func (a *App) trackServer() {
|
||||
data["system_admins"] = scr
|
||||
}
|
||||
|
||||
if scr, err := a.Srv().Store.GetDbVersion(); err == nil {
|
||||
data["database_version"] = scr
|
||||
}
|
||||
|
||||
a.SendDiagnostic(TRACK_SERVER, data)
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ type SqlStore interface {
|
||||
GetMaster() *gorp.DbMap
|
||||
GetSearchReplica() *gorp.DbMap
|
||||
GetReplica() *gorp.DbMap
|
||||
GetDbVersion() (string, error)
|
||||
TotalMasterDbConnections() int
|
||||
TotalReadDbConnections() int
|
||||
TotalSearchDbConnections() int
|
||||
|
||||
@@ -301,6 +301,27 @@ func (ss *SqlSupplier) GetCurrentSchemaVersion() string {
|
||||
return version
|
||||
}
|
||||
|
||||
func (ss *SqlSupplier) GetDbVersion() (string, error) {
|
||||
var sqlVersion string
|
||||
if ss.DriverName() == model.DATABASE_DRIVER_POSTGRES {
|
||||
sqlVersion = `SHOW server_version`
|
||||
} else if ss.DriverName() == model.DATABASE_DRIVER_MYSQL {
|
||||
sqlVersion = `SELECT version()`
|
||||
} else if ss.DriverName() == model.DATABASE_DRIVER_SQLITE {
|
||||
sqlVersion = `SELECT sqlite_version()`
|
||||
} else {
|
||||
return "", errors.New("Not supported driver")
|
||||
}
|
||||
|
||||
version, err := ss.GetReplica().SelectStr(sqlVersion)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return version, nil
|
||||
|
||||
}
|
||||
|
||||
func (ss *SqlSupplier) GetMaster() *gorp.DbMap {
|
||||
return ss.master
|
||||
}
|
||||
|
||||
@@ -4,14 +4,17 @@
|
||||
package sqlstore_test
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/gorp"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v5/store/sqlstore"
|
||||
"github.com/mattermost/mattermost-server/v5/store/storetest"
|
||||
)
|
||||
|
||||
func TestGetReplica(t *testing.T) {
|
||||
@@ -73,24 +76,10 @@ func TestGetReplica(t *testing.T) {
|
||||
t.Run(testCase.Description, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
driverName := model.DATABASE_DRIVER_SQLITE
|
||||
dataSource := ":memory:"
|
||||
maxIdleConns := 1
|
||||
connMaxLifetimeMilliseconds := 3600000
|
||||
maxOpenConns := 1
|
||||
queryTimeout := 5
|
||||
|
||||
settings := model.SqlSettings{
|
||||
DriverName: &driverName,
|
||||
DataSource: &dataSource,
|
||||
MaxIdleConns: &maxIdleConns,
|
||||
ConnMaxLifetimeMilliseconds: &connMaxLifetimeMilliseconds,
|
||||
MaxOpenConns: &maxOpenConns,
|
||||
QueryTimeout: &queryTimeout,
|
||||
DataSourceReplicas: testCase.DataSourceReplicas,
|
||||
DataSourceSearchReplicas: testCase.DataSourceSearchReplicas,
|
||||
}
|
||||
supplier := sqlstore.NewSqlSupplier(settings, nil)
|
||||
settings := makeSqlSettings(model.DATABASE_DRIVER_SQLITE)
|
||||
settings.DataSourceReplicas = testCase.DataSourceReplicas
|
||||
settings.DataSourceSearchReplicas = testCase.DataSourceSearchReplicas
|
||||
supplier := sqlstore.NewSqlSupplier(*settings, nil)
|
||||
|
||||
replicas := make(map[*gorp.DbMap]bool)
|
||||
for i := 0; i < 5; i++ {
|
||||
@@ -142,6 +131,26 @@ func TestGetReplica(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetDbVersion(t *testing.T) {
|
||||
testDrivers := []string{
|
||||
model.DATABASE_DRIVER_POSTGRES,
|
||||
model.DATABASE_DRIVER_MYSQL,
|
||||
model.DATABASE_DRIVER_SQLITE,
|
||||
}
|
||||
|
||||
for _, driver := range testDrivers {
|
||||
t.Run("Should return db version for "+driver, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
settings := makeSqlSettings(driver)
|
||||
supplier := sqlstore.NewSqlSupplier(*settings, nil)
|
||||
|
||||
version, err := supplier.GetDbVersion()
|
||||
require.Nil(t, err)
|
||||
require.Regexp(t, regexp.MustCompile(`\d+\.\d+(\.\d+)?`), version)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAllConns(t *testing.T) {
|
||||
t.Parallel()
|
||||
testCases := []struct {
|
||||
@@ -210,27 +219,43 @@ func TestGetAllConns(t *testing.T) {
|
||||
testCase := testCase
|
||||
t.Run(testCase.Description, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
driverName := model.DATABASE_DRIVER_SQLITE
|
||||
dataSource := ":memory:"
|
||||
maxIdleConns := 1
|
||||
connMaxLifetimeMilliseconds := 3600000
|
||||
maxOpenConns := 1
|
||||
queryTimeout := 5
|
||||
|
||||
settings := model.SqlSettings{
|
||||
DriverName: &driverName,
|
||||
DataSource: &dataSource,
|
||||
MaxIdleConns: &maxIdleConns,
|
||||
ConnMaxLifetimeMilliseconds: &connMaxLifetimeMilliseconds,
|
||||
MaxOpenConns: &maxOpenConns,
|
||||
QueryTimeout: &queryTimeout,
|
||||
DataSourceReplicas: testCase.DataSourceReplicas,
|
||||
DataSourceSearchReplicas: testCase.DataSourceSearchReplicas,
|
||||
}
|
||||
supplier := sqlstore.NewSqlSupplier(settings, nil)
|
||||
settings := makeSqlSettings(model.DATABASE_DRIVER_SQLITE)
|
||||
settings.DataSourceReplicas = testCase.DataSourceReplicas
|
||||
settings.DataSourceSearchReplicas = testCase.DataSourceSearchReplicas
|
||||
supplier := sqlstore.NewSqlSupplier(*settings, nil)
|
||||
|
||||
assert.Len(t, supplier.GetAllConns(), testCase.ExpectedNumConnections)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func makeSqlSettings(driver string) *model.SqlSettings {
|
||||
switch driver {
|
||||
case model.DATABASE_DRIVER_POSTGRES:
|
||||
return storetest.MakeSqlSettings(driver)
|
||||
case model.DATABASE_DRIVER_MYSQL:
|
||||
return storetest.MakeSqlSettings(driver)
|
||||
case model.DATABASE_DRIVER_SQLITE:
|
||||
return makeSqliteSettings()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func makeSqliteSettings() *model.SqlSettings {
|
||||
driverName := model.DATABASE_DRIVER_SQLITE
|
||||
dataSource := ":memory:"
|
||||
maxIdleConns := 1
|
||||
connMaxLifetimeMilliseconds := 3600000
|
||||
maxOpenConns := 1
|
||||
queryTimeout := 5
|
||||
|
||||
return &model.SqlSettings{
|
||||
DriverName: &driverName,
|
||||
DataSource: &dataSource,
|
||||
MaxIdleConns: &maxIdleConns,
|
||||
ConnMaxLifetimeMilliseconds: &connMaxLifetimeMilliseconds,
|
||||
MaxOpenConns: &maxOpenConns,
|
||||
QueryTimeout: &queryTimeout,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ type Store interface {
|
||||
UnlockFromMaster()
|
||||
DropAllTables()
|
||||
GetCurrentSchemaVersion() string
|
||||
GetDbVersion() (string, error)
|
||||
TotalMasterDbConnections() int
|
||||
TotalReadDbConnections() int
|
||||
TotalSearchDbConnections() int
|
||||
|
||||
@@ -379,6 +379,27 @@ func (_m *SqlStore) GetCurrentSchemaVersion() string {
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetDbVersion provides a mock function with given fields:
|
||||
func (_m *SqlStore) GetDbVersion() (string, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 string
|
||||
if rf, ok := ret.Get(0).(func() string); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Get(0).(string)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func() error); ok {
|
||||
r1 = rf()
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetMaster provides a mock function with given fields:
|
||||
func (_m *SqlStore) GetMaster() *gorp.DbMap {
|
||||
ret := _m.Called()
|
||||
|
||||
@@ -232,6 +232,27 @@ func (_m *Store) GetCurrentSchemaVersion() string {
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetDbVersion provides a mock function with given fields:
|
||||
func (_m *Store) GetDbVersion() (string, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 string
|
||||
if rf, ok := ret.Get(0).(func() string); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Get(0).(string)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func() error); ok {
|
||||
r1 = rf()
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Group provides a mock function with given fields:
|
||||
func (_m *Store) Group() store.GroupStore {
|
||||
ret := _m.Called()
|
||||
|
||||
@@ -87,6 +87,7 @@ func (s *Store) Close() { /* do nothing */ }
|
||||
func (s *Store) LockToMaster() { /* do nothing */ }
|
||||
func (s *Store) UnlockFromMaster() { /* do nothing */ }
|
||||
func (s *Store) DropAllTables() { /* do nothing */ }
|
||||
func (s *Store) GetDbVersion() (string, error) { return "", nil }
|
||||
func (s *Store) TotalMasterDbConnections() int { return 1 }
|
||||
func (s *Store) TotalReadDbConnections() int { return 1 }
|
||||
func (s *Store) TotalSearchDbConnections() int { return 1 }
|
||||
|
||||
Reference in New Issue
Block a user