yats.git

ref: 5c9a5a1c5e7481ebba418da8a8f17fa14ed85d30

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
/**
 * 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"
	"github.com/gin-gonic/gin"
	"net/http"
	"strconv"
	"time"
	"yats-server/config"
	"yats-server/db"
	"yats-server/model"
)

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

		if err := c.BindJSON(&metric); err != nil {
			c.IndentedJSON(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)
		}

		c.IndentedJSON(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 {
			c.IndentedJSON(http.StatusAccepted, gin.H{"ret": "-1"})
			return
		}

		clientCN := GetClientCN(c, cfg)

		if metric.SourceApplication != "" {
			if !db.CanReadSourceMetric(clientCN, metric.SourceApplication, metric.Name) {
				c.IndentedJSON(http.StatusAccepted, gin.H{"ret": "-1"})
			}
			clientCN = metric.SourceApplication
		}

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

		var metricsPack []model.MetricModel

		if metric.To == 0 {
			unixTimeUTC := time.Unix(metric.From, 0)
			timeAsBytes, _ := unixTimeUTC.UTC().MarshalText()
			metricsPack = db.MetricsFrom(db.Session, clientCN, metric.Name, string(timeAsBytes), 100)
		} else if metric.From != 0 {
			fromUnixTimeUTC := time.Unix(metric.From, 0)
			toUnixTimeUTC := time.Unix(metric.To, 0)
			fromInBytes, _ := fromUnixTimeUTC.UTC().MarshalText()
			toInBytes, _ := toUnixTimeUTC.UTC().MarshalText()
			metricsPack = db.MetricsBetween(db.Session, clientCN, metric.Name, string(fromInBytes), string(toInBytes), 100)
		}
		c.IndentedJSON(http.StatusAccepted, gin.H{"ret": "OK", "content": 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 {
			c.IndentedJSON(http.StatusAccepted, gin.H{"ret": "-1"})
		}

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

		var metricsPack []model.MetricModel

		unixTimeUTC := time.Unix(fromParamInt64, 0)
		timeAsBytes, _ := unixTimeUTC.UTC().MarshalText()
		metricsPack = db.MetricsFrom(db.Session, clientCN, nameParam, string(timeAsBytes), 100)

		c.IndentedJSON(http.StatusAccepted, gin.H{"ret": "OK", "content": metricsPack})
	}
}