203 lines
3.6 KiB
Go
203 lines
3.6 KiB
Go
package azure
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"math"
|
|
"net/http"
|
|
"net/url"
|
|
)
|
|
|
|
type CounterCurcuit struct {
|
|
curcuit []float64
|
|
cursor int
|
|
}
|
|
|
|
func (cc *CounterCurcuit) Append(val float64) {
|
|
cc.curcuit[cc.cursor] = val
|
|
cc.cursor++
|
|
}
|
|
|
|
func (cc *CounterCurcuit) Stat() (min float64, max float64, sum float64, count int) {
|
|
if cc.cursor == 0 {
|
|
return 0, 0, 0, 0
|
|
}
|
|
|
|
min = math.MaxFloat64
|
|
max = -math.MaxFloat64
|
|
sum = float64(0)
|
|
|
|
if cc.cursor < len(cc.curcuit) {
|
|
count = cc.cursor
|
|
for i := 0; i < cc.cursor; i++ {
|
|
if min > cc.curcuit[i] {
|
|
min = cc.curcuit[i]
|
|
}
|
|
if max < cc.curcuit[i] {
|
|
max = cc.curcuit[i]
|
|
}
|
|
|
|
sum += cc.curcuit[i]
|
|
}
|
|
return
|
|
}
|
|
|
|
count = len(cc.curcuit)
|
|
for _, v := range cc.curcuit {
|
|
if min > v {
|
|
min = v
|
|
}
|
|
if max < v {
|
|
max = v
|
|
}
|
|
|
|
sum += v
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func MakeCounterCurcuit(length int) *CounterCurcuit {
|
|
return &CounterCurcuit{
|
|
curcuit: make([]float64, length),
|
|
cursor: 0,
|
|
}
|
|
}
|
|
|
|
type Float64Counter struct {
|
|
Min float64 `json:"min"`
|
|
Max float64 `json:"max"`
|
|
Sum float64 `json:"sum"`
|
|
Count int `json:"count"`
|
|
}
|
|
|
|
var DefaultFloat64Counter = Float64Counter{
|
|
Min: math.MaxFloat64,
|
|
Max: -math.MaxFloat64,
|
|
Sum: 0,
|
|
Count: 0,
|
|
}
|
|
|
|
func (c *Float64Counter) Valid() bool {
|
|
return c.Count > 0
|
|
}
|
|
|
|
func (c *Float64Counter) Add(val float64) {
|
|
if c.Max < val {
|
|
c.Max = val
|
|
}
|
|
|
|
if c.Min > val {
|
|
c.Min = val
|
|
}
|
|
|
|
c.Sum += val
|
|
c.Count++
|
|
}
|
|
|
|
func (c *Float64Counter) SingleMin() Float64Counter {
|
|
return Float64Counter{
|
|
Min: c.Min,
|
|
Max: c.Min,
|
|
Sum: c.Min,
|
|
Count: 1,
|
|
}
|
|
}
|
|
|
|
func (c *Float64Counter) SingleMax() Float64Counter {
|
|
return Float64Counter{
|
|
Min: c.Max,
|
|
Max: c.Max,
|
|
Sum: c.Max,
|
|
Count: 1,
|
|
}
|
|
}
|
|
|
|
func (c *Float64Counter) AddInt(val int) {
|
|
fval := float64(val)
|
|
if c.Max < fval {
|
|
c.Max = fval
|
|
}
|
|
|
|
if c.Min > fval {
|
|
c.Min = fval
|
|
}
|
|
|
|
c.Sum += fval
|
|
c.Count++
|
|
}
|
|
|
|
type MetricSeries struct {
|
|
Float64Counter
|
|
DimValues []string `json:"dimValues"`
|
|
}
|
|
|
|
type MetructBaseData struct {
|
|
Metric string `json:"metric"`
|
|
Namespace string `json:"namespace"`
|
|
DimNames []string `json:"dimNames"`
|
|
Series []MetricSeries `json:"series"`
|
|
}
|
|
|
|
type MetricData struct {
|
|
BaseData MetructBaseData `json:"baseData"`
|
|
}
|
|
|
|
type MetricDocument struct {
|
|
Time string `json:"time"`
|
|
Data MetricData `json:"data"`
|
|
}
|
|
|
|
func MakeMetricDocument(timestamp string, namespace string, metric string, dimNames []string) MetricDocument {
|
|
output := MetricDocument{Time: timestamp}
|
|
output.Data.BaseData.DimNames = dimNames
|
|
output.Data.BaseData.Metric = metric
|
|
output.Data.BaseData.Namespace = namespace
|
|
return output
|
|
}
|
|
|
|
type Monitor struct {
|
|
*accessToken
|
|
tenantId string
|
|
}
|
|
|
|
func NewMonitor(tenantId string) *Monitor {
|
|
return &Monitor{
|
|
accessToken: &accessToken{
|
|
url: fmt.Sprintf("https://login.microsoftonline.com/%s/oauth2/token", tenantId),
|
|
values: url.Values{
|
|
"grant_type": {"client_credentials"},
|
|
"client_id": {microsoftAppId()},
|
|
"resource": {"https://monitoring.azure.com/"},
|
|
"client_secret": {microsoftAppPassword()},
|
|
},
|
|
},
|
|
tenantId: tenantId,
|
|
}
|
|
}
|
|
|
|
func (m Monitor) PostMetrics(url string, docs ...MetricDocument) error {
|
|
// https://docs.microsoft.com/ko-kr/rest/api/monitor/metrics%20(data%20plane)/create
|
|
token, err := m.getAuthoizationToken()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, doc := range docs {
|
|
bt, _ := json.Marshal(doc)
|
|
req, _ := http.NewRequest("POST", url, bytes.NewReader(bt))
|
|
req.Header.Add("Authorization", token)
|
|
req.Header.Add("Content-Type", "application/json")
|
|
resp, err := http.DefaultClient.Do(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
io.Copy(io.Discard, resp.Body)
|
|
resp.Body.Close()
|
|
}
|
|
return nil
|
|
}
|