mosn

Форк
0
/
stats.go 
153 строки · 3.4 Кб
1
package types
2

3
import (
4
	"fmt"
5
	"sync"
6
	"sync/atomic"
7
)
8

9
type Records struct {
10
	mutex    sync.Mutex
11
	reqTotal uint32
12
	respInfo map[int16]uint32 // statuscode: total
13
}
14

15
func NewRecords() *Records {
16
	return &Records{
17
		respInfo: map[int16]uint32{},
18
	}
19
}
20

21
// records response info, notice not all request will send response
22
func (r *Records) RecordResponse(statuscode int16) {
23
	r.mutex.Lock()
24
	defer r.mutex.Unlock()
25
	if _, ok := r.respInfo[statuscode]; !ok {
26
		r.respInfo[statuscode] = 0
27
	}
28
	r.respInfo[statuscode] += 1
29
}
30

31
func (r *Records) RecordRequest() {
32
	atomic.AddUint32(&r.reqTotal, 1)
33
}
34

35
func (r *Records) ResponseInfo() (map[int16]uint32, uint32) {
36
	r.mutex.Lock()
37
	defer r.mutex.Unlock()
38
	var total uint32 = 0
39
	m := make(map[int16]uint32, len(r.respInfo)) // do a copy
40
	for k, v := range r.respInfo {
41
		m[k] = v
42
		total += v
43
	}
44
	return m, total
45
}
46

47
func (r *Records) Requests() uint32 {
48
	return atomic.LoadUint32(&r.reqTotal)
49
}
50

51
func (r *Records) String() string {
52
	info, total := r.ResponseInfo()
53
	return fmt.Sprintf("request: %d, response total: %d, response status: %v", r.Requests(), total, info)
54
}
55

56
type ServerStats struct {
57
	connectionTotal  uint32
58
	connectionActive uint32
59
	connectionClosed uint32
60
	records          *Records
61
}
62

63
type ServerStatsReadOnly interface {
64
	ConnectionTotal() uint32
65
	ConnectionActive() uint32
66
	ConnectionClosed() uint32
67
	Requests() uint32
68
	ResponseInfo() (map[int16]uint32, uint32)
69
	String() string
70
}
71

72
func NewServerStats() *ServerStats {
73
	return &ServerStats{
74
		records: NewRecords(),
75
	}
76
}
77

78
func (s *ServerStats) ConnectionTotal() uint32 {
79
	return atomic.LoadUint32(&s.connectionTotal)
80
}
81

82
func (s *ServerStats) ConnectionActive() uint32 {
83
	return atomic.LoadUint32(&s.connectionActive)
84
}
85

86
func (s *ServerStats) ConnectionClosed() uint32 {
87
	return atomic.LoadUint32(&s.connectionClosed)
88
}
89

90
func (s *ServerStats) Records() *Records {
91
	return s.records
92
}
93

94
func (s *ServerStats) ResponseInfo() (map[int16]uint32, uint32) {
95
	return s.records.ResponseInfo()
96
}
97
func (s *ServerStats) Requests() uint32 {
98
	return s.records.Requests()
99
}
100

101
func (s *ServerStats) ActiveConnection() {
102
	atomic.AddUint32(&s.connectionTotal, 1)
103
	atomic.AddUint32(&s.connectionActive, 1)
104
}
105

106
func (s *ServerStats) CloseConnection() {
107
	// subtract x, add ^uint32(x-1)
108
	atomic.AddUint32(&s.connectionActive, ^uint32(0))
109
	atomic.AddUint32(&s.connectionClosed, 1)
110
}
111

112
func (s *ServerStats) String() string {
113
	return fmt.Sprintf("connections: { total: %d, actvie: %d, closed: %d}, response info: %s",
114
		s.ConnectionTotal(), s.ConnectionActive(), s.ConnectionClosed(), s.Records().String())
115
}
116

117
type ClientStatsReadOnly interface {
118
	ServerStatsReadOnly
119
	ExpectedResponseCount() uint32
120
	UnexpectedResponseCount() uint32
121
}
122

123
type ClientStats struct {
124
	*ServerStats
125
	expectedResponse   uint32
126
	unexpectedResponse uint32
127
}
128

129
func NewClientStats() *ClientStats {
130
	return &ClientStats{
131
		ServerStats: NewServerStats(),
132
	}
133
}
134

135
func (c *ClientStats) ExpectedResponseCount() uint32 {
136
	return atomic.LoadUint32(&c.expectedResponse)
137
}
138

139
func (c *ClientStats) UnexpectedResponseCount() uint32 {
140
	return atomic.LoadUint32(&c.unexpectedResponse)
141
}
142

143
func (c *ClientStats) Response(expected bool) {
144
	if expected {
145
		atomic.AddUint32(&c.expectedResponse, 1)
146
	} else {
147
		atomic.AddUint32(&c.unexpectedResponse, 1)
148
	}
149
}
150

151
func (c *ClientStats) String() string {
152
	return fmt.Sprintf("%s, expected response: %d, unexpected response: %d", c.ServerStats.String(), c.ExpectedResponseCount(), c.UnexpectedResponseCount())
153
}
154

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.