github.com/sacloud/iaas-api-go@v1.12.0/naked/monitor.go (about)

     1  // Copyright 2022-2023 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  			v.BinlogUsedSizeKiB == nil || v.DelayTimeSec == nil {
   674  			continue
   675  		}
   676  		time, err := time.Parse(time.RFC3339, k) // RFC3339 ≒ ISO8601
   677  		if err != nil {
   678  			return nil, err
   679  		}
   680  		values = append(values, &MonitorDatabaseValue{
   681  			Time:              time,
   682  			TotalMemorySize:   *v.TotalMemorySize,
   683  			UsedMemorySize:    *v.UsedMemorySize,
   684  			TotalDisk1Size:    *v.TotalDisk1Size,
   685  			UsedDisk1Size:     *v.UsedDisk1Size,
   686  			TotalDisk2Size:    *v.TotalDisk2Size,
   687  			UsedDisk2Size:     *v.UsedDisk2Size,
   688  			BinlogUsedSizeKiB: *v.BinlogUsedSizeKiB,
   689  			DelayTimeSec:      *v.DelayTimeSec,
   690  		})
   691  	}
   692  
   693  	sort.Slice(values, func(i, j int) bool { return values[i].Time.Before(values[j].Time) })
   694  	return values, nil
   695  }
   696  
   697  func (m *rawMonitorValues) monitorFreeDiskSizeValues() (MonitorFreeDiskSizeValues, error) {
   698  	var values MonitorFreeDiskSizeValues
   699  
   700  	for k, v := range *m {
   701  		if v.FreeDiskSize == nil {
   702  			continue
   703  		}
   704  		time, err := time.Parse(time.RFC3339, k) // RFC3339 ≒ ISO8601
   705  		if err != nil {
   706  			return nil, err
   707  		}
   708  		values = append(values, &MonitorFreeDiskSizeValue{
   709  			Time:         time,
   710  			FreeDiskSize: *v.FreeDiskSize,
   711  		})
   712  	}
   713  
   714  	sort.Slice(values, func(i, j int) bool { return values[i].Time.Before(values[j].Time) })
   715  	return values, nil
   716  }
   717  
   718  func (m *rawMonitorValues) monitorResponseTimeSecValues() (MonitorResponseTimeSecValues, error) {
   719  	var values MonitorResponseTimeSecValues
   720  
   721  	for k, v := range *m {
   722  		if v.ResponseTimeSec == nil {
   723  			continue
   724  		}
   725  		time, err := time.Parse(time.RFC3339, k) // RFC3339 ≒ ISO8601
   726  		if err != nil {
   727  			return nil, err
   728  		}
   729  		values = append(values, &MonitorResponseTimeSecValue{
   730  			Time:            time,
   731  			ResponseTimeSec: *v.ResponseTimeSec,
   732  		})
   733  	}
   734  
   735  	sort.Slice(values, func(i, j int) bool { return values[i].Time.Before(values[j].Time) })
   736  	return values, nil
   737  }
   738  
   739  func (m *rawMonitorValues) monitorLinkValues() (MonitorLinkValues, error) {
   740  	var values MonitorLinkValues
   741  
   742  	for k, v := range *m {
   743  		if v.UplinkBPS == nil || v.DownlinkBPS == nil {
   744  			continue
   745  		}
   746  		time, err := time.Parse(time.RFC3339, k) // RFC3339 ≒ ISO8601
   747  		if err != nil {
   748  			return nil, err
   749  		}
   750  		values = append(values, &MonitorLinkValue{
   751  			Time:        time,
   752  			UplinkBPS:   *v.UplinkBPS,
   753  			DownlinkBPS: *v.DownlinkBPS,
   754  		})
   755  	}
   756  
   757  	sort.Slice(values, func(i, j int) bool { return values[i].Time.Before(values[j].Time) })
   758  	return values, nil
   759  }
   760  
   761  func (m *rawMonitorValues) monitorConnectionValues() (MonitorConnectionValues, error) {
   762  	var values MonitorConnectionValues
   763  
   764  	for k, v := range *m {
   765  		if v.ActiveConnections == nil || v.ConnectionsPerSec == nil {
   766  			continue
   767  		}
   768  		time, err := time.Parse(time.RFC3339, k) // RFC3339 ≒ ISO8601
   769  		if err != nil {
   770  			return nil, err
   771  		}
   772  		values = append(values, &MonitorConnectionValue{
   773  			Time:              time,
   774  			ActiveConnections: *v.ActiveConnections,
   775  			ConnectionsPerSec: *v.ConnectionsPerSec,
   776  		})
   777  	}
   778  
   779  	sort.Slice(values, func(i, j int) bool { return values[i].Time.Before(values[j].Time) })
   780  	return values, nil
   781  }
   782  
   783  func (m *rawMonitorValues) monitorLocalRouterValues() (MonitorLocalRouterValues, error) {
   784  	var values MonitorLocalRouterValues
   785  
   786  	for k, v := range *m {
   787  		if v.ReceiveBytesPerSec == nil || v.SendBytesPerSec == nil {
   788  			continue
   789  		}
   790  		time, err := time.Parse(time.RFC3339, k) // RFC3339 ≒ ISO8601
   791  		if err != nil {
   792  			return nil, err
   793  		}
   794  		values = append(values, &MonitorLocalRouterValue{
   795  			Time:               time,
   796  			ReceiveBytesPerSec: *v.ReceiveBytesPerSec,
   797  			SendBytesPerSec:    *v.SendBytesPerSec,
   798  		})
   799  	}
   800  
   801  	sort.Slice(values, func(i, j int) bool { return values[i].Time.Before(values[j].Time) })
   802  	return values, nil
   803  }