Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Read metrics from file (v2) #1118

Merged
merged 43 commits into from
Sep 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
5393f65
Configuration for metrics.
Jul 14, 2020
7783939
Dummy (test) driver implementation.
Jul 14, 2020
e7f2c0c
JSON metrics data file driver implementation.
Jul 14, 2020
8c25641
Metrics now uses data driver to access the actual metrics data.
Jul 14, 2020
0935163
deleted
Jul 14, 2020
db1fc17
New configuration for metrics.
Jul 14, 2020
c28411c
Changed package name, dummy driver struct name.
Jul 14, 2020
dac5a4f
Changed package name.
Jul 14, 2020
256b4af
Changed package name.
Jul 14, 2020
0eaecaf
Struct name changed to please hound bot.
Jul 14, 2020
51c6b14
Moved.
Jul 14, 2020
81a59e0
Rebase on SysInfo metrics
Jul 14, 2020
7bb316a
Fixed unnecessary conversion.
Jul 14, 2020
db498a9
Changelog added.
Jul 15, 2020
55ce5a9
Fixed: custom json file location not used.
Jul 15, 2020
c3b0242
Use sharedconfig instead.
Aug 25, 2020
3616aec
Does not need config.
Aug 25, 2020
3e503b9
Read file location from sharedconfig.
Aug 25, 2020
cf0eac5
Add metrics data driver type, location.
Aug 25, 2020
2f86b9b
Self initialize and periodic metrics data recording. Use sharedconfig.
Aug 25, 2020
5e60a12
Metrics conf moved to shared block.
Aug 25, 2020
1059a7a
Use driver type dummy by default.
Aug 25, 2020
9d1d53f
Fixed error check.
Aug 25, 2020
29f220a
Fixed title.
Aug 25, 2020
db62bc1
Reset sharedconf. Metrics does not use it.
Sep 4, 2020
c271c33
Add metrics drivers to loader.
Sep 4, 2020
e3f47c5
Add metrics service to loader.
Sep 4, 2020
6191a44
Config for metrics.
Sep 4, 2020
e16eb4a
Drivers register themselfes.
Sep 4, 2020
93180dc
New metrics service.
Sep 4, 2020
c418d20
Driver register.
Sep 4, 2020
f9b3103
Use register to get configured driver.
Sep 4, 2020
e419e36
Moved to dedicated namespace.
Sep 4, 2020
e6a14f9
Changelog added.
Sep 4, 2020
ab30488
Renamed.
Sep 4, 2020
6aa7da8
New parameter: metrics_record_interval
Sep 4, 2020
69d8a66
Init returns error.
Sep 4, 2020
66cd435
Init returns error.
Sep 4, 2020
c6bbced
Fix missing service line.
Sep 9, 2020
1f8b376
Load specific drivers in pkg loader.
Sep 9, 2020
375b588
Remove prefix.
Sep 9, 2020
3cf7ae2
Remove prefix.
Sep 9, 2020
473da68
Clean up.
Sep 9, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions changelog/unreleased/read-metrics-from-file-2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Enhancement: Metrics module can be configured to retrieve metrics data from file

- Export site metrics in Prometheus #698

