monitor.go raw
1 // Copyright 2022-2025 The sacloud/iaas-api-go Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 package naked
16
17 import (
18 "encoding/json"
19 "sort"
20 "strings"
21 "time"
22 )
23
24 // MonitorValues アクティビティモニタのレスポンス向け汎用エンベロープ
25 type MonitorValues struct {
26 // CPU CPU-TIME
27 CPU MonitorCPUTimeValues
28 // Disk Read/Write
29 Disk MonitorDiskValues
30 // Interface Send/Receive
31 Interface MonitorInterfaceValues
32 // Router In/Out
33 Router MonitorRouterValues
34 // Database データベース
35 Database MonitorDatabaseValues
36 // FreeDiskSize 空きディスクサイズ(NFS)
37 FreeDiskSize MonitorFreeDiskSizeValues
38 // ResponseTimeSec 応答時間(シンプル監視)
39 ResponseTimeSec MonitorResponseTimeSecValues
40 // Link UplinkBPS/DownlinkBPS
41 Link MonitorLinkValues
42 // Connection 接続数
43 Connection MonitorConnectionValues
44 // LocalRouter Receive/Send bytes per sec
45 LocalRouter MonitorLocalRouterValues
46 }
47
48 // UnmarshalJSON アクティビティモニタ向けUnmarshalJSON実装
49 func (m *MonitorValues) UnmarshalJSON(data []byte) error {
50 v := MonitorValues{}
51
52 // CPU
53 if err := json.Unmarshal(data, &v.CPU); err != nil {
54 return nil
55 }
56 if len(v.CPU) > 0 {
57 *m = v
58 return nil
59 }
60
61 // Disk
62 if err := json.Unmarshal(data, &v.Disk); err != nil {
63 return nil
64 }
65 if len(v.Disk) > 0 {
66 *m = v
67 return nil
68 }
69
70 // Interface
71 if err := json.Unmarshal(data, &v.Interface); err != nil {
72 return nil
73 }
74 if len(v.Interface) > 0 {
75 *m = v
76 return nil
77 }
78
79 // Router
80 if err := json.Unmarshal(data, &v.Router); err != nil {
81 return nil
82 }
83 if len(v.Router) > 0 {
84 *m = v
85 return nil
86 }
87
88 // Database
89 if err := json.Unmarshal(data, &v.Database); err != nil {
90 return nil
91 }
92 if len(v.Database) > 0 {
93 *m = v
94 return nil
95 }
96
97 // FreeDiskSize
98 if err := json.Unmarshal(data, &v.FreeDiskSize); err != nil {
99 return nil
100 }
101 if len(v.FreeDiskSize) > 0 {
102 *m = v
103 return nil
104 }
105
106 // ResponseTimeSec
107 if err := json.Unmarshal(data, &v.ResponseTimeSec); err != nil {
108 return nil
109 }
110 if len(v.ResponseTimeSec) > 0 {
111 *m = v
112 return nil
113 }
114
115 // Link
116 if err := json.Unmarshal(data, &v.Link); err != nil {
117 return nil
118 }
119 if len(v.Link) > 0 {
120 *m = v
121 return nil
122 }
123
124 // Connection
125 if err := json.Unmarshal(data, &v.Connection); err != nil {
126 return nil
127 }
128 if len(v.Connection) > 0 {
129 *m = v
130 return nil
131 }
132
133 // LocalRouter
134 if err := json.Unmarshal(data, &v.LocalRouter); err != nil {
135 return nil
136 }
137 if len(v.LocalRouter) > 0 {
138 *m = v
139 return nil
140 }
141 return nil
142 }
143
144 /************************************************
145 * CPU-TIME
146 ************************************************/
147
148 // MonitorCPUTimeValue CPU-TIMEアクティビティモニタ
149 type MonitorCPUTimeValue struct {
150 Time time.Time // 対象時刻
151 CPUTime float64
152 }
153
154 // MonitorCPUTimeValues CPU-TIMEアクティビティモニタ
155 type MonitorCPUTimeValues []*MonitorCPUTimeValue
156
157 // UnmarshalJSON アクティビティモニタ向けUnmarshalJSON実装
158 func (m *MonitorCPUTimeValues) UnmarshalJSON(data []byte) error {
159 targetData := strings.ReplaceAll(strings.ReplaceAll(string(data), " ", ""), "\n", "")
160 if targetData == `[]` {
161 return nil
162 }
163
164 var rawMonitorValues rawMonitorValues
165 if err := json.Unmarshal(data, &rawMonitorValues); err != nil {
166 return err
167 }
168 values, err := rawMonitorValues.monitorCPUTimeValues()
169 if err != nil {
170 return err
171 }
172
173 *m = values
174 return nil
175 }
176
177 /************************************************
178 * Disk(Read/Write)
179 ************************************************/
180
181 // MonitorDiskValue アクティビティモニタ
182 type MonitorDiskValue struct {
183 Time time.Time
184 Write float64
185 Read float64
186 }
187
188 // MonitorDiskValues アクティビティモニタ
189 type MonitorDiskValues []*MonitorDiskValue
190
191 // UnmarshalJSON アクティビティモニタ向けUnmarshalJSON実装
192 func (m *MonitorDiskValues) UnmarshalJSON(data []byte) error {
193 targetData := strings.ReplaceAll(strings.ReplaceAll(string(data), " ", ""), "\n", "")
194 if targetData == `[]` {
195 return nil
196 }
197
198 var rawMonitorValues rawMonitorValues
199 if err := json.Unmarshal(data, &rawMonitorValues); err != nil {
200 return err
201 }
202 values, err := rawMonitorValues.monitorDiskValues()
203 if err != nil {
204 return err
205 }
206
207 *m = values
208 return nil
209 }
210
211 /************************************************
212 * Interface(Send/Receive)
213 ************************************************/
214
215 // MonitorInterfaceValue アクティビティモニタ
216 type MonitorInterfaceValue struct {
217 Time time.Time
218 Send float64
219 Receive float64
220 }
221
222 // MonitorInterfaceValues アクティビティモニタ
223 type MonitorInterfaceValues []*MonitorInterfaceValue
224
225 // UnmarshalJSON アクティビティモニタ向けUnmarshalJSON実装
226 func (m *MonitorInterfaceValues) UnmarshalJSON(data []byte) error {
227 targetData := strings.ReplaceAll(strings.ReplaceAll(string(data), " ", ""), "\n", "")
228 if targetData == `[]` {
229 return nil
230 }
231
232 var rawMonitorValues rawMonitorValues
233 if err := json.Unmarshal(data, &rawMonitorValues); err != nil {
234 return err
235 }
236 values, err := rawMonitorValues.monitorInterfaceValues()
237 if err != nil {
238 return err
239 }
240
241 *m = values
242 return nil
243 }
244
245 /************************************************
246 * Router(In/Out)
247 ************************************************/
248
249 // MonitorRouterValue アクティビティモニタ
250 type MonitorRouterValue struct {
251 Time time.Time
252 In float64
253 Out float64
254 }
255
256 // MonitorRouterValues アクティビティモニタ
257 type MonitorRouterValues []*MonitorRouterValue
258
259 // UnmarshalJSON アクティビティモニタ向けUnmarshalJSON実装
260 func (m *MonitorRouterValues) UnmarshalJSON(data []byte) error {
261 targetData := strings.ReplaceAll(strings.ReplaceAll(string(data), " ", ""), "\n", "")
262 if targetData == `[]` {
263 return nil
264 }
265
266 var rawMonitorValues rawMonitorValues
267 if err := json.Unmarshal(data, &rawMonitorValues); err != nil {
268 return err
269 }
270 values, err := rawMonitorValues.monitorRouterValues()
271 if err != nil {
272 return err
273 }
274
275 *m = values
276 return nil
277 }
278
279 /************************************************
280 * Database
281 ************************************************/
282
283 // MonitorDatabaseValue アクティビティモニタ
284 type MonitorDatabaseValue struct {
285 Time time.Time // 対象時刻
286 TotalMemorySize float64
287 UsedMemorySize float64
288 TotalDisk1Size float64
289 UsedDisk1Size float64
290 TotalDisk2Size float64
291 UsedDisk2Size float64
292 BinlogUsedSizeKiB float64
293 DelayTimeSec float64
294 }
295
296 // MonitorDatabaseValues アクティビティモニタ
297 type MonitorDatabaseValues []*MonitorDatabaseValue
298
299 // UnmarshalJSON アクティビティモニタ向けUnmarshalJSON実装
300 func (m *MonitorDatabaseValues) UnmarshalJSON(data []byte) error {
301 targetData := strings.ReplaceAll(strings.ReplaceAll(string(data), " ", ""), "\n", "")
302 if targetData == `[]` {
303 return nil
304 }
305
306 var rawMonitorValues rawMonitorValues
307 if err := json.Unmarshal(data, &rawMonitorValues); err != nil {
308 return err
309 }
310 values, err := rawMonitorValues.monitorDatabaseValues()
311 if err != nil {
312 return err
313 }
314
315 *m = values
316 return nil
317 }
318
319 /************************************************
320 * FreeDiskSize
321 ************************************************/
322
323 // MonitorFreeDiskSizeValue アクティビティモニタ
324 type MonitorFreeDiskSizeValue struct {
325 Time time.Time // 対象時刻
326 FreeDiskSize float64
327 }
328
329 // MonitorFreeDiskSizeValues アクティビティモニタ
330 type MonitorFreeDiskSizeValues []*MonitorFreeDiskSizeValue
331
332 // UnmarshalJSON アクティビティモニタ向けUnmarshalJSON実装
333 func (m *MonitorFreeDiskSizeValues) UnmarshalJSON(data []byte) error {
334 targetData := strings.ReplaceAll(strings.ReplaceAll(string(data), " ", ""), "\n", "")
335 if targetData == `[]` {
336 return nil
337 }
338
339 var rawMonitorValues rawMonitorValues
340 if err := json.Unmarshal(data, &rawMonitorValues); err != nil {
341 return err
342 }
343 values, err := rawMonitorValues.monitorFreeDiskSizeValues()
344 if err != nil {
345 return err
346 }
347
348 *m = values
349 return nil
350 }
351
352 /************************************************
353 * ResponseTimeSec
354 ************************************************/
355
356 // MonitorResponseTimeSecValue アクティビティモニタ
357 type MonitorResponseTimeSecValue struct {
358 Time time.Time // 対象時刻
359 ResponseTimeSec float64
360 }
361
362 // MonitorResponseTimeSecValues アクティビティモニタ
363 type MonitorResponseTimeSecValues []*MonitorResponseTimeSecValue
364
365 // UnmarshalJSON アクティビティモニタ向けUnmarshalJSON実装
366 func (m *MonitorResponseTimeSecValues) UnmarshalJSON(data []byte) error {
367 targetData := strings.ReplaceAll(strings.ReplaceAll(string(data), " ", ""), "\n", "")
368 if targetData == `[]` {
369 return nil
370 }
371
372 var rawMonitorValues rawMonitorValues
373 if err := json.Unmarshal(data, &rawMonitorValues); err != nil {
374 return err
375 }
376 values, err := rawMonitorValues.monitorResponseTimeSecValues()
377 if err != nil {
378 return err
379 }
380
381 *m = values
382 return nil
383 }
384
385 /************************************************
386 * Link(up/down)
387 ************************************************/
388
389 // MonitorLinkValue アクティビティモニタ
390 type MonitorLinkValue struct {
391 Time time.Time
392 UplinkBPS float64
393 DownlinkBPS float64
394 }
395
396 // MonitorLinkValues アクティビティモニタ
397 type MonitorLinkValues []*MonitorLinkValue
398
399 // UnmarshalJSON アクティビティモニタ向けUnmarshalJSON実装
400 func (m *MonitorLinkValues) UnmarshalJSON(data []byte) error {
401 targetData := strings.ReplaceAll(strings.ReplaceAll(string(data), " ", ""), "\n", "")
402 if targetData == `[]` {
403 return nil
404 }
405
406 var rawMonitorValues rawMonitorValues
407 if err := json.Unmarshal(data, &rawMonitorValues); err != nil {
408 return err
409 }
410 values, err := rawMonitorValues.monitorLinkValues()
411 if err != nil {
412 return err
413 }
414
415 *m = values
416 return nil
417 }
418
419 /************************************************
420 * Connection(ProxyLB)
421 ************************************************/
422
423 // MonitorConnectionValue アクティビティモニタ
424 type MonitorConnectionValue struct {
425 Time time.Time
426 ActiveConnections float64
427 ConnectionsPerSec float64
428 }
429
430 // MonitorConnectionValues アクティビティモニタ
431 type MonitorConnectionValues []*MonitorConnectionValue
432
433 // UnmarshalJSON アクティビティモニタ向けUnmarshalJSON実装
434 func (m *MonitorConnectionValues) UnmarshalJSON(data []byte) error {
435 targetData := strings.ReplaceAll(strings.ReplaceAll(string(data), " ", ""), "\n", "")
436 if targetData == `[]` {
437 return nil
438 }
439
440 var rawMonitorValues rawMonitorValues
441 if err := json.Unmarshal(data, &rawMonitorValues); err != nil {
442 return err
443 }
444 values, err := rawMonitorValues.monitorConnectionValues()
445 if err != nil {
446 return err
447 }
448
449 *m = values
450 return nil
451 }
452
453 /************************************************
454 * LocalRouter(Receive/Send BytesPerSec)
455 ************************************************/
456
457 // MonitorLocalRouterValue アクティビティモニタ
458 type MonitorLocalRouterValue struct {
459 Time time.Time
460 ReceiveBytesPerSec float64
461 SendBytesPerSec float64
462 }
463
464 // MonitorLocalRouterValues アクティビティモニタ
465 type MonitorLocalRouterValues []*MonitorLocalRouterValue
466
467 // UnmarshalJSON アクティビティモニタ向けUnmarshalJSON実装
468 func (m *MonitorLocalRouterValues) UnmarshalJSON(data []byte) error {
469 targetData := strings.ReplaceAll(strings.ReplaceAll(string(data), " ", ""), "\n", "")
470 if targetData == `[]` {
471 return nil
472 }
473
474 var rawMonitorValues rawMonitorValues
475 if err := json.Unmarshal(data, &rawMonitorValues); err != nil {
476 return err
477 }
478 values, err := rawMonitorValues.monitorLocalRouterValues()
479 if err != nil {
480 return err
481 }
482
483 *m = values
484 return nil
485 }
486
487 // rawMonitorValue アクティビティモニター
488 type rawMonitorValue struct {
489 CPUTime *float64 `json:"CPU-TIME,omitempty" yaml:"cpu_timme,omitempty" structs:",omitempty"` // CPU時間
490 Write *float64 `json:",omitempty" yaml:"write,omitempty" structs:",omitempty"` // ディスク書き込み
491 Read *float64 `json:",omitempty" yaml:"read,omitempty" structs:",omitempty"` // ディスク読み取り
492 Receive *float64 `json:",omitempty" yaml:"receive,omitempty" structs:",omitempty"` // パケット受信
493 Send *float64 `json:",omitempty" yaml:"send,omitempty" structs:",omitempty"` // パケット送信
494 In *float64 `json:",omitempty" yaml:"in,omitempty" structs:",omitempty"` // パケット受信
495 Out *float64 `json:",omitempty" yaml:"out,omitempty" structs:",omitempty"` // パケット送信
496 TotalMemorySize *float64 `json:"Total-Memory-Size,omitempty" yaml:"total_memory_size,omitempty" structs:",omitempty"` // 総メモリサイズ
497 UsedMemorySize *float64 `json:"Used-Memory-Size,omitempty" yaml:"used_memory_size,omitempty" structs:",omitempty"` // 使用済みメモリサイズ
498 TotalDisk1Size *float64 `json:"Total-Disk1-Size,omitempty" yaml:"total_disk1_size,omitempty" structs:",omitempty"` // 総ディスクサイズ
499 UsedDisk1Size *float64 `json:"Used-Disk1-Size,omitempty" yaml:"used_disk1_size,omitempty" structs:",omitempty"` // 使用済みディスクサイズ
500 TotalDisk2Size *float64 `json:"Total-Disk2-Size,omitempty" yaml:"total_disk2_size,omitempty" structs:",omitempty"` // 総ディスクサイズ
501 UsedDisk2Size *float64 `json:"Used-Disk2-Size,omitempty" yaml:"used_disk2_size,omitempty" structs:",omitempty"` // 使用済みディスクサイズ
502 BinlogUsedSizeKiB *float64 `json:"binlogUsedSizeKiB,omitempty" yaml:"binlog_used_size_kib,omitempty" structs:",omitempty"` // バイナリログのサイズ(レプリケーション有効時のみ、master/slave両方で利用可能)
503 DelayTimeSec *float64 `json:"delayTimeSec,omitempty" yaml:"delay_time_sec,omitempty" structs:",omitempty"` // レプリケーション遅延時間(レプリケーション有効時のみ、slave側のみ)
504 FreeDiskSize *float64 `json:"Free-Disk-Size,omitempty" yaml:"free_disk_size,omitempty" structs:",omitempty"` // 空きディスクサイズ(NFS)
505 ResponseTimeSec *float64 `json:"responsetimesec,omitempty" yaml:"response_time_sec,omitempty" structs:",omitempty"` // レスポンスタイム(シンプル監視)
506 UplinkBPS *float64 `json:"UplinkBps,omitempty" yaml:"uplink_bps,omitempty" structs:",omitempty"` // 上り方向トラフィック
507 DownlinkBPS *float64 `json:"DownlinkBps,omitempty" yaml:"downlink_bps,omitempty" structs:",omitempty"` // 下り方向トラフィック
508 ActiveConnections *float64 `json:"activeConnections,omitempty" yaml:"active_connections,omitempty" structs:",omitempty"` // アクティブコネクション(プロキシLB)
509 ConnectionsPerSec *float64 `json:"connectionsPerSec,omitempty" yaml:"connections_per_sec,omitempty" structs:",omitempty"` // 秒間コネクション数
510 ReceiveBytesPerSec *float64 `json:"receiveBytesPerSec,omitempty" yaml:"receive_bytes_per_sec,omitempty" structs:",omitempty"` // 秒間受信バイト数
511 SendBytesPerSec *float64 `json:"sendBytesPerSec,omitempty" yaml:"send_bytes_per_sec,omitempty" structs:",omitempty"` // 秒間送信バイト数
512 }
513
514 // UnmarshalJSON JSONアンマーシャル(配列、オブジェクトが混在するためここで対応)
515 func (m *rawMonitorValue) UnmarshalJSON(data []byte) error {
516 targetData := strings.ReplaceAll(strings.ReplaceAll(string(data), " ", ""), "\n", "")
517 if targetData == `[]` {
518 return nil
519 }
520
521 tmp := &struct {
522 CPUTime *float64 `json:"CPU-TIME,omitempty" yaml:"cpu_timme,omitempty" structs:",omitempty"`
523 Write *float64 `json:",omitempty" yaml:"write,omitempty" structs:",omitempty"`
524 Read *float64 `json:",omitempty" yaml:"read,omitempty" structs:",omitempty"`
525 Receive *float64 `json:",omitempty" yaml:"receive,omitempty" structs:",omitempty"`
526 Send *float64 `json:",omitempty" yaml:"send,omitempty" structs:",omitempty"`
527 In *float64 `json:",omitempty" yaml:"in,omitempty" structs:",omitempty"`
528 Out *float64 `json:",omitempty" yaml:"out,omitempty" structs:",omitempty"`
529 TotalMemorySize *float64 `json:"Total-Memory-Size,omitempty" yaml:"total_memory_size,omitempty" structs:",omitempty"`
530 UsedMemorySize *float64 `json:"Used-Memory-Size,omitempty" yaml:"used_memory_size,omitempty" structs:",omitempty"`
531 TotalDisk1Size *float64 `json:"Total-Disk1-Size,omitempty" yaml:"total_disk1_size,omitempty" structs:",omitempty"`
532 UsedDisk1Size *float64 `json:"Used-Disk1-Size,omitempty" yaml:"used_disk1_size,omitempty" structs:",omitempty"`
533 TotalDisk2Size *float64 `json:"Total-Disk2-Size,omitempty" yaml:"total_disk2_size,omitempty" structs:",omitempty"`
534 UsedDisk2Size *float64 `json:"Used-Disk2-Size,omitempty" yaml:"used_disk2_size,omitempty" structs:",omitempty"`
535 BinlogUsedSizeKiB *float64 `json:"binlogUsedSizeKiB,omitempty" yaml:"binlog_used_size_kib,omitempty" structs:",omitempty"`
536 DelayTimeSec *float64 `json:"delayTimeSec,omitempty" yaml:"delay_time_sec,omitempty" structs:",omitempty"`
537 FreeDiskSize *float64 `json:"Free-Disk-Size,omitempty" yaml:"free_disk_size,omitempty" structs:",omitempty"`
538 ResponseTimeSec *float64 `json:"responsetimesec,omitempty" yaml:"response_time_sec,omitempty" structs:",omitempty"`
539 UplinkBPS *float64 `json:"UplinkBps,omitempty" yaml:"uplink_bps,omitempty" structs:",omitempty"`
540 DownlinkBPS *float64 `json:"DownlinkBps,omitempty" yaml:"downlink_bps,omitempty" structs:",omitempty"`
541 ActiveConnections *float64 `json:"activeConnections,omitempty" yaml:"active_connections,omitempty" structs:",omitempty"`
542 ConnectionsPerSec *float64 `json:"connectionsPerSec,omitempty" yaml:"connections_per_sec,omitempty" structs:",omitempty"`
543 ReceiveBytesPerSec *float64 `json:"receiveBytesPerSec,omitempty" yaml:"receive_bytes_per_sec,omitempty" structs:",omitempty"`
544 SendBytesPerSec *float64 `json:"sendBytesPerSec,omitempty" yaml:"send_bytes_per_sec,omitempty" structs:",omitempty"`
545 }{}
546 if err := json.Unmarshal(data, &tmp); err != nil {
547 return err
548 }
549
550 m.CPUTime = tmp.CPUTime
551 m.Write = tmp.Write
552 m.Read = tmp.Read
553 m.Receive = tmp.Receive
554 m.Send = tmp.Send
555 m.In = tmp.In
556 m.Out = tmp.Out
557 m.TotalMemorySize = tmp.TotalMemorySize
558 m.UsedMemorySize = tmp.UsedMemorySize
559 m.TotalDisk1Size = tmp.TotalDisk1Size
560 m.UsedDisk1Size = tmp.UsedDisk1Size
561 m.TotalDisk2Size = tmp.TotalDisk2Size
562 m.UsedDisk2Size = tmp.UsedDisk2Size
563 m.BinlogUsedSizeKiB = tmp.BinlogUsedSizeKiB
564 m.DelayTimeSec = tmp.DelayTimeSec
565 m.FreeDiskSize = tmp.FreeDiskSize
566 m.ResponseTimeSec = tmp.ResponseTimeSec
567 m.UplinkBPS = tmp.UplinkBPS
568 m.DownlinkBPS = tmp.DownlinkBPS
569 m.ActiveConnections = tmp.ActiveConnections
570 m.ConnectionsPerSec = tmp.ConnectionsPerSec
571 m.ReceiveBytesPerSec = tmp.ReceiveBytesPerSec
572 m.SendBytesPerSec = tmp.SendBytesPerSec
573
574 return nil
575 }
576
577 type rawMonitorValues map[string]*rawMonitorValue
578
579 func (m *rawMonitorValues) monitorCPUTimeValues() (MonitorCPUTimeValues, error) {
580 var values MonitorCPUTimeValues
581
582 for k, v := range *m {
583 if v.CPUTime == nil {
584 continue
585 }
586 time, err := time.Parse(time.RFC3339, k) // RFC3339 ≒ ISO8601
587 if err != nil {
588 return nil, err
589 }
590 values = append(values, &MonitorCPUTimeValue{
591 Time: time,
592 CPUTime: *v.CPUTime,
593 })
594 }
595
596 sort.Slice(values, func(i, j int) bool { return values[i].Time.Before(values[j].Time) })
597 return values, nil
598 }
599
600 func (m *rawMonitorValues) monitorDiskValues() (MonitorDiskValues, error) {
601 var values MonitorDiskValues
602
603 for k, v := range *m {
604 if v.Read == nil || v.Write == nil {
605 continue
606 }
607 time, err := time.Parse(time.RFC3339, k) // RFC3339 ≒ ISO8601
608 if err != nil {
609 return nil, err
610 }
611 values = append(values, &MonitorDiskValue{
612 Time: time,
613 Read: *v.Read,
614 Write: *v.Write,
615 })
616 }
617
618 sort.Slice(values, func(i, j int) bool { return values[i].Time.Before(values[j].Time) })
619 return values, nil
620 }
621
622 func (m *rawMonitorValues) monitorInterfaceValues() (MonitorInterfaceValues, error) {
623 var values MonitorInterfaceValues
624
625 for k, v := range *m {
626 if v.Send == nil || v.Receive == nil {
627 continue
628 }
629 time, err := time.Parse(time.RFC3339, k) // RFC3339 ≒ ISO8601
630 if err != nil {
631 return nil, err
632 }
633 values = append(values, &MonitorInterfaceValue{
634 Time: time,
635 Send: *v.Send,
636 Receive: *v.Receive,
637 })
638 }
639
640 sort.Slice(values, func(i, j int) bool { return values[i].Time.Before(values[j].Time) })
641 return values, nil
642 }
643
644 func (m *rawMonitorValues) monitorRouterValues() (MonitorRouterValues, error) {
645 var values MonitorRouterValues
646
647 for k, v := range *m {
648 if v.In == nil || v.Out == nil {
649 continue
650 }
651 time, err := time.Parse(time.RFC3339, k) // RFC3339 ≒ ISO8601
652 if err != nil {
653 return nil, err
654 }
655 values = append(values, &MonitorRouterValue{
656 Time: time,
657 In: *v.In,
658 Out: *v.Out,
659 })
660 }
661
662 sort.Slice(values, func(i, j int) bool { return values[i].Time.Before(values[j].Time) })
663 return values, nil
664 }
665
666 func (m *rawMonitorValues) monitorDatabaseValues() (MonitorDatabaseValues, error) {
667 var values MonitorDatabaseValues
668
669 for k, v := range *m {
670 if v.TotalMemorySize == nil || v.UsedMemorySize == nil ||
671 v.TotalDisk1Size == nil || v.UsedDisk1Size == nil ||
672 v.TotalDisk2Size == nil || v.UsedDisk2Size == nil {
673 continue
674 }
675 time, err := time.Parse(time.RFC3339, k) // RFC3339 ≒ ISO8601
676 if err != nil {
677 return nil, err
678 }
679 value := &MonitorDatabaseValue{
680 Time: time,
681 TotalMemorySize: *v.TotalMemorySize,
682 UsedMemorySize: *v.UsedMemorySize,
683 TotalDisk1Size: *v.TotalDisk1Size,
684 UsedDisk1Size: *v.UsedDisk1Size,
685 TotalDisk2Size: *v.TotalDisk2Size,
686 UsedDisk2Size: *v.UsedDisk2Size,
687 }
688 if v.BinlogUsedSizeKiB != nil {
689 value.BinlogUsedSizeKiB = *v.BinlogUsedSizeKiB
690 }
691 if v.DelayTimeSec != nil {
692 value.DelayTimeSec = *v.DelayTimeSec
693 }
694 values = append(values, value)
695 }
696
697 sort.Slice(values, func(i, j int) bool { return values[i].Time.Before(values[j].Time) })
698 return values, nil
699 }
700
701 func (m *rawMonitorValues) monitorFreeDiskSizeValues() (MonitorFreeDiskSizeValues, error) {
702 var values MonitorFreeDiskSizeValues
703
704 for k, v := range *m {
705 if v.FreeDiskSize == nil {
706 continue
707 }
708 time, err := time.Parse(time.RFC3339, k) // RFC3339 ≒ ISO8601
709 if err != nil {
710 return nil, err
711 }
712 values = append(values, &MonitorFreeDiskSizeValue{
713 Time: time,
714 FreeDiskSize: *v.FreeDiskSize,
715 })
716 }
717
718 sort.Slice(values, func(i, j int) bool { return values[i].Time.Before(values[j].Time) })
719 return values, nil
720 }
721
722 func (m *rawMonitorValues) monitorResponseTimeSecValues() (MonitorResponseTimeSecValues, error) {
723 var values MonitorResponseTimeSecValues
724
725 for k, v := range *m {
726 if v.ResponseTimeSec == nil {
727 continue
728 }
729 time, err := time.Parse(time.RFC3339, k) // RFC3339 ≒ ISO8601
730 if err != nil {
731 return nil, err
732 }
733 values = append(values, &MonitorResponseTimeSecValue{
734 Time: time,
735 ResponseTimeSec: *v.ResponseTimeSec,
736 })
737 }
738
739 sort.Slice(values, func(i, j int) bool { return values[i].Time.Before(values[j].Time) })
740 return values, nil
741 }
742
743 func (m *rawMonitorValues) monitorLinkValues() (MonitorLinkValues, error) {
744 var values MonitorLinkValues
745
746 for k, v := range *m {
747 if v.UplinkBPS == nil || v.DownlinkBPS == nil {
748 continue
749 }
750 time, err := time.Parse(time.RFC3339, k) // RFC3339 ≒ ISO8601
751 if err != nil {
752 return nil, err
753 }
754 values = append(values, &MonitorLinkValue{
755 Time: time,
756 UplinkBPS: *v.UplinkBPS,
757 DownlinkBPS: *v.DownlinkBPS,
758 })
759 }
760
761 sort.Slice(values, func(i, j int) bool { return values[i].Time.Before(values[j].Time) })
762 return values, nil
763 }
764
765 func (m *rawMonitorValues) monitorConnectionValues() (MonitorConnectionValues, error) {
766 var values MonitorConnectionValues
767
768 for k, v := range *m {
769 if v.ActiveConnections == nil || v.ConnectionsPerSec == nil {
770 continue
771 }
772 time, err := time.Parse(time.RFC3339, k) // RFC3339 ≒ ISO8601
773 if err != nil {
774 return nil, err
775 }
776 values = append(values, &MonitorConnectionValue{
777 Time: time,
778 ActiveConnections: *v.ActiveConnections,
779 ConnectionsPerSec: *v.ConnectionsPerSec,
780 })
781 }
782
783 sort.Slice(values, func(i, j int) bool { return values[i].Time.Before(values[j].Time) })
784 return values, nil
785 }
786
787 func (m *rawMonitorValues) monitorLocalRouterValues() (MonitorLocalRouterValues, error) {
788 var values MonitorLocalRouterValues
789
790 for k, v := range *m {
791 if v.ReceiveBytesPerSec == nil || v.SendBytesPerSec == nil {
792 continue
793 }
794 time, err := time.Parse(time.RFC3339, k) // RFC3339 ≒ ISO8601
795 if err != nil {
796 return nil, err
797 }
798 values = append(values, &MonitorLocalRouterValue{
799 Time: time,
800 ReceiveBytesPerSec: *v.ReceiveBytesPerSec,
801 SendBytesPerSec: *v.SendBytesPerSec,
802 })
803 }
804
805 sort.Slice(values, func(i, j int) bool { return values[i].Time.Before(values[j].Time) })
806 return values, nil
807 }
808