yats.git

ref: e3514c03dbe4aa75d064ac589d0b71c991538ca3

server/rest/rest-metric.go


  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/**
 * Yats - yats
 *
 * This file is licensed under the Affero General Public License version 3 or
 * later. See the COPYING file.
 *
 * @author Paolo Lulli <kevwe.com>
 * @copyright Paolo Lulli 2024
 */

package rest

import (
	"fmt"
	"log"
	"net/http"
	"os"
	"strconv"
	"time"
	"yats-server/config"
	"yats-server/db"
	"yats-server/model"
	"yats-server/util"

	"github.com/gin-gonic/gin"
)

var (
	//outfile, _ = os.Create(configuration.LogFile)
	LOG               = log.New(os.Stdout, "[YATS] ", log.Ldate|log.Ltime)
	MaxPageSize int64 = 100
)

// @BasePath /

// WriteMetric godoc
// @Param X-SSL-Client-CN header string true "clientCN"
// @Summary write metric to db
// @Schemes
// @Description store metric
// @Tags Metrics
// @Accept json
// @Param metric2 body model.MetricRequest true "Metric request body"
// @Produce json
// @Success 202 {string} WriteMetric
// @Router /metric [post]
func WriteMetric(cfg config.Configuration) gin.HandlerFunc {
	return func(c *gin.Context) {
		var metric model.MetricRequest

		if err := c.BindJSON(&metric); err != nil {
			JsonPrint(cfg, c, http.StatusAccepted, gin.H{"ret": "-1"})
			return
		}

		clientCN := GetClientCN(c, cfg)
		fmt.Printf("%s / %s / %s", clientCN, metric.Name, metric.Value)

		if metric.Mtime != 0 {
			unixTimeUTC := time.Unix(metric.Mtime, 0)
			db.SaveMetricAt(clientCN, unixTimeUTC, metric.Name, metric.Value)
		} else {
			db.SaveMetric(clientCN, metric.Name, metric.Value)
		}

		JsonPrint(cfg, c, http.StatusAccepted, gin.H{"ret": "OK"})
	}
}

// SearchMetrics  godoc
// @Param X-SSL-Client-CN header string true "clientCN"
// @Summary Get the metrics From ... and To when present
// @Schemes
// @Description search metrics in the specified timeframe
// @Tags Metrics
// @Accept json
// @Param metric1 body model.MetricSearchRequest true "Metric query filters"
// @Produce json
// @Success 200 {string} WriteMetric
// @Router /metric/search [post]
func SearchMetrics(cfg config.Configuration) gin.HandlerFunc {
	return func(c *gin.Context) {
		var metric model.MetricSearchRequest

		if err := c.BindJSON(&metric); err != nil {
			JsonPrint(cfg, c, http.StatusBadRequest, gin.H{"ret": "-1"})
			return
		}

		clientCN := GetClientCN(c, cfg)

		if metric.SourceApplication != "" {
			if !db.CanReadSourceMetric(clientCN, metric.SourceApplication, metric.Name) {
				JsonPrint(cfg, c, http.StatusBadRequest, gin.H{"ret": "-2"})
				return
			}
			clientCN = metric.SourceApplication
		}

		fmt.Printf("%s / %s ", clientCN, metric.Name)

		var metricsPack []model.MetricModel

		if metric.To == 0 {
			metricsPack = db.MetricsFrom(db.Session, clientCN, metric.Name, util.Int64ToTimeUTC(metric.From), MaxPageSize)
		} else if metric.From != 0 {
			metricsPack = db.MetricsBetween(db.Session, clientCN, metric.Name, util.Int64ToTimeUTC(metric.From), util.Int64ToTimeUTC(metric.To), MaxPageSize)
		}

		maxpage := metricsPack[len(metricsPack)-1].Mtime
		JsonPrint(cfg, c, http.StatusAccepted, gin.H{"maxpage": maxpage, "data": metricsPack})
	}
}

// SearchMetricsFrom SearchMetrics  godoc
// @Param X-SSL-Client-CN header string true "clientCN"
// @Summary Get the specific metric {name} starting from the epoch {from}
// @Schemes
// @Description search metrics after the specified timestamp
// @Tags Metrics
// @Produce json
// @Success 200 {string} []model.MetricModel
// @Router /metric/{name}/{from} [get]
// @Param name path string true "Metric Name :name"
// @Param from path string true "Starting from epoch :from"
func SearchMetricsFrom(cfg config.Configuration) gin.HandlerFunc {
	return func(c *gin.Context) {

		var metric model.MetricSearchRequest

		nameParam := c.Param("name")
		fromParam := c.Param("from")
		fromParamInt64, err := strconv.ParseInt(fromParam, 10, 64)
		if err != nil {
			JsonPrint(cfg, c, http.StatusBadRequest, gin.H{"ret": "-1"})
			return
		}

		clientCN := GetClientCN(c, cfg)
		fmt.Printf("%s / %s ", clientCN, metric.Name)

		var metricsPack []model.MetricModel
		metricsPack = db.MetricsFrom(db.Session, clientCN, nameParam, util.Int64ToTimeUTC(fromParamInt64), MaxPageSize)

		maxpage := metricsPack[len(metricsPack)-1].Mtime
		JsonPrint(cfg, c, http.StatusAccepted, gin.H{"maxpage": maxpage, "data": metricsPack})
	}
}