https://github.com/cs3org/reva/pull/1118
2 changes: 1 addition & 1 deletion cmd/revad/runtime/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (
_ "github.com/cs3org/reva/internal/http/services/loader"
_ "github.com/cs3org/reva/pkg/auth/manager/loader"
_ "github.com/cs3org/reva/pkg/auth/registry/loader"
_ "github.com/cs3org/reva/pkg/metrics"
_ "github.com/cs3org/reva/pkg/metrics/driver/loader"
_ "github.com/cs3org/reva/pkg/ocm/invite/manager/loader"
_ "github.com/cs3org/reva/pkg/ocm/provider/authorizer/loader"
_ "github.com/cs3org/reva/pkg/ocm/share/manager/loader"
Expand Down
11 changes: 9 additions & 2 deletions examples/metrics/metrics.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
[shared]
jwt_secret = "Pive-Fumkiu4"

[http.services.metrics]
# one of dummy, json.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These need to be defined for the service, not shared conf.

metrics_data_driver_type = "dummy"
# if left unspecified location /var/tmp/reva/metrics/metricsdata.json is used (for driver type json).
metrics_data_location = ""
# metrics recording interval in milliseconds
metrics_record_interval = 5000

[http.services.prometheus]

[http]
address = "0.0.0.0:5550"
address = "0.0.0.0:5550"
1 change: 1 addition & 0 deletions internal/http/services/loader/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
_ "github.com/cs3org/reva/internal/http/services/helloworld"
_ "github.com/cs3org/reva/internal/http/services/mentix"
_ "github.com/cs3org/reva/internal/http/services/meshdirectory"
_ "github.com/cs3org/reva/internal/http/services/metrics"
_ "github.com/cs3org/reva/internal/http/services/ocmd"
_ "github.com/cs3org/reva/internal/http/services/oidcprovider"
_ "github.com/cs3org/reva/internal/http/services/owncloud/ocdav"
Expand Down
92 changes: 92 additions & 0 deletions internal/http/services/metrics/metrics.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Copyright 2018-2020 CERN
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// In applying this license, CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

package metrics

/*
This service initializes the metrics package according to the metrics configuration.
*/
import (
"net/http"
"os"

"github.com/cs3org/reva/pkg/logger"
"github.com/mitchellh/mapstructure"
"github.com/rs/zerolog"

"github.com/cs3org/reva/pkg/metrics"
"github.com/cs3org/reva/pkg/metrics/config"
"github.com/cs3org/reva/pkg/rhttp/global"
)

func init() {
global.Register(serviceName, New)
}

const (
serviceName = "metrics"
)

// Close is called when this service is being stopped.
func (s *svc) Close() error {
return nil
}

// Prefix returns the main endpoint of this service.
func (s *svc) Prefix() string {
return ""
}

// Unprotected returns all endpoints that can be queried without prior authorization.
func (s *svc) Unprotected() []string {
return []string{}
}

// Handler serves all HTTP requests.
func (s *svc) Handler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log := logger.New().With().Int("pid", os.Getpid()).Logger()
if _, err := w.Write([]byte("This is the metrics service.\n")); err != nil {
log.Error().Err(err).Msg("error writing metrics response")
}
})
}

// New returns a new metrics service.
func New(m map[string]interface{}, log *zerolog.Logger) (global.Service, error) {
// Prepare the configuration
conf := &config.Config{}
if err := mapstructure.Decode(m, conf); err != nil {
return nil, err
}

conf.Init()

// initialize metrics using the configuration
err := metrics.Init(conf)
if err != nil {
return nil, err
}

// Create the service
s := &svc{}
return s, nil
}

type svc struct {
}
2 changes: 0 additions & 2 deletions internal/http/services/prometheus/prometheus.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ import (
"go.opencensus.io/stats/view"

"github.com/cs3org/reva/pkg/rhttp/global"
// Initializes goroutines which periodically update stats
_ "github.com/cs3org/reva/pkg/metrics/reader/dummy"
)

