The very basic metricator-client and package.
Package can be used in external things if needed.
This commit is contained in:
146
pkg/client/client.go
Normal file
146
pkg/client/client.go
Normal file
@@ -0,0 +1,146 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"go.dev.pztrn.name/metricator/internal/logger"
|
||||
"go.dev.pztrn.name/metricator/pkg/schema"
|
||||
)
|
||||
|
||||
// Client is a Metricator client that is ready to be used in other applications
|
||||
// or libraries.
|
||||
type Client struct {
|
||||
config *Config
|
||||
logger *logger.Logger
|
||||
|
||||
httpClient *http.Client
|
||||
}
|
||||
|
||||
// NewClient creates new Metricator client.
|
||||
func NewClient(config *Config, logger *logger.Logger) *Client {
|
||||
c := &Client{
|
||||
config: config,
|
||||
logger: logger,
|
||||
}
|
||||
c.initialize()
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
// Executes request and parses it's contents.
|
||||
func (c *Client) executeAndParse(req *http.Request, dest interface{}) error {
|
||||
c.logger.Debugf("Executing HTTP request to %s%s", c.config.Host, req.URL.RequestURI())
|
||||
|
||||
ctx, cancelFunc := context.WithTimeout(context.Background(), time.Second*time.Duration(c.config.Timeout))
|
||||
defer cancelFunc()
|
||||
|
||||
req = req.WithContext(ctx)
|
||||
|
||||
response, err := c.httpClient.Do(req)
|
||||
if err != nil {
|
||||
c.logger.Infoln("Failed to execute request to Metricator:", err.Error())
|
||||
|
||||
return fmt.Errorf("metricator client: %w", err)
|
||||
}
|
||||
|
||||
defer response.Body.Close()
|
||||
|
||||
respData, err := ioutil.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
c.logger.Infoln("Failed to read response body:", err.Error())
|
||||
|
||||
return fmt.Errorf("metricator client: %w", err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(respData, dest)
|
||||
if err != nil {
|
||||
c.logger.Infoln("Failed to parse response:", err.Error())
|
||||
|
||||
return fmt.Errorf("metricator client: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetAppsList returns a slice with applications that was registered at Metricator.
|
||||
func (c *Client) GetAppsList() schema.AppsList {
|
||||
address := fmt.Sprintf("%s/api/v1/apps_list", c.config.Host)
|
||||
|
||||
// Request's context sets in c.executeAndParse, so:
|
||||
// nolint:noctx
|
||||
req, err := http.NewRequest("GET", address, nil)
|
||||
if err != nil {
|
||||
c.logger.Infoln("Failed to create HTTP request:", err.Error())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
appsList := make(schema.AppsList, 0)
|
||||
|
||||
err = c.executeAndParse(req, &appsList)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return appsList
|
||||
}
|
||||
|
||||
// GetMetric returns value for metric.
|
||||
func (c *Client) GetMetric(appName, metricName string) interface{} {
|
||||
address := fmt.Sprintf("%s/api/v1/metrics/%s/%s", c.config.Host, appName, metricName)
|
||||
|
||||
// Request's context sets in c.executeAndParse, so:
|
||||
// nolint:noctx
|
||||
req, err := http.NewRequest("GET", address, nil)
|
||||
if err != nil {
|
||||
c.logger.Infoln("Failed to create HTTP request:", err.Error())
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
var data interface{}
|
||||
|
||||
err = c.executeAndParse(req, &data)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
// GetMetricsList returns a slice with metrics names for passed application.
|
||||
func (c *Client) GetMetricsList(appName string) schema.Metrics {
|
||||
address := fmt.Sprintf("%s/api/v1/metrics/%s", c.config.Host, appName)
|
||||
|
||||
// Request's context sets in c.executeAndParse, so:
|
||||
// nolint:noctx
|
||||
req, err := http.NewRequest("GET", address, nil)
|
||||
if err != nil {
|
||||
c.logger.Infoln("Failed to create HTTP request:", err.Error())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
data := make(schema.Metrics, 0)
|
||||
|
||||
err = c.executeAndParse(req, &data)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
// Initializes internal states and storages.
|
||||
func (c *Client) initialize() {
|
||||
// We do not need to set everything for client actually, so:
|
||||
// nolint:exhaustivestruct
|
||||
c.httpClient = &http.Client{
|
||||
Timeout: time.Second * time.Duration(c.config.Timeout),
|
||||
}
|
||||
}
|
9
pkg/client/config.go
Normal file
9
pkg/client/config.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package client
|
||||
|
||||
// Config is a Metricator client configuration.
|
||||
type Config struct {
|
||||
// Host is a host where Metricator is available for requests.
|
||||
Host string
|
||||
// Timeout specifies HTTP client timeout.
|
||||
Timeout int
|
||||
}
|
9
pkg/schema/apps_list.go
Normal file
9
pkg/schema/apps_list.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package schema
|
||||
|
||||
// AppsList represents applications list structure from Metricator's API.
|
||||
type AppsList []string
|
||||
|
||||
// IsEmpty returns true if returned applications list is empty.
|
||||
func (a AppsList) IsEmpty() bool {
|
||||
return len(a) == 0
|
||||
}
|
41
pkg/schema/metric.go
Normal file
41
pkg/schema/metric.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package schema
|
||||
|
||||
// Metric is a generic metric structure. Used in HTTP responses and data storage.
|
||||
type Metric struct {
|
||||
// BaseName is a metric's base name, used for constructing name.
|
||||
BaseName string
|
||||
// Name is a metric name.
|
||||
Name string
|
||||
// Description is a metric description from HELP line.
|
||||
Description string
|
||||
// Type is a metric type from TYPE line.
|
||||
Type string
|
||||
// Value is a metric value.
|
||||
Value string
|
||||
// Params is an additional params which are placed inside "{}".
|
||||
Params []string
|
||||
}
|
||||
|
||||
// NewMetric creates new structure for storing single metric data.
|
||||
func NewMetric(name, mType, description string, params []string) Metric {
|
||||
m := Metric{
|
||||
BaseName: name,
|
||||
Name: name,
|
||||
Description: description,
|
||||
Type: mType,
|
||||
Params: params,
|
||||
Value: "",
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// GetValue returns metric's value.
|
||||
func (m *Metric) GetValue() string {
|
||||
return m.Value
|
||||
}
|
||||
|
||||
// SetValue sets value for metric.
|
||||
func (m *Metric) SetValue(value string) {
|
||||
m.Value = value
|
||||
}
|
9
pkg/schema/metrics.go
Normal file
9
pkg/schema/metrics.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package schema
|
||||
|
||||
// Metrics is a metrics collection response.
|
||||
type Metrics []*Metric
|
||||
|
||||
// IsEmpty returns true if returned applications list is empty.
|
||||
func (m Metrics) IsEmpty() bool {
|
||||
return len(m) == 0
|
||||
}
|
Reference in New Issue
Block a user