API version checking and linting.
This commit is contained in:
parent
045769a292
commit
095aff540e
@ -14,19 +14,16 @@ import (
|
||||
// Application is a thing that responsible for all application-related
|
||||
// actions like data fetching, storing, etc. on higher level.
|
||||
type Application struct {
|
||||
config *Config
|
||||
ctx context.Context
|
||||
storage storage.Metrics
|
||||
config *Config
|
||||
doneChan chan struct{}
|
||||
logger *logger.Logger
|
||||
name string
|
||||
|
||||
storage storage.Metrics
|
||||
storageDone chan struct{}
|
||||
|
||||
fetchIsRunning bool
|
||||
fetchIsRunningMutex sync.RWMutex
|
||||
|
||||
httpClient *http.Client
|
||||
name string
|
||||
fetchIsRunningMutex sync.RWMutex
|
||||
fetchIsRunning bool
|
||||
}
|
||||
|
||||
// NewApplication creates new application.
|
||||
|
@ -4,11 +4,11 @@ import "time"
|
||||
|
||||
// Config is a generic application configuration.
|
||||
type Config struct {
|
||||
// Headers is a list of headers that should be added to metrics request.
|
||||
Headers map[string]string `yaml:"headers"`
|
||||
// Endpoint is a remote application endpoint which should give us metrics
|
||||
// in Prometheus format.
|
||||
Endpoint string `yaml:"endpoint"`
|
||||
// Headers is a list of headers that should be added to metrics request.
|
||||
Headers map[string]string `yaml:"headers"`
|
||||
// TimeBetweenRequests is a minimal amount of time which should pass
|
||||
// between requests.
|
||||
TimeBetweenRequests time.Duration `yaml:"time_between_requests"`
|
||||
|
@ -29,6 +29,7 @@ func (a *Application) parse(body string) map[string]models.Metric {
|
||||
a.logger.Debugln("Analyzing line:", line)
|
||||
|
||||
name = a.getMetricName(line)
|
||||
|
||||
metric, found := data[name]
|
||||
if !found {
|
||||
metric = models.NewMetric(name, "", "", nil)
|
||||
@ -53,9 +54,9 @@ func (a *Application) parse(body string) map[string]models.Metric {
|
||||
|
||||
data[name] = metric
|
||||
|
||||
// According to https://github.com/Showmax/prometheus-docs/blob/master/content/docs/instrumenting/exposition_formats.md
|
||||
// HELP and TYPE lines should be printed before actual metric. Do not even
|
||||
// According to docs HELP and TYPE lines should be printed before actual metric. Do not even
|
||||
// report bugs regarding that!
|
||||
// Docs: https://github.com/Showmax/prometheus-docs/blob/master/content/docs/instrumenting/exposition_formats.md
|
||||
continue
|
||||
}
|
||||
|
||||
@ -76,12 +77,12 @@ func (a *Application) parse(body string) map[string]models.Metric {
|
||||
|
||||
metric.Value = a.getMetricValue(line)
|
||||
|
||||
a.logger.Debugln("Got metric: %+v\n", metric)
|
||||
a.logger.Debugf("Got metric: %+v\n", metric)
|
||||
|
||||
data[name] = metric
|
||||
}
|
||||
|
||||
a.logger.Debugln("Data parsed: %+v\n", data)
|
||||
a.logger.Debugf("Data parsed: %+v\n", data)
|
||||
|
||||
return data
|
||||
}
|
||||
@ -138,7 +139,7 @@ func (a *Application) getParametersForPrometheusMetric(line string) []string {
|
||||
}
|
||||
|
||||
// Sometimes nestif causes questions, like here. Is code below is
|
||||
// "deply nested"? I think not. So:
|
||||
// "deeply nested"? I think not. So:
|
||||
// nolint:nestif
|
||||
if !paramNameFinished {
|
||||
if string(r) != "=" {
|
||||
|
@ -39,7 +39,6 @@ func (h *handler) getAppsList() ([]byte, error) {
|
||||
appsList, err := json.Marshal(apps)
|
||||
if err != nil {
|
||||
// ToDo: log error
|
||||
|
||||
return nil, errNoAppsRegistered
|
||||
}
|
||||
|
||||
@ -70,23 +69,41 @@ func (h *handler) getRequestInfo(r *http.Request) (*models.RequestInfo, error) {
|
||||
|
||||
// Parse API version.
|
||||
apiVersionRaw := strings.TrimLeft(pathSplitted[2], "v")
|
||||
|
||||
apiVersion, err := strconv.Atoi(apiVersionRaw)
|
||||
if err != nil {
|
||||
// ToDo: log error
|
||||
return nil, errInvalidAPIVersion
|
||||
}
|
||||
|
||||
// Check used API version.
|
||||
var supportedAPIVersionUsed bool
|
||||
|
||||
for _, version := range supportedAPIVersions {
|
||||
if apiVersion == version {
|
||||
supportedAPIVersionUsed = true
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !supportedAPIVersionUsed {
|
||||
return nil, errInvalidAPIVersion
|
||||
}
|
||||
|
||||
// Get request type and key.
|
||||
requestType = pathSplitted[3]
|
||||
|
||||
if len(pathSplitted) >= 5 {
|
||||
appName = pathSplitted[4]
|
||||
}
|
||||
|
||||
if len(pathSplitted) >= 6 {
|
||||
metricName = strings.Join(pathSplitted[5:], "/")
|
||||
}
|
||||
|
||||
reqInfo := &models.RequestInfo{
|
||||
ApiVersion: apiVersion,
|
||||
APIVersion: apiVersion,
|
||||
Application: appName,
|
||||
Metric: metricName,
|
||||
RequestType: requestType,
|
||||
@ -103,8 +120,9 @@ func (h *handler) register(appName string, hndl common.HTTPHandlerFunc) {
|
||||
// ServeHTTP handles every HTTP request.
|
||||
func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
startTime := time.Now()
|
||||
|
||||
defer func() {
|
||||
requestDuration := time.Now().Sub(startTime)
|
||||
requestDuration := time.Since(startTime)
|
||||
|
||||
log.Printf("[HTTP Request] from %s to %s, duration %.4fs\n", r.RemoteAddr, r.URL.Path, requestDuration.Seconds())
|
||||
}()
|
||||
|
@ -2,16 +2,16 @@ package models
|
||||
|
||||
// Metric is a generic metric structure.
|
||||
type Metric struct {
|
||||
// Metric name.
|
||||
// Name is a metric name.
|
||||
Name string
|
||||
// HELP data, if present.
|
||||
// Description is a metric description from HELP line.
|
||||
Description string
|
||||
// Additional parameters, data inside "{}".
|
||||
Params []string
|
||||
// Type is a metric type.
|
||||
// Type is a metric type from TYPE line.
|
||||
Type string
|
||||
// Metric value.
|
||||
// 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.
|
||||
@ -21,6 +21,7 @@ func NewMetric(name, mType, description string, params []string) Metric {
|
||||
Description: description,
|
||||
Type: mType,
|
||||
Params: params,
|
||||
Value: "",
|
||||
}
|
||||
|
||||
return m
|
||||
|
@ -2,8 +2,8 @@ package models
|
||||
|
||||
// RequestInfo is a parsed request information to throw into application's handler.
|
||||
type RequestInfo struct {
|
||||
ApiVersion int
|
||||
Application string
|
||||
Metric string
|
||||
RequestType string
|
||||
APIVersion int
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user