@@ -25,7 +25,9 @@ import (
25
25
"github.com/elastic/elastic-package/internal/benchrunner"
26
26
"github.com/elastic/elastic-package/internal/benchrunner/reporters"
27
27
"github.com/elastic/elastic-package/internal/benchrunner/reporters/outputs"
28
+ benchcommon "github.com/elastic/elastic-package/internal/benchrunner/runners/common"
28
29
"github.com/elastic/elastic-package/internal/benchrunner/runners/pipeline"
30
+ "github.com/elastic/elastic-package/internal/benchrunner/runners/rally"
29
31
"github.com/elastic/elastic-package/internal/benchrunner/runners/system"
30
32
"github.com/elastic/elastic-package/internal/cobraext"
31
33
"github.com/elastic/elastic-package/internal/common"
@@ -48,6 +50,12 @@ These benchmarks allow you to benchmark any Ingest Node Pipelines defined by you
48
50
49
51
For details on how to configure pipeline benchmarks for a package, review the [HOWTO guide](./docs/howto/pipeline_benchmarking.md).
50
52
53
+ #### Rally Benchmarks
54
+
55
+ These benchmarks allow you to benchmark an integration corpus with rally.
56
+
57
+ For details on how to configure rally benchmarks for a package, review the [HOWTO guide](./docs/howto/rally_benchmarking.md).
58
+
51
59
#### System Benchmarks
52
60
53
61
These benchmarks allow you to benchmark an integration end to end.
@@ -66,6 +74,9 @@ func setupBenchmarkCommand() *cobraext.Command {
66
74
pipelineCmd := getPipelineCommand ()
67
75
cmd .AddCommand (pipelineCmd )
68
76
77
+ rallyCmd := getRallyCommand ()
78
+ cmd .AddCommand (rallyCmd )
79
+
69
80
systemCmd := getSystemCommand ()
70
81
cmd .AddCommand (systemCmd )
71
82
@@ -213,6 +224,151 @@ func pipelineCommandAction(cmd *cobra.Command, args []string) error {
213
224
return nil
214
225
}
215
226
227
+ func getRallyCommand () * cobra.Command {
228
+ cmd := & cobra.Command {
229
+ Use : "rally" ,
230
+ Short : "Run rally benchmarks" ,
231
+ Long : "Run rally benchmarks for the package (esrally needs to be installed in the path of the system)" ,
232
+ Args : cobra .NoArgs ,
233
+ RunE : rallyCommandAction ,
234
+ }
235
+
236
+ cmd .Flags ().StringP (cobraext .BenchNameFlagName , "" , "" , cobraext .BenchNameFlagDescription )
237
+ cmd .Flags ().BoolP (cobraext .BenchReindexToMetricstoreFlagName , "" , false , cobraext .BenchReindexToMetricstoreFlagDescription )
238
+ cmd .Flags ().DurationP (cobraext .BenchMetricsIntervalFlagName , "" , time .Second , cobraext .BenchMetricsIntervalFlagDescription )
239
+ cmd .Flags ().DurationP (cobraext .DeferCleanupFlagName , "" , 0 , cobraext .DeferCleanupFlagDescription )
240
+ cmd .Flags ().String (cobraext .VariantFlagName , "" , cobraext .VariantFlagDescription )
241
+ cmd .Flags ().StringP (cobraext .BenchCorpusRallyTrackOutputDirFlagName , "" , "" , cobraext .BenchCorpusRallyTrackOutputDirFlagDescription )
242
+ cmd .Flags ().BoolP (cobraext .BenchCorpusRallyDryRunFlagName , "" , false , cobraext .BenchCorpusRallyDryRunFlagDescription )
243
+
244
+ return cmd
245
+ }
246
+
247
+ func rallyCommandAction (cmd * cobra.Command , args []string ) error {
248
+ cmd .Println ("Run rally benchmarks for the package" )
249
+
250
+ variant , err := cmd .Flags ().GetString (cobraext .VariantFlagName )
251
+ if err != nil {
252
+ return cobraext .FlagParsingError (err , cobraext .VariantFlagName )
253
+ }
254
+
255
+ benchName , err := cmd .Flags ().GetString (cobraext .BenchNameFlagName )
256
+ if err != nil {
257
+ return cobraext .FlagParsingError (err , cobraext .BenchNameFlagName )
258
+ }
259
+
260
+ deferCleanup , err := cmd .Flags ().GetDuration (cobraext .DeferCleanupFlagName )
261
+ if err != nil {
262
+ return cobraext .FlagParsingError (err , cobraext .DeferCleanupFlagName )
263
+ }
264
+
265
+ metricsInterval , err := cmd .Flags ().GetDuration (cobraext .BenchMetricsIntervalFlagName )
266
+ if err != nil {
267
+ return cobraext .FlagParsingError (err , cobraext .BenchMetricsIntervalFlagName )
268
+ }
269
+
270
+ dataReindex , err := cmd .Flags ().GetBool (cobraext .BenchReindexToMetricstoreFlagName )
271
+ if err != nil {
272
+ return cobraext .FlagParsingError (err , cobraext .BenchReindexToMetricstoreFlagName )
273
+ }
274
+
275
+ rallyTrackOutputDir , err := cmd .Flags ().GetString (cobraext .BenchCorpusRallyTrackOutputDirFlagName )
276
+ if err != nil {
277
+ return cobraext .FlagParsingError (err , cobraext .BenchCorpusRallyTrackOutputDirFlagName )
278
+ }
279
+
280
+ rallyDryRun , err := cmd .Flags ().GetBool (cobraext .BenchCorpusRallyDryRunFlagName )
281
+ if err != nil {
282
+ return cobraext .FlagParsingError (err , cobraext .BenchCorpusRallyDryRunFlagName )
283
+ }
284
+
285
+ packageRootPath , found , err := packages .FindPackageRoot ()
286
+ if ! found {
287
+ return errors .New ("package root not found" )
288
+ }
289
+ if err != nil {
290
+ return fmt .Errorf ("locating package root failed: %w" , err )
291
+ }
292
+
293
+ profile , err := cobraext .GetProfileFlag (cmd )
294
+ if err != nil {
295
+ return err
296
+ }
297
+
298
+ signal .Enable ()
299
+
300
+ esClient , err := stack .NewElasticsearchClientFromProfile (profile )
301
+ if err != nil {
302
+ return fmt .Errorf ("can't create Elasticsearch client: %w" , err )
303
+ }
304
+ err = esClient .CheckHealth (cmd .Context ())
305
+ if err != nil {
306
+ return err
307
+ }
308
+
309
+ kc , err := stack .NewKibanaClientFromProfile (profile )
310
+ if err != nil {
311
+ return fmt .Errorf ("can't create Kibana client: %w" , err )
312
+ }
313
+
314
+ withOpts := []rally.OptionFunc {
315
+ rally .WithVariant (variant ),
316
+ rally .WithBenchmarkName (benchName ),
317
+ rally .WithDeferCleanup (deferCleanup ),
318
+ rally .WithMetricsInterval (metricsInterval ),
319
+ rally .WithDataReindexing (dataReindex ),
320
+ rally .WithPackageRootPath (packageRootPath ),
321
+ rally .WithESAPI (esClient .API ),
322
+ rally .WithKibanaClient (kc ),
323
+ rally .WithProfile (profile ),
324
+ rally .WithRallyTrackOutputDir (rallyTrackOutputDir ),
325
+ rally .WithRallyDryRun (rallyDryRun ),
326
+ }
327
+
328
+ esMetricsClient , err := initializeESMetricsClient (cmd .Context ())
329
+ if err != nil {
330
+ return fmt .Errorf ("can't create Elasticsearch metrics client: %w" , err )
331
+ }
332
+ if esMetricsClient != nil {
333
+ withOpts = append (withOpts , rally .WithESMetricsAPI (esMetricsClient .API ))
334
+ }
335
+
336
+ runner := rally .NewRallyBenchmark (rally .NewOptions (withOpts ... ))
337
+
338
+ r , err := benchrunner .Run (runner )
339
+ if errors .Is (err , rally .ErrDryRun ) {
340
+ return nil
341
+ }
342
+
343
+ if err != nil {
344
+ return fmt .Errorf ("error running package rally benchmarks: %w" , err )
345
+ }
346
+
347
+ multiReport , ok := r .(reporters.MultiReportable )
348
+ if ! ok {
349
+ return fmt .Errorf ("rally benchmark is expected to return multiple reports" )
350
+ }
351
+
352
+ reports := multiReport .Split ()
353
+ if len (reports ) != 2 {
354
+ return fmt .Errorf ("rally benchmark is expected to return a human and a file report" )
355
+ }
356
+
357
+ // human report will always be the first
358
+ human := reports [0 ]
359
+ if err := reporters .WriteReportable (reporters .Output (outputs .ReportOutputSTDOUT ), human ); err != nil {
360
+ return fmt .Errorf ("error writing benchmark report: %w" , err )
361
+ }
362
+
363
+ // file report will always be the second
364
+ file := reports [1 ]
365
+ if err := reporters .WriteReportable (reporters .Output (outputs .ReportOutputFile ), file ); err != nil {
366
+ return fmt .Errorf ("error writing benchmark report: %w" , err )
367
+ }
368
+
369
+ return nil
370
+ }
371
+
216
372
func getSystemCommand () * cobra.Command {
217
373
cmd := & cobra.Command {
218
374
Use : "system" ,
@@ -410,10 +566,10 @@ func generateDataStreamCorpusCommandAction(cmd *cobra.Command, _ []string) error
410
566
}
411
567
412
568
func initializeESMetricsClient (ctx context.Context ) (* elasticsearch.Client , error ) {
413
- address := os .Getenv (system .ESMetricstoreHostEnv )
414
- user := os .Getenv (system .ESMetricstoreUsernameEnv )
415
- pass := os .Getenv (system .ESMetricstorePasswordEnv )
416
- cacert := os .Getenv (system .ESMetricstoreCACertificateEnv )
569
+ address := os .Getenv (benchcommon .ESMetricstoreHostEnv )
570
+ user := os .Getenv (benchcommon .ESMetricstoreUsernameEnv )
571
+ pass := os .Getenv (benchcommon .ESMetricstorePasswordEnv )
572
+ cacert := os .Getenv (benchcommon .ESMetricstoreCACertificateEnv )
417
573
if address == "" || user == "" || pass == "" {
418
574
logger .Debugf ("can't initialize metricstore, missing environment configuration" )
419
575
return nil , nil
0 commit comments