2 Copyright (c) 2021 AT&T Intellectual Property.
3 Copyright (c) 2018-2021 Nokia.
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
9 http://www.apache.org/licenses/LICENSE-2.0
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
19 * This source code is part of the near-RT RIC (RAN Intelligent Controller)
20 * platform project (RICP).
27 "gerrit.o-ran-sc.org/r/ric-plt/sdlgo/internal/sdlgoredis"
28 "github.com/spf13/cobra"
35 rootCmd.AddCommand(newStatisticsCmd(newDatabase))
39 statsLong = `Display SDL resource usage statistics`
41 statsExample = ` # Show statistics per node
45 func newStatisticsCmd(dbCreateCb DbCreateCb) *cobra.Command {
46 return &cobra.Command{
48 Short: "Display statistics.",
50 Example: statsExample,
51 Args: cobra.ExactArgs(0),
52 RunE: func(cmd *cobra.Command, args []string) error {
53 statistics, err := runStats(dbCreateCb)
55 fmt.Fprintf(os.Stderr, "%s", buf.String())
58 printStatistics(cmd, statistics)
64 func runStats(dbCreateCb DbCreateCb) ([]*sdlgoredis.DbStatistics, error) {
65 var statistics []*sdlgoredis.DbStatistics
66 for _, dbInst := range dbCreateCb().Instances {
67 dbStatistics, err := dbInst.Statistics()
71 statistics = append(statistics, dbStatistics)
73 return statistics, nil
76 func writeClientsInfo(w *tabwriter.Writer, clients sdlgoredis.ClientsInfoFields) {
77 fmt.Fprintf(w, "\t\t\tConnectedClients:%d\n", clients.ConnectedClients)
78 fmt.Fprintf(w, "\t\t\tClientRecentMaxInputBuffer:%d\n", clients.ClientRecentMaxInputBuffer)
79 fmt.Fprintf(w, "\t\t\tClientRecentMaxOutputBuffer:%d\n", clients.ClientRecentMaxOutputBuffer)
82 func writeMemoryInfo(w *tabwriter.Writer, memory sdlgoredis.MeroryInfoFields) {
83 fmt.Fprintf(w, "\t\t\tUsedMemory:%d\n", memory.UsedMemory)
84 fmt.Fprintf(w, "\t\t\tUsedMemoryHuman:%s\n", memory.UsedMemoryHuman)
85 fmt.Fprintf(w, "\t\t\tUsedMemoryRss:%d\n", memory.UsedMemoryRss)
86 fmt.Fprintf(w, "\t\t\tUsedMemoryRssHuman:%s\n", memory.UsedMemoryRssHuman)
87 fmt.Fprintf(w, "\t\t\tUsedMemoryPeak:%d\n", memory.UsedMemoryPeak)
88 fmt.Fprintf(w, "\t\t\tUsedMemoryPeakHuman:%s\n", memory.UsedMemoryPeakHuman)
89 fmt.Fprintf(w, "\t\t\tUsedMemoryPeakPerc:%s\n", memory.UsedMemoryPeakPerc)
90 fmt.Fprintf(w, "\t\t\tMemFragmentationRatio:%.2f\n", memory.MemFragmentationRatio)
91 fmt.Fprintf(w, "\t\t\tMemFragmentationBytes:%d\n", memory.MemFragmentationBytes)
94 func writeStatsInfo(w *tabwriter.Writer, stats sdlgoredis.StatsInfoFields) {
95 fmt.Fprintf(w, "\t\t\tTotalConnectionsReceived:%d\n", stats.TotalConnectionsReceived)
96 fmt.Fprintf(w, "\t\t\tTotalCommandsProcessed:%d\n", stats.TotalCommandsProcessed)
97 fmt.Fprintf(w, "\t\t\tSyncFull:%d\n", stats.SyncFull)
98 fmt.Fprintf(w, "\t\t\tSyncPartialOk:%d\n", stats.SyncPartialOk)
99 fmt.Fprintf(w, "\t\t\tSyncPartialErr:%d\n", stats.SyncPartialErr)
100 fmt.Fprintf(w, "\t\t\tPubsubChannels:%d\n", stats.PubsubChannels)
103 func writeCpuInfo(w *tabwriter.Writer, cpu sdlgoredis.CpuInfoFields) {
104 fmt.Fprintf(w, "\t\t\tUsedCpuSys:%v\n", cpu.UsedCpuSys)
105 fmt.Fprintf(w, "\t\t\tUsedCpuUser:%v\n", cpu.UsedCpuUser)
108 func fillCommandstatsInfo(w *tabwriter.Writer, i interface{}, cmdstat string) {
109 stype := reflect.ValueOf(i).Elem()
110 callsField := stype.FieldByName("Calls").Interface()
111 usecField := stype.FieldByName("Usec").Interface()
112 usecPerCallField := stype.FieldByName("UsecPerCall").Interface()
114 if callsField.(uint32) > 0 {
115 fmt.Fprintf(w, "\t\t\t%s:calls=%d usec:%d usecPerCall:%.2f\n",
116 cmdstat, callsField, usecField, usecPerCallField)
120 func writeCommandstatsInfo(w *tabwriter.Writer, commandstats sdlgoredis.CommandstatsInfoFields) {
121 fillCommandstatsInfo(w, &commandstats.CmdstatReplconf, "CmdstatReplconf")
122 fillCommandstatsInfo(w, &commandstats.CmdstatKeys, "CmdstatKeys")
123 fillCommandstatsInfo(w, &commandstats.CmdstatRole, "CmdstatRole")
124 fillCommandstatsInfo(w, &commandstats.CmdstatPsync, "CmdstatPsync")
125 fillCommandstatsInfo(w, &commandstats.CmdstatMset, "CmdstatMset")
126 fillCommandstatsInfo(w, &commandstats.CmdstatPublish, "CmdstatPublish")
127 fillCommandstatsInfo(w, &commandstats.CmdstatInfo, "CmdstatInfo")
128 fillCommandstatsInfo(w, &commandstats.CmdstatPing, "CmdstatPing")
129 fillCommandstatsInfo(w, &commandstats.CmdstatClient, "CmdstatClient")
130 fillCommandstatsInfo(w, &commandstats.CmdstatCommand, "CmdstatCommand")
131 fillCommandstatsInfo(w, &commandstats.CmdstatSubscribe, "CmdstatSubscribe")
132 fillCommandstatsInfo(w, &commandstats.CmdstatMonitor, "CmdstatMonitor")
133 fillCommandstatsInfo(w, &commandstats.CmdstatConfig, "CmdstatConfig")
134 fillCommandstatsInfo(w, &commandstats.CmdstatSlaveof, "CmdstatSlaveof")
137 func writeKeyspaceInfo(w *tabwriter.Writer, keyspace sdlgoredis.KeyspaceInfoFields) {
138 fmt.Fprintf(w, "\t\t\tDb0:keys=%d\n", keyspace.Db.Keys)
141 func printStatistics(cmd *cobra.Command, statistics []*sdlgoredis.DbStatistics) {
142 w := tabwriter.NewWriter(cmd.OutOrStdout(), 6, 4, 2, ' ', 0)
143 fmt.Fprintln(w, "CLUSTER\tROLE\tADDRESS\tSTATISTICS")
145 for i, s := range statistics {
146 for _, stats := range s.Stats {
147 fmt.Fprintf(w, "%d", i)
148 if stats.Info.Fields.PrimaryRole {
149 fmt.Fprintf(w, "\tPrimary")
151 fmt.Fprintf(w, "\tReplica")
153 fmt.Fprintf(w, "\t%s:%s", stats.IPAddr, stats.Port)
154 fmt.Fprintf(w, "\tUptimeInDays:%d\n", stats.Info.Fields.Server.UptimeInDays)
155 writeClientsInfo(w, stats.Info.Fields.Clients)
156 writeMemoryInfo(w, stats.Info.Fields.Memory)
157 writeStatsInfo(w, stats.Info.Fields.Stats)
158 writeCpuInfo(w, stats.Info.Fields.Cpu)
159 writeCommandstatsInfo(w, stats.Info.Fields.Commandstats)
160 writeKeyspaceInfo(w, stats.Info.Fields.Keyspace)