Skip to content

Commit

Permalink
Merge pull request #17 from Zagir2000/iter17
Browse files Browse the repository at this point in the history
Iter18
  • Loading branch information
Zagir2000 committed Oct 8, 2023
2 parents 139a657 + a464cf0 commit 1447b83
Show file tree
Hide file tree
Showing 15 changed files with 128 additions and 15 deletions.
8 changes: 4 additions & 4 deletions cmd/agent/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ func main() {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
// создаем буферизованный канал для отправки результатов
jobs := make(chan []byte, 2)

go Metric.NewСollect(ctx, cancel, jobs)
jobs := make(chan []byte, 20)
go Metric.NewСollectMetricGopsutil(ctx, cancel, jobs)
go Metric.NewСollect(ctx, cancel, jobs)

for {
select {
case <-ctx.Done():
Expand All @@ -37,7 +37,7 @@ func main() {
g.Go(func() error {
var mx sync.Mutex
mx.Lock()
err := Metric.SendMetricsGor(jobs, flag.runAddr, flag.secretKey)
err := metricscollect.SendMetricsGor(jobs, flag.runAddr, flag.secretKey)
if err != nil {
return err
}
Expand Down
Binary file added cmd/server/profiles/base.pprof
Binary file not shown.
Binary file added cmd/server/profiles/result.pprof
Binary file not shown.
1 change: 1 addition & 0 deletions internal/agent/hash/hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"hash"
)

// Создаем хеш для его передачи на сервер.
func CrateHash(secretKey string, data []byte, hashNew func() hash.Hash) string {
secretKeyToByte := []byte(secretKey)
h := hmac.New(hashNew, secretKeyToByte)
Expand Down
36 changes: 26 additions & 10 deletions internal/agent/metricscollect/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,31 +23,39 @@ import (
)

const (
counterMetric string = "counter"
gaugeMetric string = "gauge"
randomValueName string = "RandomValue"
counterMetric string = "counter" //counter metric
gaugeMetric string = "gauge" //gauge metric
randomValueName string = "RandomValue" // random value
pollCountName string = "PollCount"
contentType string = "application/json"
compressType string = "gzip"
)

// Константы для хедера.
const (
contentType string = "application/json"
compressType string = "gzip"
)

// Структура для сбора и отправки метрик.
type RuntimeMetrics struct {
RuntimeMemstats map[string]float64
PollCount int64
RandomValue float64
pollInterval time.Duration
}

// Структура для ошибки при отправке на сервер.
type SendMetricsError struct {
Code int `json:"code"`
Message string `json:"message"`
Timestamp time.Time `json:"timestamp"`
}

// Инициализицаия структуры для сбора и отправки метрик.
func IntervalPin(pollIntervalFlag int) RuntimeMetrics {
return RuntimeMetrics{pollInterval: time.Duration(pollIntervalFlag), RuntimeMemstats: make(map[string]float64), PollCount: 0, RandomValue: 0}
}

// Добавление метрик в стрктуру RuntimeMetrics для будущей их отправки.
func (m *RuntimeMetrics) AddValueMetric() error {

mapstats := make(map[string]float64)
Expand Down Expand Up @@ -97,6 +105,7 @@ func (m *RuntimeMetrics) AddValueMetric() error {
return nil
}

// Добавление метрик с помощью пакета gopsutil и сбор дополнительных метрик.
func (m *RuntimeMetrics) AddVaueMetricGopsutil() error {
cpuStat, err := cpu.Times(true)
if err != nil {
Expand All @@ -117,8 +126,9 @@ func (m *RuntimeMetrics) AddVaueMetricGopsutil() error {
return nil
}

// Функция для отправления метрик на сервер пачками.
func (m *RuntimeMetrics) jsonMetricsToBatch() []byte {
var metrics []models.Metrics
metrics := make([]models.Metrics, 0, len(m.RuntimeMemstats)+2)
for k, v := range m.RuntimeMemstats {
valueGauge := v
jsonGauge := &models.Metrics{
Expand Down Expand Up @@ -147,7 +157,8 @@ func (m *RuntimeMetrics) jsonMetricsToBatch() []byte {
return out
}

func (m *RuntimeMetrics) SendMetrics(res []byte, hash, hostpath string) error {
// Функция для отправление на сервер по одной метрике за запрос.
func SendMetrics(res []byte, hash, hostpath string) error {
url := strings.Join([]string{"http:/", hostpath, "updates/"}, "/")

responseErr := &SendMetricsError{}
Expand Down Expand Up @@ -177,6 +188,7 @@ func (m *RuntimeMetrics) SendMetrics(res []byte, hash, hostpath string) error {
return nil
}

// Функция которая добавляет и сжимает метрики для последующей отправки в канал.
func (m *RuntimeMetrics) NewСollect(ctx context.Context, cancel context.CancelFunc, jobs chan []byte) {
for {
select {
Expand All @@ -200,12 +212,13 @@ func (m *RuntimeMetrics) NewСollect(ctx context.Context, cancel context.CancelF
}
}

// Функция которая добавляет и сжимает метрики для последующей отправки в канал.
func (m *RuntimeMetrics) NewСollectMetricGopsutil(ctx context.Context, cancel context.CancelFunc, jobs chan []byte) {
for {
select {
case <-ctx.Done():
return
default:
case <-time.After(time.Duration(1) * time.Second):
err := m.AddVaueMetricGopsutil()
if err != nil {
log.Println("Error in collect metrics 1", err)
Expand All @@ -221,6 +234,7 @@ func (m *RuntimeMetrics) NewСollectMetricGopsutil(ctx context.Context, cancel c
}
}

// Функция для сжатия данных.
func gzipCompress(data []byte) ([]byte, error) {
var buf bytes.Buffer

Expand All @@ -239,10 +253,12 @@ func gzipCompress(data []byte) ([]byte, error) {
return buf.Bytes(), err
}

func (m *RuntimeMetrics) SendMetricsGor(jobs <-chan []byte, runAddr, secretKey string) error {
// Функция для отправки метрик на сервер.
func SendMetricsGor(jobs <-chan []byte, runAddr, secretKey string) error {
for j := range jobs {

hash := hash.CrateHash(secretKey, j, sha256.New)
err := m.SendMetrics(j, hash, runAddr)
err := SendMetrics(j, hash, runAddr)
if err != nil {
log.Println("Error in send metrics:", err)
return err
Expand Down
2 changes: 1 addition & 1 deletion internal/agent/metricscollect/metrics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func TestRuntimeMetrics_SendMetrics(t *testing.T) {
if err != nil {
fmt.Println(err)
}
if err := m.SendMetrics(res, tt.args.hostpath, ""); (err != nil) != tt.wantErr {
if err := SendMetrics(res, tt.args.hostpath, ""); (err != nil) != tt.wantErr {
t.Errorf("RuntimeMetrics.SendMetrics() error = %v, wantErr %v", err, tt.wantErr)
}
})
Expand Down
2 changes: 2 additions & 0 deletions internal/models/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ package models

import "time"

// Структура для одной метрики
type Metrics struct {
ID string `json:"id"` // имя метрики
MType string `json:"type"` // параметр, принимающий значение gauge или counter
Delta *int64 `json:"delta,omitempty"` // значение метрики в случае передачи counter
Value *float64 `json:"value,omitempty"` // значение метрики в случае передачи gauge
}

// Время подключение к серверу
var TimeConnect []time.Duration = []time.Duration{1 * time.Second, 3 * time.Second, 5 * time.Second}
10 changes: 10 additions & 0 deletions internal/server/handlers/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,21 @@ import (
"go.uber.org/zap"
)

// Структура с бд, которую используют хэндеры.
type MetricHandlerDB struct {
Storage storage.Repository
pgDB *storage.PostgresDB
}

// Инициализация структуры MetricHandlerDB.
func MetricHandlerNew(s storage.Repository, pgDB *storage.PostgresDB) *MetricHandlerDB {
return &MetricHandlerDB{
Storage: s,
pgDB: pgDB,
}
}

// Метод для получения всех метрик.
func (m *MetricHandlerDB) GetAllMetrics(ctx context.Context, log *zap.Logger) http.HandlerFunc {
return func(res http.ResponseWriter, req *http.Request) {

Expand Down Expand Up @@ -60,6 +63,7 @@ func (m *MetricHandlerDB) GetAllMetrics(ctx context.Context, log *zap.Logger) ht

}

// Метод для получения одной метрики.
func (m *MetricHandlerDB) GetNowValueMetrics(ctx context.Context, log *zap.Logger) http.HandlerFunc {
return func(res http.ResponseWriter, req *http.Request) {
if req.Method != http.MethodGet {
Expand Down Expand Up @@ -97,6 +101,7 @@ func (m *MetricHandlerDB) GetNowValueMetrics(ctx context.Context, log *zap.Logge

}

// Метод для обновления метрик.
func (m *MetricHandlerDB) UpdateNewMetrics(ctx context.Context, log *zap.Logger) http.HandlerFunc {
return func(res http.ResponseWriter, req *http.Request) {
if req.Method != http.MethodPost {
Expand Down Expand Up @@ -147,6 +152,7 @@ func (m *MetricHandlerDB) UpdateNewMetrics(ctx context.Context, log *zap.Logger)
}
}

// Метод для добавления метрики, который использует json формат.
func (m *MetricHandlerDB) AddValueMetricsToJSON(ctx context.Context, log *zap.Logger) http.HandlerFunc {
return func(res http.ResponseWriter, req *http.Request) {

Expand Down Expand Up @@ -199,6 +205,8 @@ func (m *MetricHandlerDB) AddValueMetricsToJSON(ctx context.Context, log *zap.Lo
res.Write(response)
}
}

// Метод для обновления метрик, который использует json формат.
func (m *MetricHandlerDB) NewMetricsToJSON(ctx context.Context, log *zap.Logger) http.HandlerFunc {
return func(res http.ResponseWriter, req *http.Request) {
if req.Method != http.MethodPost {
Expand Down Expand Up @@ -263,6 +271,7 @@ func (m *MetricHandlerDB) NewMetricsToJSON(ctx context.Context, log *zap.Logger)
}
}

// Метод для проверки соединения бд.
func (m *MetricHandlerDB) PingDBConnect(ctx context.Context, log *zap.Logger) http.HandlerFunc {
return func(res http.ResponseWriter, req *http.Request) {
if req.Method != http.MethodGet {
Expand All @@ -280,6 +289,7 @@ func (m *MetricHandlerDB) PingDBConnect(ctx context.Context, log *zap.Logger) ht
}
}

// Метод для обновления метрик, котрый использует пакеты.
func (m *MetricHandlerDB) UpdateNewMetricsBatch(ctx context.Context, log *zap.Logger, keySecret string) http.HandlerFunc {
return func(res http.ResponseWriter, req *http.Request) {

Expand Down
40 changes: 40 additions & 0 deletions internal/server/handlers/handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/Zagir2000/alert/internal/server/storage"
"github.com/d5/tengo/assert"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
)

func TestMetricHandler_MainPage(t *testing.T) {
Expand Down Expand Up @@ -75,3 +76,42 @@ func TestMetricHandler_MainPage(t *testing.T) {
})
}
}

func Example() {
//инициализируем логер
log, _ := logger.InitializeLogger("info")

ctx := context.Background()
//папка с миграциями
migrationsDir := "migrations"
//значение, указывающее, следует ли загружать ранее сохраненные значения из указанного файла при запуске сервера
restore := true
//time interval according to which the current server servers are kept on disk
//интервал времени, в течение которого текущие серверы сервера хранятся на диске
storeIntervall := 300
databaseDsn := "postgres://postgres:123456@localhost/metrics?sslmode=disable"
memStorageInterface, postgresDB, err := storage.NewStorage(ctx, migrationsDir, log, migrationsDir, restore, storeIntervall, databaseDsn)
if err != nil {
log.Fatal("Error in create storage", zap.Error(err))
}
if postgresDB != nil {
defer postgresDB.Close()
}
newHandStruct := MetricHandlerNew(memStorageInterface, postgresDB)
// Выполняем операцию получения метрик.
newHandStruct.GetAllMetrics(ctx, log)
// Выполняем операцию добавления метрики, который использует json формат.
newHandStruct.AddValueMetricsToJSON(ctx, log)
// Выполняем операцию получения метрик.
newHandStruct.GetNowValueMetrics(ctx, log)
// Выполняем операцию добавления метрик, который использует json формат.
newHandStruct.NewMetricsToJSON(ctx, log)
// Выполняем операцию проверки соединения базы данных.
newHandStruct.PingDBConnect(ctx, log)
// Выполняем операцию обновления метрики.
newHandStruct.UpdateNewMetrics(ctx, log)
//Ключ для подписи хэша
key := "secret"
// Выполняем операцию обновления метрик.
newHandStruct.UpdateNewMetricsBatch(ctx, log, key)
}
14 changes: 14 additions & 0 deletions internal/server/handlers/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ package handlers

import (
"context"
"net/http/pprof"
_ "net/http/pprof" // подключаем пакет pprof

"github.com/Zagir2000/alert/internal/server/logger"
"github.com/go-chi/chi/v5"
"go.uber.org/zap"
)

// Роутер, который реализует все методы API.
func Router(ctx context.Context, log *zap.Logger, newHandStruct *MetricHandlerDB, keySecret string) chi.Router {
r := chi.NewRouter()
r.Use((logger.WithLogging(log)))
Expand All @@ -18,5 +21,16 @@ func Router(ctx context.Context, log *zap.Logger, newHandStruct *MetricHandlerDB
r.Get("/", gzipMiddleware(newHandStruct.GetAllMetrics(ctx, log)))
r.Get("/value/{metricType}/{metricName}", gzipMiddleware(newHandStruct.GetNowValueMetrics(ctx, log)))
r.Get("/ping", gzipMiddleware(newHandStruct.PingDBConnect(ctx, log)))

r.HandleFunc("/debug/pprof/", pprof.Index)
r.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
r.HandleFunc("/debug/pprof/profile", pprof.Profile)
r.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
r.HandleFunc("/debug/pprof/trace", pprof.Trace)

r.Handle("/debug/pprof/block", pprof.Handler("block"))
r.Handle("/debug/pprof/goroutine", pprof.Handler("goroutine"))
r.Handle("/debug/pprof/heap", pprof.Handler("heap"))
r.Handle("/debug/pprof/threadcreate", pprof.Handler("threadcreate"))
return r
}
1 change: 1 addition & 0 deletions internal/server/hash/checkhash.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"hash"
)

// Проверка хэша при получении запроса
func CheckHash(data []byte, secretKey, checksum string, hashNew func() hash.Hash) error {
secretKeyToByte := []byte(secretKey)
h := hmac.New(hashNew, secretKeyToByte)
Expand Down
Loading

0 comments on commit 1447b83

Please sign in to comment.