API version checking and linting.

This commit is contained in:
Stanislav Nikitin 2020-12-23 19:31:09 +05:00
parent 045769a292
commit 095aff540e
Signed by: pztrn
GPG Key ID: 1E944A0F0568B550
6 changed files with 46 additions and 29 deletions

View File

@ -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.

View File

@ -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"`

View File

@ -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) != "=" {

View File

@ -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())
}()

View File

@ -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

View File

@ -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
}