func init() {
Expand Down
39 changes: 39 additions & 0 deletions pkg/metrics/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright 2018-2020 CERN
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// In applying this license, CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

package config

// Config holds the config options that need to be passed down to the metrics reader(driver)
type Config struct {
MetricsDataDriverType string `mapstructure:"metrics_data_driver_type"`
MetricsDataLocation string `mapstructure:"metrics_data_location"`
MetricsRecordInterval int `mapstructure:"metrics_record_interval"`
}

// Init sets sane defaults
func (c *Config) Init() {
if c.MetricsDataDriverType == "json" {
// default values
if c.MetricsDataLocation == "" {
c.MetricsDataLocation = "/var/tmp/reva/metrics/metricsdata.json"
}
}
if c.MetricsRecordInterval == 0 {
c.MetricsRecordInterval = 5000
}
}
60 changes: 60 additions & 0 deletions pkg/metrics/driver/dummy/dummy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright 2018-2020 CERN
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// In applying this license, CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

package dummy

import (
"math/rand"

"github.com/cs3org/reva/pkg/metrics/config"
"github.com/cs3org/reva/pkg/metrics/driver/registry"
)

func init() {
driver := &MetricsDummyDriver{}
registry.Register(driverName(), driver)
}

func driverName() string {
return "dummy"
}

// MetricsDummyDriver the MetricsDummyDriver struct
type MetricsDummyDriver struct {
}

// Configure configures this driver
func (d *MetricsDummyDriver) Configure(c *config.Config) error {
// no configuration necessary
return nil
}

// GetNumUsers returns the number of site users; it's a random number
func (d *MetricsDummyDriver) GetNumUsers() int64 {
return int64(rand.Intn(30000))
}

// GetNumGroups returns the number of site groups; it's a random number
func (d *MetricsDummyDriver) GetNumGroups() int64 {
return int64(rand.Intn(200))
}

// GetAmountStorage returns the amount of site storage used; it's a random amount
func (d *MetricsDummyDriver) GetAmountStorage() int64 {
return int64(rand.Intn(70000000000))
}
98 changes: 98 additions & 0 deletions pkg/metrics/driver/json/json.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright 2018-2020 CERN
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// In applying this license, CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

package json

import (
"encoding/json"
"errors"
"io/ioutil"
"os"

"github.com/cs3org/reva/pkg/metrics/driver/registry"

"github.com/cs3org/reva/pkg/logger"
"github.com/cs3org/reva/pkg/metrics/config"
"github.com/rs/zerolog"
)

var log zerolog.Logger

func init() {
log = logger.New().With().Int("pid", os.Getpid()).Logger()
driver := &MetricsJSONDriver{}
registry.Register(driverName(), driver)
}

func driverName() string {
return "json"
}

// readJSON always returns a data object but logs the error in case reading the json fails.
func readJSON(driver *MetricsJSONDriver) *data {
data := &data{}

file, err := ioutil.ReadFile(driver.metricsDataLocation)
if err != nil {
log.Error().Err(err).Str("location", driver.metricsDataLocation).Msg("Unable to read json file from location.")
}
err = json.Unmarshal(file, data)
if err != nil {
log.Error().Err(err).Msg("Unable to unmarshall json file.")
}

return data
}

type data struct {
NumUsers int64 `json:"cs3_org_sciencemesh_site_total_num_users"`
NumGroups int64 `json:"cs3_org_sciencemesh_site_total_num_groups"`
AmountStorage int64 `json:"cs3_org_sciencemesh_site_total_amount_storage"`
}

// MetricsJSONDriver the JsonDriver struct
type MetricsJSONDriver struct {
metricsDataLocation string
}

// Configure configures this driver
func (d *MetricsJSONDriver) Configure(c *config.Config) error {
if c.MetricsDataLocation == "" {
err := errors.New("Unable to initialize a metrics data driver, has the data location (metrics_data_location) been configured?")
return err
}

d.metricsDataLocation = c.MetricsDataLocation

return nil
}

// GetNumUsers returns the number of site users
func (d *MetricsJSONDriver) GetNumUsers() int64 {
return readJSON(d).NumUsers
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're reading the file each time for all the three metrics, but they would be accessed simultaneously. Can you see if we can prevent reading the file three times?

Copy link
Contributor Author

@redblom redblom Sep 9, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ishank011 Hmm, that's like the initial implementation where the whole pkg got initialized on each metrics server call and all methods where read in one go. It is my recollection that it was decided to changed it to be like this.
I have to think about this.
Maybe we can leave it for now?

}

// GetNumGroups returns the number of site groups
func (d *MetricsJSONDriver) GetNumGroups() int64 {
return readJSON(d).NumGroups
}

// GetAmountStorage returns the amount of site storage used
func (d *MetricsJSONDriver) GetAmountStorage() int64 {
return readJSON(d).AmountStorage
}
26 changes: 26 additions & 0 deletions pkg/metrics/driver/loader/loader.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright 2018-2020 CERN
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// In applying this license, CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

package loader

import (
// Load metrics drivers.
_ "github.com/cs3org/reva/pkg/metrics/driver/dummy"
_ "github.com/cs3org/reva/pkg/metrics/driver/json"
// Add your own here
)
Loading