metrics

package module
v0.0.1-alpha2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 27, 2023 License: MIT Imports: 25 Imported by: 4

README

MetricNexus

MetricNexus is a library that provides a centralized source of metrics for Prometheus to scrape. It eliminates the need for manual configuration updates, firewall rule creation, and other repetitive tasks when new machines join an environment or cluster. The library consists of a server and a client, both leveraging the fiber framework for efficient performance.

Key Features

  • Centralized Metrics: The server acts as a single source of metrics, enabling you to collect and analyze statistics for the entire cluster's lifetime, rather than focusing on individual members of the cluster.
  • Stateful Server: Each server is stateful and automatically saves its current metrics every minute. In case of server restarts, the metrics are preserved, ensuring seamless processing continuity.
  • API Key Authentication: The server is secured with API key authentication. Only authorized clients with valid API keys can access and manipulate the metrics.
  • Automatic Self-Signed Certificate: When the server is started without a key file and a certificate file (either empty strings or both files do not exist), the library automatically generates a self-signed certificate.
  • Activity Monitoring The server will regularly check how many clients have been active within the last hour. It will expose that value via the metric_nexus_clients metric.

Use Case Examples

Here are a couple of use case examples highlighting the versatility of MetricNexus:

Monitoring Spiders

In my spiders use case, I deploy numerous web spiders across multiple servers. Rather than focusing on individual spider activity, my interest lies in understanding their collective performance over time. With this solution, even if the servers restart due to various reasons, the metrics such as kills and time wasted can seamlessly resume without resetting each time a server reboots.

Multi-Application Server Metrics

Another use case involves a server running multiple applications that communicate with a single instance of this library instead of exposing their own Prometheus endpoints. Each application can utilize its unique metric prefix, ensuring metrics don't overwrite each other and making it effortless to differentiate metrics across applications.

Security Considerations

Please note that MetricNexus currently relies solely on API keys for authentication and operates as HTTP server without TLS. It is essential to implement additional security measures, such as network-level security, to protect sensitive data. Contributions implementing alternative protocols are welcome.

Server

server := metrics.NewServer("127.0.0.1", 3000, "/tmp/state.yaml")
server.AddAPIKey("Hello World")

// Either start with your own TLS certificate 
panic(server.Start("my.key", "my.cert"))

// Or let MetricNexus automatically create self-signed key and cert
panic(server.Start("", ""))

The server exposes Prometheus metrics at /__metrics and provides a CRUD REST API for manipulating metrics.

Client

// Simple uptime metric
apiKey := "Hello World"
allowSelfSigned := true // set to false if you want to error on self-signed certificates
client := metrics.NewClient("127.0.0.1", 3000, apiKey, allowSelfSigned)
if err := client.Create("uptime", "metric server uptime"); err != nil {
    fmt.Printf("Failed to create uptime metric: %s\n", err.Error())
}

for {
    s := time.Since(t).Seconds()
    if err := client.Update("uptime", s); err != nil {
        fmt.Printf("Failed to set uptime metric: %s\n", err.Error())
    }
    time.Sleep(5 * time.Second)
}

The client has the following methods:

Method Returns Description
Create(key, description string) error Creates the metric if it doesn't exist.
Update(key string, value interface{}) error Set the metric to the given value (casted to float64).
CreateUpdate(key, description string, value interface{}) error First creates and then sets the metric.
Read(key string) (float64, error) Reads the metric. If an error occurs it will be returned as the second value.
Increment(key string) error Increments the metric.
Decrement(key string) error Decrements the metric.
Add(key string, value interface{}) error Add the given value to the metric.
Subtract(key string, value interface{}) error Subtracts the given value from the metric.
Delete(key string) error Unregisters the metric and removes it from the known metrics. WARNING: Creating the metric again, but with a different description, will cause a crash!

API

If you need to control metrics from a non-Go application, you can utilize the REST API:

Endpoint Returns OK Status Description
POST /:metric 201 Creates a new metric with the provided key and uses the request body as its description.
GET /:metric float64 200 Retrieves and returns the value of the specified metric.
PUT /:metric 204 Updates the specified metric with the value from the request body.
PUT /:metric/inc 204 Increments the specified metric.
PUT /:metric/dec 204 Decrements the specified metric.
PUT /:metric/add 204 Adds the value from the request body to the specified metric.
PUT /:metric/sub 204 Subtracts the value from the request body from the specified metric.
DELETE /:metric 204 DANGER! Unregisters the specified metric and removes it from the known metric list. Re-adding the metric with a different description will cause a crash!

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

func NewClient

func NewClient(host string, port int, apiKey string, allowSelfSigned bool) *Client

func (*Client) Add

func (c *Client) Add(key string, value interface{}) error

func (*Client) Create

func (c *Client) Create(key, description string) error

func (*Client) CreateUpdate

func (c *Client) CreateUpdate(key, description string, value interface{}) error

func (*Client) Decrement

func (c *Client) Decrement(key string) error

func (*Client) Delete

func (c *Client) Delete(key string) error

func (*Client) Increment

func (c *Client) Increment(key string) error

func (*Client) Read

func (c *Client) Read(key string) (float64, error)

func (*Client) Subtract

func (c *Client) Subtract(key string, value interface{}) error

func (*Client) Update

func (c *Client) Update(key string, value interface{}) error

type Server

type Server struct {
	// contains filtered or unexported fields
}

func NewServer

func NewServer(host string, port int, stateFile string) *Server

func (*Server) Add

func (srv *Server) Add(key string, v interface{}) bool

func (*Server) AddAPIKey

func (srv *Server) AddAPIKey(key string)

func (*Server) Create

func (srv *Server) Create(key, description string, value interface{}) bool

func (*Server) CreateUpdate

func (srv *Server) CreateUpdate(key, description string, value interface{})

func (*Server) Decrement

func (srv *Server) Decrement(key string) bool

func (*Server) Delete

func (srv *Server) Delete(key string) bool

func (*Server) Increment

func (srv *Server) Increment(key string) bool

func (*Server) Read

func (srv *Server) Read(key string) (float64, bool)

func (*Server) Start

func (srv *Server) Start(keyFile, certFile string) error

func (*Server) Sub

func (srv *Server) Sub(key string, v interface{}) bool

func (*Server) Update

func (srv *Server) Update(key string, value interface{}) bool

type State

type State struct {
	Metrics []StateMetric `yaml:"metrics"`
	// contains filtered or unexported fields
}

func (*State) Append

func (s *State) Append(k, d string, v float64)

func (*State) SetValue

func (s *State) SetValue(k string, v float64) bool

type StateMetric

type StateMetric struct {
	Key         string  `yaml:"key"`
	Description string  `yaml:"description"`
	Value       float64 `yaml:"value"`
}

Directories

Path Synopsis
app
example

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL