datasource.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package datasource
  15. import (
  16. "context"
  17. "time"
  18. "golang.org/x/sync/errgroup"
  19. "yunion.io/x/log"
  20. "yunion.io/x/pkg/errors"
  21. "yunion.io/x/pkg/util/httputils"
  22. "yunion.io/x/pkg/util/stringutils"
  23. "yunion.io/x/pkg/util/wait"
  24. commontsdb "yunion.io/x/onecloud/pkg/cloudcommon/tsdb"
  25. "yunion.io/x/onecloud/pkg/mcclient/auth"
  26. "yunion.io/x/onecloud/pkg/monitor/options"
  27. "yunion.io/x/onecloud/pkg/monitor/registry"
  28. "yunion.io/x/onecloud/pkg/monitor/tsdb"
  29. )
  30. func init() {
  31. registry.RegisterService(GetManager())
  32. }
  33. var (
  34. dsMan *dataSourceManager
  35. )
  36. type DataSourceManager interface {
  37. registry.Service
  38. GetDefaultSource(db string) *tsdb.DataSource
  39. }
  40. func GetManager() DataSourceManager {
  41. if dsMan == nil {
  42. dsMan = newDataSourceManager()
  43. }
  44. return dsMan
  45. }
  46. func GetDefaultSource(db string) (*tsdb.DataSource, error) {
  47. src := GetManager().GetDefaultSource(db)
  48. if src == nil {
  49. return nil, errors.Errorf("default data source is not initialization")
  50. }
  51. return src, nil
  52. }
  53. func GetDefaultQueryEndpoint() (tsdb.TsdbQueryEndpoint, error) {
  54. ds, err := GetDefaultSource("")
  55. if err != nil {
  56. return nil, errors.Wrap(err, "get default datasource")
  57. }
  58. return tsdb.GetTsdbQueryEndpointFor(ds)
  59. }
  60. func newDataSourceManager() *dataSourceManager {
  61. return &dataSourceManager{
  62. defaultDS: nil,
  63. }
  64. }
  65. type dataSourceManager struct {
  66. defaultDS *tsdb.DataSource
  67. }
  68. func (m *dataSourceManager) Init() error {
  69. return m.initDefaultDataSource(context.Background())
  70. }
  71. func (m *dataSourceManager) Run(ctx context.Context) error {
  72. errgrp, ctx := errgroup.WithContext(ctx)
  73. errgrp.Go(func() error {
  74. m.run(ctx)
  75. return nil
  76. })
  77. return errgrp.Wait()
  78. }
  79. func (m *dataSourceManager) GetDefaultSource(db string) *tsdb.DataSource {
  80. ds := m.defaultDS
  81. return &tsdb.DataSource{
  82. Id: ds.Id,
  83. Name: ds.Name,
  84. Type: ds.Type,
  85. Url: ds.Url,
  86. User: ds.User,
  87. Password: ds.Password,
  88. Database: db,
  89. BasicAuth: ds.BasicAuth,
  90. BasicAuthUser: ds.BasicAuthUser,
  91. BasicAuthPassword: ds.BasicAuthPassword,
  92. TimeInterval: ds.TimeInterval,
  93. Updated: ds.Updated,
  94. }
  95. }
  96. func (man *dataSourceManager) shouldChangeDataSource(dsType string, url string) bool {
  97. if man.defaultDS == nil {
  98. return true
  99. }
  100. if man.defaultDS.Type != dsType {
  101. return true
  102. }
  103. if man.defaultDS.Url != url {
  104. return true
  105. }
  106. return false
  107. }
  108. func (man *dataSourceManager) setDataSource(dsType string, url string) {
  109. if !man.shouldChangeDataSource(dsType, url) {
  110. return
  111. }
  112. log.Infof("set TSDB data source %q: %q", dsType, url)
  113. man.defaultDS = &tsdb.DataSource{
  114. Id: stringutils.UUID4(),
  115. Name: dsType,
  116. Type: dsType,
  117. Url: url,
  118. Updated: time.Now(),
  119. }
  120. }
  121. func (man *dataSourceManager) initDefaultDataSource(ctx context.Context) error {
  122. region := options.Options.Region
  123. epType := options.Options.SessionEndpointType
  124. s := auth.GetAdminSession(ctx, region)
  125. //dsSvc := options.Options.MonitorDataSource
  126. if s == nil {
  127. return errors.Errorf("get empty public session for region %s", region)
  128. }
  129. source, err := commontsdb.GetDefaultServiceSource(s, epType)
  130. if err != nil {
  131. return errors.Wrap(err, "get default TSDB source")
  132. }
  133. dsSvc := source.Type
  134. if err := tsdb.IsValidDataSource(dsSvc); err != nil {
  135. return errors.Wrapf(err, "invalid type %q", dsSvc)
  136. }
  137. url, err := s.GetServiceURL(dsSvc, epType, httputils.POST)
  138. if err != nil {
  139. return errors.Errorf("get %q public url: %v", dsSvc, err)
  140. }
  141. man.setDataSource(dsSvc, url)
  142. return nil
  143. }
  144. func (m *dataSourceManager) run(ctx context.Context) {
  145. wait.Forever(func() {
  146. if err := m.initDefaultDataSource(ctx); err != nil {
  147. log.Errorf("init default source")
  148. }
  149. }, 30*time.Second)
  150. }