github.com/cs3org/reva/v2@v2.27.7/pkg/metrics/metrics.go (about)

     1  // Copyright 2018-2021 CERN
     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  //
    15  // In applying this license, CERN does not waive the privileges and immunities
    16  // granted to it by virtue of its status as an Intergovernmental Organization
    17  // or submit itself to any jurisdiction.
    18  
    19  package metrics
    20  
    21  /*
    22  Metrics registers OpenCensus data views of the metrics.
    23  Metrics initializes the driver as specified in the configuration.
    24  */
    25  import (
    26  	"context"
    27  	"os"
    28  	"time"
    29  
    30  	"github.com/cs3org/reva/v2/pkg/metrics/config"
    31  	"github.com/cs3org/reva/v2/pkg/metrics/driver/registry"
    32  	"github.com/cs3org/reva/v2/pkg/metrics/reader"
    33  
    34  	"github.com/cs3org/reva/v2/pkg/logger"
    35  	"go.opencensus.io/stats"
    36  	"go.opencensus.io/stats/view"
    37  )
    38  
    39  // Init intializes metrics according to the specified configuration
    40  func Init(conf *config.Config) error {
    41  	log := logger.New().With().Int("pid", os.Getpid()).Logger()
    42  
    43  	driver := registry.GetDriver(conf.MetricsDataDriverType)
    44  
    45  	if driver == nil {
    46  		log.Info().Msg("No metrics are being recorded.")
    47  		// No error but just don't proceed with metrics
    48  		return nil
    49  	}
    50  
    51  	// configure the driver
    52  	err := driver.Configure(conf)
    53  	if err != nil {
    54  		return err
    55  	}
    56  
    57  	m := &Metrics{
    58  		dataDriver:           driver,
    59  		NumUsersMeasure:      stats.Int64("cs3_org_sciencemesh_site_total_num_users", "The total number of users within this site", stats.UnitDimensionless),
    60  		NumGroupsMeasure:     stats.Int64("cs3_org_sciencemesh_site_total_num_groups", "The total number of groups within this site", stats.UnitDimensionless),
    61  		AmountStorageMeasure: stats.Int64("cs3_org_sciencemesh_site_total_amount_storage", "The total amount of storage used within this site", stats.UnitBytes),
    62  	}
    63  
    64  	if err := view.Register(
    65  		m.getNumUsersView(),
    66  		m.getNumGroupsView(),
    67  		m.getAmountStorageView(),
    68  	); err != nil {
    69  		return err
    70  	}
    71  
    72  	// periodically record metrics data
    73  	go func() {
    74  		for {
    75  			if err := m.recordMetrics(); err != nil {
    76  				log.Error().Err(err).Msg("Metrics recording failed.")
    77  			}
    78  			<-time.After(time.Millisecond * time.Duration(conf.MetricsRecordInterval))
    79  		}
    80  	}()
    81  
    82  	return nil
    83  }
    84  
    85  // Metrics the metrics struct
    86  type Metrics struct {
    87  	dataDriver           reader.Reader // the metrics data driver is an implemention of Reader
    88  	NumUsersMeasure      *stats.Int64Measure
    89  	NumGroupsMeasure     *stats.Int64Measure
    90  	AmountStorageMeasure *stats.Int64Measure
    91  }
    92  
    93  // RecordMetrics records the latest metrics from the metrics data source as OpenCensus stats views.
    94  func (m *Metrics) recordMetrics() error {
    95  	// record all latest metrics
    96  	if m.dataDriver != nil {
    97  		m.recordNumUsers()
    98  		m.recordNumGroups()
    99  		m.recordAmountStorage()
   100  	}
   101  	return nil
   102  }
   103  
   104  // recordNumUsers records the latest number of site users figure
   105  func (m *Metrics) recordNumUsers() {
   106  	ctx := context.Background()
   107  	stats.Record(ctx, m.NumUsersMeasure.M(m.dataDriver.GetNumUsers()))
   108  }
   109  
   110  func (m *Metrics) getNumUsersView() *view.View {
   111  	return &view.View{
   112  		Name:        m.NumUsersMeasure.Name(),
   113  		Description: m.NumUsersMeasure.Description(),
   114  		Measure:     m.NumUsersMeasure,
   115  		Aggregation: view.LastValue(),
   116  	}
   117  }
   118  
   119  // recordNumGroups records the latest number of site groups figure
   120  func (m *Metrics) recordNumGroups() {
   121  	ctx := context.Background()
   122  	stats.Record(ctx, m.NumGroupsMeasure.M(m.dataDriver.GetNumGroups()))
   123  }
   124  
   125  func (m *Metrics) getNumGroupsView() *view.View {
   126  	return &view.View{
   127  		Name:        m.NumGroupsMeasure.Name(),
   128  		Description: m.NumGroupsMeasure.Description(),
   129  		Measure:     m.NumGroupsMeasure,
   130  		Aggregation: view.LastValue(),
   131  	}
   132  }
   133  
   134  // recordAmountStorage records the latest amount storage figure
   135  func (m *Metrics) recordAmountStorage() {
   136  	ctx := context.Background()
   137  	stats.Record(ctx, m.AmountStorageMeasure.M(m.dataDriver.GetAmountStorage()))
   138  }
   139  
   140  func (m *Metrics) getAmountStorageView() *view.View {
   141  	return &view.View{
   142  		Name:        m.AmountStorageMeasure.Name(),
   143  		Description: m.AmountStorageMeasure.Description(),
   144  		Measure:     m.AmountStorageMeasure,
   145  		Aggregation: view.LastValue(),
   146  	}
   147  }