diff --git a/.gitignore b/.gitignore index 476f2a0..e37f082 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ ._bin .vscode metricator.yaml +.idea diff --git a/internal/application/fetcher.go b/internal/application/fetcher.go index 207c2c8..0a81013 100644 --- a/internal/application/fetcher.go +++ b/internal/application/fetcher.go @@ -1,7 +1,6 @@ package application import ( - "io/ioutil" "net/http" "time" ) @@ -44,15 +43,13 @@ func (a *Application) fetch() { defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) + data, err := a.parse(resp.Body) if err != nil { - a.logger.Infoln("Failed to read response body for", a.name, "metrics:", err.Error()) + a.logger.Infoln("Failed to parse response body for", a.name, "metrics:", err.Error()) return } - data := a.parse(string(body)) - a.storage.Put(data) a.fetchIsRunningMutex.Lock() diff --git a/internal/application/parser.go b/internal/application/parser.go index 3b631db..4a615f2 100644 --- a/internal/application/parser.go +++ b/internal/application/parser.go @@ -1,19 +1,27 @@ package application import ( + "bufio" + "fmt" + "io" "strings" "go.dev.pztrn.name/metricator/pkg/schema" ) -// Parses passed body and returns a map suitable for pushing into storage. -func (a *Application) parse(body string) map[string]schema.Metric { +// Parses io.Reader passed and returns a map suitable for pushing into storage. +func (a *Application) parse(r io.Reader) (map[string]schema.Metric, error) { data := make(map[string]schema.Metric) - // ToDo: switch to bytes buffer and maybe do not read body in caller? - splittedBody := strings.Split(body, "\n") + scanner := bufio.NewScanner(r) + for scanner.Scan() { + line := scanner.Text() + + // Skip empty lines. + if line == "" { + continue + } - for _, line := range splittedBody { // Prometheus line contains metric name and metric parameters defined // in "{}". var ( @@ -21,11 +29,6 @@ func (a *Application) parse(body string) map[string]schema.Metric { params []string ) - // Skip empty lines. - if line == "" { - continue - } - a.logger.Debugln("Analyzing line:", line) name = a.getMetricName(line) @@ -80,19 +83,22 @@ func (a *Application) parse(body string) map[string]schema.Metric { newMetric.Params = params metric = newMetric - data[metric.Name] = metric } metric.Value = a.getMetricValue(line) a.logger.Debugf("Got metric: %+v\n", metric) - data[name] = metric + data[metric.Name] = metric + } + + if err := scanner.Err(); err != nil { + return nil, fmt.Errorf("wasn't able to scan input: %w", err) } a.logger.Debugf("Data parsed: %+v\n", data) - return data + return data, nil } // Gets metric description from passed line. diff --git a/internal/logger/logger.go b/internal/logger/logger.go index a12306e..a09ae84 100644 --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -9,6 +9,10 @@ type Logger struct { // NewLogger creates new logging wrapper and returns it to caller. func NewLogger(config *Config) *Logger { + if config == nil { + config = &Config{Debug: false} + } + l := &Logger{config: config} return l