Skip to content

Commit bd9f0cb

Browse files
authored
Enhance GetStatsCmd to include additional options for backlog statistics (#1801)
* Enhance GetStatsCmd to include additional options for backlog statistics - Added flags for precise backlog size, subscription backlog size, and earliest time in backlog. - Updated doGetStats function to accept new parameters and utilize them in the stats retrieval process. - Modified calls to GetPartitionedStats and GetStats to use the new options structure. * Add unit tests for new GetStatsCmd flags in stats_test.go - Implemented tests for precise backlog, subscription backlog size, and earliest time in backlog. - Added tests for handling multiple flags and partitioned topic statistics. - Ensured that the output matches expected default statistics for various scenarios. * Refactor GetStatsCmd flag definitions for improved clarity - Removed shorthand flags for precise backlog, subscription backlog size, and earliest time in backlog. - Updated flag definitions to enhance readability and maintain consistency in the command structure. * Update test cases in stats_test.go for consistency with new flag definitions - Ensured that test cases for GetPerPartitionStats reflect the latest command structure. - Verified that the output remains consistent with expected statistics for partitioned topics.
1 parent 8d3f12d commit bd9f0cb

2 files changed

Lines changed: 167 additions & 4 deletions

File tree

pkg/ctl/topic/stats.go

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,20 +142,30 @@ func GetStatsCmd(vc *cmdutils.VerbCmd) {
142142

143143
var partition bool
144144
var perPartition bool
145+
var getPreciseBacklog bool
146+
var subscriptionBacklogSize bool
147+
var getEarliestTimeInBacklog bool
148+
145149
vc.SetRunFuncWithNameArg(func() error {
146-
return doGetStats(vc, partition, perPartition)
150+
return doGetStats(vc, partition, perPartition, getPreciseBacklog, subscriptionBacklogSize, getEarliestTimeInBacklog)
147151
}, "the topic name is not specified or the topic name is specified more than one")
148152

149153
vc.FlagSetGroup.InFlagSet("Stats", func(set *pflag.FlagSet) {
150154
set.BoolVarP(&partition, "partitioned-topic", "p", false,
151155
"Get the partitioned topic stats")
152156
set.BoolVarP(&perPartition, "per-partition", "", false,
153157
"Get the per partition topic stats")
158+
set.BoolVarP(&getPreciseBacklog, "get-precise-backlog", "", false,
159+
"Get the precise backlog size")
160+
set.BoolVarP(&subscriptionBacklogSize, "get-subscription-backlog-size", "", true,
161+
"Get the backlog size for each subscription")
162+
set.BoolVarP(&getEarliestTimeInBacklog, "get-earliest-time-in-backlog", "", false,
163+
"Get the earliest time in backlog")
154164
})
155165
vc.EnableOutputFlagSet()
156166
}
157167

158-
func doGetStats(vc *cmdutils.VerbCmd, partitionedTopic, perPartition bool) error {
168+
func doGetStats(vc *cmdutils.VerbCmd, partitionedTopic, perPartition bool, getPreciseBacklog, subscriptionBacklogSize, getEarliestTimeInBacklog bool) error {
159169
// for testing
160170
if vc.NameError != nil {
161171
return vc.NameError
@@ -166,18 +176,24 @@ func doGetStats(vc *cmdutils.VerbCmd, partitionedTopic, perPartition bool) error
166176
return err
167177
}
168178

179+
getStatsOptions := utils.GetStatsOptions{
180+
GetPreciseBacklog: getPreciseBacklog,
181+
SubscriptionBacklogSize: subscriptionBacklogSize,
182+
GetEarliestTimeInBacklog: getEarliestTimeInBacklog,
183+
}
184+
169185
admin := cmdutils.NewPulsarClient()
170186

171187
if partitionedTopic {
172-
stats, err := admin.Topics().GetPartitionedStats(*topic, perPartition)
188+
stats, err := admin.Topics().GetPartitionedStatsWithOption(*topic, perPartition, getStatsOptions)
173189
if err == nil {
174190
oc := cmdutils.NewOutputContent().WithObject(stats)
175191
err = vc.OutputConfig.WriteOutput(vc.Command.OutOrStdout(), oc)
176192
}
177193
return err
178194
}
179195

180-
topicStats, err := admin.Topics().GetStats(*topic)
196+
topicStats, err := admin.Topics().GetStatsWithOption(*topic, getStatsOptions)
181197
if err == nil {
182198
oc := cmdutils.NewOutputContent().WithObject(topicStats)
183199
err = vc.OutputConfig.WriteOutput(vc.Command.OutOrStdout(), oc)

pkg/ctl/topic/stats_test.go

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,3 +180,150 @@ func TestGetNonPartitionedTopicStatsError(t *testing.T) {
180180
assert.NotNil(t, execErr)
181181
assert.Contains(t, execErr.Error(), "code: 404 reason: Partitioned Topic")
182182
}
183+
184+
func TestGetStatsWithPreciseBacklog(t *testing.T) {
185+
args := []string{"create", "test-stats-precise-backlog", "0"}
186+
_, execErr, _, _ := TestTopicCommands(CreateTopicCmd, args)
187+
assert.Nil(t, execErr)
188+
189+
args = []string{"stats", "--get-precise-backlog", "test-stats-precise-backlog"}
190+
out, execErr, _, _ := TestTopicCommands(GetStatsCmd, args)
191+
assert.Nil(t, execErr)
192+
193+
var stats utils.TopicStats
194+
err := json.Unmarshal(out.Bytes(), &stats)
195+
if err != nil {
196+
t.Fatal(err)
197+
}
198+
199+
assert.Equal(t, defaultStats, stats)
200+
}
201+
202+
func TestGetStatsWithoutSubscriptionBacklogSize(t *testing.T) {
203+
args := []string{"create", "test-stats-no-subscription-backlog", "0"}
204+
_, execErr, _, _ := TestTopicCommands(CreateTopicCmd, args)
205+
assert.Nil(t, execErr)
206+
207+
args = []string{"stats", "--get-subscription-backlog-size=false", "test-stats-no-subscription-backlog"}
208+
out, execErr, _, _ := TestTopicCommands(GetStatsCmd, args)
209+
assert.Nil(t, execErr)
210+
211+
var stats utils.TopicStats
212+
err := json.Unmarshal(out.Bytes(), &stats)
213+
if err != nil {
214+
t.Fatal(err)
215+
}
216+
217+
assert.Equal(t, defaultStats, stats)
218+
}
219+
220+
func TestGetStatsWithEarliestTimeInBacklog(t *testing.T) {
221+
args := []string{"create", "test-stats-earliest-time-backlog", "0"}
222+
_, execErr, _, _ := TestTopicCommands(CreateTopicCmd, args)
223+
assert.Nil(t, execErr)
224+
225+
args = []string{"stats", "--get-earliest-time-in-backlog", "test-stats-earliest-time-backlog"}
226+
out, execErr, _, _ := TestTopicCommands(GetStatsCmd, args)
227+
assert.Nil(t, execErr)
228+
229+
var stats utils.TopicStats
230+
err := json.Unmarshal(out.Bytes(), &stats)
231+
if err != nil {
232+
t.Fatal(err)
233+
}
234+
235+
assert.Equal(t, defaultStats, stats)
236+
}
237+
238+
func TestGetStatsWithMultipleNewFlags(t *testing.T) {
239+
args := []string{"create", "test-stats-multiple-flags", "0"}
240+
_, execErr, _, _ := TestTopicCommands(CreateTopicCmd, args)
241+
assert.Nil(t, execErr)
242+
243+
args = []string{"stats", "--get-precise-backlog", "--get-earliest-time-in-backlog", "test-stats-multiple-flags"}
244+
out, execErr, _, _ := TestTopicCommands(GetStatsCmd, args)
245+
assert.Nil(t, execErr)
246+
247+
var stats utils.TopicStats
248+
err := json.Unmarshal(out.Bytes(), &stats)
249+
if err != nil {
250+
t.Fatal(err)
251+
}
252+
253+
assert.Equal(t, defaultStats, stats)
254+
}
255+
256+
func TestGetPartitionedStatsWithNewFlags(t *testing.T) {
257+
args := []string{"create", "test-partitioned-stats-new-flags", "2"}
258+
_, execErr, _, _ := TestTopicCommands(CreateTopicCmd, args)
259+
assert.Nil(t, execErr)
260+
261+
args = []string{"stats", "--partitioned-topic", "--get-precise-backlog", "test-partitioned-stats-new-flags"}
262+
out, execErr, _, _ := TestTopicCommands(GetStatsCmd, args)
263+
assert.Nil(t, execErr)
264+
265+
var stats utils.PartitionedTopicStats
266+
err := json.Unmarshal(out.Bytes(), &stats)
267+
if err != nil {
268+
t.Fatal(err)
269+
}
270+
271+
assert.Equal(t, float64(0), stats.MsgRateIn)
272+
assert.Equal(t, float64(0), stats.MsgRateOut)
273+
assert.Equal(t, float64(0), stats.MsgThroughputIn)
274+
assert.Equal(t, float64(0), stats.MsgThroughputOut)
275+
assert.Equal(t, float64(0), stats.AverageMsgSize)
276+
assert.Equal(t, int64(0), stats.StorageSize)
277+
assert.Equal(t, 0, len(stats.Publishers))
278+
assert.Equal(t, 0, len(stats.Subscriptions))
279+
assert.Equal(t, 0, len(stats.Replication))
280+
assert.Equal(t, "", stats.DeDuplicationStatus)
281+
assert.Equal(t, 2, stats.Metadata.Partitions)
282+
assert.Equal(t, 0, len(stats.Partitions))
283+
}
284+
285+
func TestGetPerPartitionStatsWithNewFlags(t *testing.T) {
286+
args := []string{"create", "test-per-part-stats-new-flags", "1"}
287+
_, execErr, _, _ := TestTopicCommands(CreateTopicCmd, args)
288+
assert.Nil(t, execErr)
289+
290+
args = []string{"stats", "--partitioned-topic", "--per-partition", "--get-earliest-time-in-backlog", "test-per-part-stats-new-flags"}
291+
out, execErr, _, _ := TestTopicCommands(GetStatsCmd, args)
292+
assert.Nil(t, execErr)
293+
294+
var stats utils.PartitionedTopicStats
295+
err := json.Unmarshal(out.Bytes(), &stats)
296+
if err != nil {
297+
t.Fatal(err)
298+
}
299+
300+
defaultStats := utils.PartitionedTopicStats{
301+
MsgRateIn: 0,
302+
MsgRateOut: 0,
303+
MsgThroughputIn: 0,
304+
MsgThroughputOut: 0,
305+
AverageMsgSize: 0,
306+
StorageSize: 0,
307+
Publishers: []utils.PublisherStats{},
308+
Subscriptions: map[string]utils.SubscriptionStats{},
309+
Replication: map[string]utils.ReplicatorStats{},
310+
DeDuplicationStatus: "",
311+
Metadata: utils.PartitionedTopicMetadata{Partitions: 1},
312+
Partitions: map[string]utils.TopicStats{
313+
"persistent://public/default/test-per-part-stats-new-flags-partition-0": {
314+
MsgRateIn: 0,
315+
MsgRateOut: 0,
316+
MsgThroughputIn: 0,
317+
MsgThroughputOut: 0,
318+
AverageMsgSize: 0,
319+
StorageSize: 0,
320+
Publishers: []utils.PublisherStats{},
321+
Subscriptions: map[string]utils.SubscriptionStats{},
322+
Replication: map[string]utils.ReplicatorStats{},
323+
DeDuplicationStatus: "Disabled",
324+
},
325+
},
326+
}
327+
328+
assert.Equal(t, defaultStats, stats)
329+
}

0 commit comments

Comments
 (0)