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 cmd := &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)
66 func runStats(dbCreateCb DbCreateCb) ([]*sdlgoredis.DbStatistics, error) {
67 var statistics []*sdlgoredis.DbStatistics
68 for _, dbInst := range dbCreateCb().Instances {
69 dbStatistics, err := dbInst.Statistics()
73 statistics = append(statistics, dbStatistics)
75 return statistics, nil
78 func writeClientsInfo(w *tabwriter.Writer, clients sdlgoredis.ClientsInfoFields) {
79 fmt.Fprintf(w, "\t\t\tConnectedClients:%d\n", clients.ConnectedClients)
80 fmt.Fprintf(w, "\t\t\tClientRecentMaxInputBuffer:%d\n", clients.ClientRecentMaxInputBuffer)
81 fmt.Fprintf(w, "\t\t\tClientRecentMaxOutputBuffer:%d\n", clients.ClientRecentMaxOutputBuffer)
84 func writeMemoryInfo(w *tabwriter.Writer, memory sdlgoredis.MeroryInfoFields) {
85 fmt.Fprintf(w, "\t\t\tUsedMemory:%d\n", memory.UsedMemory)
86 fmt.Fprintf(w, "\t\t\tUsedMemoryHuman:%s\n", memory.UsedMemoryHuman)
87 fmt.Fprintf(w, "\t\t\tUsedMemoryRss:%d\n", memory.UsedMemoryRss)
88 fmt.Fprintf(w, "\t\t\tUsedMemoryRssHuman:%s\n", memory.UsedMemoryRssHuman)
89 fmt.Fprintf(w, "\t\t\tUsedMemoryPeak:%d\n", memory.UsedMemoryPeak)
90 fmt.Fprintf(w, "\t\t\tUsedMemoryPeakHuman:%s\n", memory.UsedMemoryPeakHuman)
91 fmt.Fprintf(w, "\t\t\tUsedMemoryPeakPerc:%s\n", memory.UsedMemoryPeakPerc)
92 fmt.Fprintf(w, "\t\t\tMemFragmentationRatio:%.2f\n", memory.MemFragmentationRatio)
93 fmt.Fprintf(w, "\t\t\tMemFragmentationBytes:%d\n", memory.MemFragmentationBytes)
96 func writeStatsInfo(w *tabwriter.Writer, stats sdlgoredis.StatsInfoFields) {
97 fmt.Fprintf(w, "\t\t\tTotalConnectionsReceived:%d\n", stats.TotalConnectionsReceived)
98 fmt.Fprintf(w, "\t\t\tTotalCommandsProcessed:%d\n", stats.TotalCommandsProcessed)
99 fmt.Fprintf(w, "\t\t\tSyncFull:%d\n", stats.SyncFull)
100 fmt.Fprintf(w, "\t\t\tSyncPartialOk:%d\n", stats.SyncPartialOk)
101 fmt.Fprintf(w, "\t\t\tSyncPartialErr:%d\n", stats.SyncPartialErr)
102 fmt.Fprintf(w, "\t\t\tPubsubChannels:%d\n", stats.PubsubChannels)
105 func writeCpuInfo(w *tabwriter.Writer, cpu sdlgoredis.CpuInfoFields) {
106 fmt.Fprintf(w, "\t\t\tUsedCpuSys:%v\n", cpu.UsedCpuSys)
107 fmt.Fprintf(w, "\t\t\tUsedCpuUser:%v\n", cpu.UsedCpuUser)
110 func fillCommandstatsInfo(w *tabwriter.Writer, i interface{}, cmdstat string) {
111 stype := reflect.ValueOf(i).Elem()
112 callsField := stype.FieldByName("Calls").Interface()
113 usecField := stype.FieldByName("Usec").Interface()
114 usecPerCallField := stype.FieldByName("UsecPerCall").Interface()
116 if callsField.(uint32) > 0 {
117 fmt.Fprintf(w, "\t\t\t%s:calls=%d usec:%d usecPerCall:%.2f\n",
118 cmdstat, callsField, usecField, usecPerCallField)
122 func writeCommandstatsInfo(w *tabwriter.Writer, commandstats sdlgoredis.CommandstatsInfoFields) {
123 fillCommandstatsInfo(w, &commandstats.CmdstatReplconf, "CmdstatReplconf")
124 fillCommandstatsInfo(w, &commandstats.CmdstatKeys, "CmdstatKeys")
125 fillCommandstatsInfo(w, &commandstats.CmdstatRole, "CmdstatRole")
126 fillCommandstatsInfo(w, &commandstats.CmdstatPsync, "CmdstatPsync")
127 fillCommandstatsInfo(w, &commandstats.CmdstatMset, "CmdstatMset")
128 fillCommandstatsInfo(w, &commandstats.CmdstatPublish, "CmdstatPublish")
129 fillCommandstatsInfo(w, &commandstats.CmdstatInfo, "CmdstatInfo")
130 fillCommandstatsInfo(w, &commandstats.CmdstatPing, "CmdstatPing")
131 fillCommandstatsInfo(w, &commandstats.CmdstatClient, "CmdstatClient")
132 fillCommandstatsInfo(w, &commandstats.CmdstatCommand, "CmdstatCommand")
133 fillCommandstatsInfo(w, &commandstats.CmdstatSubscribe, "CmdstatSubscribe")
134 fillCommandstatsInfo(w, &commandstats.CmdstatMonitor, "CmdstatMonitor")
135 fillCommandstatsInfo(w, &commandstats.CmdstatConfig, "CmdstatConfig")
136 fillCommandstatsInfo(w, &commandstats.CmdstatSlaveof, "CmdstatSlaveof")
139 func writeKeyspaceInfo(w *tabwriter.Writer, keyspace sdlgoredis.KeyspaceInfoFields) {
140 fmt.Fprintf(w, "\t\t\tDb0:keys=%d\n", keyspace.Db.Keys)
143 func printStatistics(cmd *cobra.Command, statistics []*sdlgoredis.DbStatistics) {
144 w := tabwriter.NewWriter(cmd.OutOrStdout(), 6, 4, 2, ' ', 0)
145 fmt.Fprintln(w, "CLUSTER\tROLE\tADDRESS\tSTATISTICS")
147 for i, s := range statistics {
148 for _, stats := range s.Stats {
149 fmt.Fprintf(w, "%d", i)
150 if stats.Info.Fields.PrimaryRole {
151 fmt.Fprintf(w, "\tPrimary")
153 fmt.Fprintf(w, "\tReplica")
155 fmt.Fprintf(w, "\t%s:%s", stats.IPAddr, stats.Port)
156 fmt.Fprintf(w, "\tUptimeInDays:%d\n", stats.Info.Fields.Server.UptimeInDays)
157 writeClientsInfo(w, stats.Info.Fields.Clients)
158 writeMemoryInfo(w, stats.Info.Fields.Memory)
159 writeStatsInfo(w, stats.Info.Fields.Stats)
160 writeCpuInfo(w, stats.Info.Fields.Cpu)
161 writeCommandstatsInfo(w, stats.Info.Fields.Commandstats)
162 writeKeyspaceInfo(w, stats.Info.Fields.Keyspace)