auto group jobs with user-defined template to support template compare mode background: before compare, create job-groups for all jobs that query from ES with user's filter then, create matrices-groups according job-groups finally, compare each group matrices
Signed-off-by: Lu Weitao luweitaobe@163.com --- lib/params_group.rb | 121 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 120 insertions(+), 1 deletion(-)
diff --git a/lib/params_group.rb b/lib/params_group.rb index 0f07d26..3c6de7a 100644 --- a/lib/params_group.rb +++ b/lib/params_group.rb @@ -2,7 +2,7 @@ # Copyright (c) 2020 Huawei Technologies Co., Ltd. All rights reserved. # frozen_string_literal: true
-# Exammple: +# Example: # Input: jobs_list. The results of ES query. # # eg: [ jobs1, jobs2, ...... ] @@ -113,3 +113,122 @@ end def remove_singleton(groups) groups.delete_if { |_k, v| v.length < 2 } end + +# -------------------------------------------------------------------------------------------------- +# auto group job_list by user's template +# Example: +# Input: +# 1. jobs_list. +# 2. params from template include: +# groups_params(x_params): +# eg: ['block_size', 'package_size'] +# dimensions: +# eg: [ +# {'os' => 'openeuler', 'os_version' => '20.03'}, +# {'os' => 'centos', 'os_version' => '7.6'} +# ] +# metrics: +# eg: ['fio.read_iops', 'fio_write_iops'] +# Output: +# eg: +# { +# '4K|1G' => { +# 'openeuler 20.03' => [ +# {'stats' => {'fio.write_iops' => 312821.002387, 'fio.read_iops' => 212821.2387}}, +# {'stats' => {'fio.write_iops' => 289661.878453}}, +# ... +# ], +# 'centos 7.6' => [...] +# }, +# '16K|1G' => {...}, +# ... +# } +# + +def auto_group_by_template(jobs_list, group_params, dimensions, metrics) + job_list = extract_jobs_list(jobs_list) + get_group_by_template(job_list, group_params, dimensions, metrics) +end + +def get_group_by_template(job_list, group_params, dimensions, metrics) + groups = {} + job_list.each do |job| + next unless job['stats'] + + group_key = get_user_group_key(job, group_params) + dimension = get_user_dimension(job, dimensions) + next unless group_key && dimension + + new_job = get_new_job_by_metrics(job, metrics) + next if new_job.empty? + + groups[group_key] ||= {} + groups[group_key][dimension] ||= [] + groups[group_key][dimension] << new_job + end + groups +end + +# @group_params Array(String) +# eg: +# ['block_size', 'package_size'] +# return eg: +# '4K|1G' +def get_user_group_key(job, group_params) + group_key_list = [] + group_params.each do |param| + if job.key?(param) + group_key_list << job[param] + next + end + job.each_value do |v| + if v.is_a?(Hash) && v.key?(param) + group_key_list << v[param] + break + end + end + end + return nil if group_key_list.size < group_params.size || group_key_list.empty? + + group_key_list.join('|') +end + +# @dimension Array(Hash) +# eg: +# [ +# {os => openeuler, os_version => 20.03}, +# {os => centos, os_version => 7.6} +# ] +# return eg: +# 'openeuler 20.03' +def get_user_dimension(job, dimensions) + dimension_list = [] + dimensions.each do |dim| + dim.each do |key, value| + if job[key] == value + dimension_list << value + end + end + return nil if !dimension_list.empty? && dimension_list.size < dim.size + end + return nil if dimension_list.empty? + + dimension_list.join(' ') +end + +# @metrics Array(String) +# eg: +# ["fio.read_iops", "fio.write_iops"] +# return new_job +# eg: +# {'stats' => {'fio.write_iops' => 312821.002387, 'fio.read_iops' => 212821.2387}}, +def get_new_job_by_metrics(job, metrics) + new_job = {} + metrics.each do |metric| + if job['stats'].key?(metric) + new_job['stats'] ||= {} + new_job['stats'][metric] = job['stats'][metric] + end + end + new_job +end
On Thu, Oct 29, 2020 at 05:07:22PM +0800, Wu Fengguang wrote:
+# Output: +# eg: +# { +# '4K|1G' => { +# 'openeuler 20.03' => [
这种不匹配echarts格式啊
这一步是把查出来的job, 按照x_params 自动分组 { x_params_1 => { dimension_1 => [job1, job2], dimension_2 => [job3, job4] }, x_params_2 => {...} } 这里顺便按template中的metrics过滤了一下,所以每个job就只有 'stats' => {'metric' => xxxx}
下一步,为每一组生成matrix: { x_params_1 => { dimension_1 => matrix, dimension_2 => matrix }, x_params_2 => {...} }
最后, 按组(x_params)compare, 输出适合echart的json数据
生成matrix 和compare的功能主要服用之前的代码,类似于原先的group compare模式
Thanks, Weitao
+# {'stats' => {'fio.write_iops' => 312821.002387, 'fio.read_iops' => 212821.2387}}, +# {'stats' => {'fio.write_iops' => 289661.878453}},
Thanks, Fengguang
}
+# {'stats' => {'fio.write_iops' => 312821.002387, 'fio.read_iops' => 212821.2387}}, +# {'stats' => {'fio.write_iops' => 289661.878453}},
Thanks, Fengguang
the groups-matrices(according to template.yaml) can use old auto-group-compare mode, get average/stddev/change value result as bellow:
4k|1G
openeuler 20.03 debian sid metric -------------------- ------------------------------ ------------------------------ %stddev change %stddev \ | \ 308298.55 ± 12% -28.5% 220289.08 fio.write_iops
next, we can create json result for echart.
Thanks, weitao
On Thu, Oct 29, 2020 at 05:30:47PM +0800, Lu Weitao wrote:
On Thu, Oct 29, 2020 at 05:07:22PM +0800, Wu Fengguang wrote:
+# Output: +# eg: +# { +# '4K|1G' => { +# 'openeuler 20.03' => [
这种不匹配echarts格式啊
这一步是把查出来的job, 按照x_params 自动分组
So you are talking about some internal and intermediate data? Then should add function name before the comment. Like this
+# auto_group_by_template: auto group job_list by user's template
Thanks, Fengguang
On Sat, Oct 31, 2020 at 09:02:28PM +0800, Wu Fengguang wrote:
On Thu, Oct 29, 2020 at 05:30:47PM +0800, Lu Weitao wrote:
On Thu, Oct 29, 2020 at 05:07:22PM +0800, Wu Fengguang wrote:
+# Output: +# eg: +# { +# '4K|1G' => { +# 'openeuler 20.03' => [
这种不匹配echarts格式啊
这一步是把查出来的job, 按照x_params 自动分组
So you are talking about some internal and intermediate data? Then should add function name before the comment. Like this
+# auto_group_by_template: auto group job_list by user's template
yes, it's better.
Thanks, Weitao
Thanks, Fengguang
Yuhang, would you help review?
Thanks, Fengguang
On Thu, Oct 29, 2020 at 04:46:05PM +0800, Lu Weitao wrote:
auto group jobs with user-defined template to support template compare mode background: before compare, create job-groups for all jobs that query from ES with user's filter then, create matrices-groups according job-groups finally, compare each group matrices
Signed-off-by: Lu Weitao luweitaobe@163.com
lib/params_group.rb | 121 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 120 insertions(+), 1 deletion(-)
diff --git a/lib/params_group.rb b/lib/params_group.rb index 0f07d26..3c6de7a 100644 --- a/lib/params_group.rb +++ b/lib/params_group.rb @@ -2,7 +2,7 @@ # Copyright (c) 2020 Huawei Technologies Co., Ltd. All rights reserved. # frozen_string_literal: true
-# Exammple: +# Example: # Input: jobs_list. The results of ES query. # # eg: [ jobs1, jobs2, ...... ] @@ -113,3 +113,122 @@ end def remove_singleton(groups) groups.delete_if { |_k, v| v.length < 2 } end
+# -------------------------------------------------------------------------------------------------- +# auto group job_list by user's template +# Example: +# Input: +# 1. jobs_list. +# 2. params from template include: +# groups_params(x_params): +# eg: ['block_size', 'package_size'] +# dimensions: +# eg: [ +# {'os' => 'openeuler', 'os_version' => '20.03'}, +# {'os' => 'centos', 'os_version' => '7.6'} +# ] +# metrics: +# eg: ['fio.read_iops', 'fio_write_iops'] +# Output: +# eg: +# { +# '4K|1G' => { +# 'openeuler 20.03' => [ +# {'stats' => {'fio.write_iops' => 312821.002387, 'fio.read_iops' => 212821.2387}}, +# {'stats' => {'fio.write_iops' => 289661.878453}}, +# ... +# ], +# 'centos 7.6' => [...] +# }, +# '16K|1G' => {...}, +# ... +# } +#
+def auto_group_by_template(jobs_list, group_params, dimensions, metrics)
- job_list = extract_jobs_list(jobs_list)
- get_group_by_template(job_list, group_params, dimensions, metrics)
+end
+def get_group_by_template(job_list, group_params, dimensions, metrics)
- groups = {}
- job_list.each do |job|
- next unless job['stats']
- group_key = get_user_group_key(job, group_params)
- dimension = get_user_dimension(job, dimensions)
- next unless group_key && dimension
- new_job = get_new_job_by_metrics(job, metrics)
- next if new_job.empty?
- groups[group_key] ||= {}
- groups[group_key][dimension] ||= []
- groups[group_key][dimension] << new_job
- end
- groups
+end
+# @group_params Array(String) +# eg: +# ['block_size', 'package_size'] +# return eg: +# '4K|1G' +def get_user_group_key(job, group_params)
- group_key_list = []
- group_params.each do |param|
- if job.key?(param)
group_key_list << job[param]
next
- end
- job.each_value do |v|
if v.is_a?(Hash) && v.key?(param)
group_key_list << v[param]
break
end
- end
- end
- return nil if group_key_list.size < group_params.size || group_key_list.empty?
- group_key_list.join('|')
+end
+# @dimension Array(Hash) +# eg: +# [ +# {os => openeuler, os_version => 20.03}, +# {os => centos, os_version => 7.6} +# ] +# return eg: +# 'openeuler 20.03' +def get_user_dimension(job, dimensions)
- dimension_list = []
- dimensions.each do |dim|
- dim.each do |key, value|
if job[key] == value
dimension_list << value
end
- end
- return nil if !dimension_list.empty? && dimension_list.size < dim.size
- end
- return nil if dimension_list.empty?
- dimension_list.join(' ')
+end
+# @metrics Array(String) +# eg: +# ["fio.read_iops", "fio.write_iops"] +# return new_job +# eg: +# {'stats' => {'fio.write_iops' => 312821.002387, 'fio.read_iops' => 212821.2387}}, +def get_new_job_by_metrics(job, metrics)
- new_job = {}
- metrics.each do |metric|
- if job['stats'].key?(metric)
new_job['stats'] ||= {}
new_job['stats'][metric] = job['stats'][metric]
- end
- end
- new_job
+end
2.23.0
On Sat, Oct 31, 2020 at 09:03:32PM +0800, Wu Fengguang wrote:
Yuhang, would you help review?
Thanks, Fengguang
Yes, this version I did not find problems.
Thanks, Zhang Yuhang
On Thu, Oct 29, 2020 at 04:46:05PM +0800, Lu Weitao wrote:
auto group jobs with user-defined template to support template compare mode background: before compare, create job-groups for all jobs that query from ES with user's filter then, create matrices-groups according job-groups finally, compare each group matrices
Signed-off-by: Lu Weitao luweitaobe@163.com
lib/params_group.rb | 121 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 120 insertions(+), 1 deletion(-)
diff --git a/lib/params_group.rb b/lib/params_group.rb index 0f07d26..3c6de7a 100644 --- a/lib/params_group.rb +++ b/lib/params_group.rb @@ -2,7 +2,7 @@ # Copyright (c) 2020 Huawei Technologies Co., Ltd. All rights reserved. # frozen_string_literal: true
-# Exammple: +# Example: # Input: jobs_list. The results of ES query. # # eg: [ jobs1, jobs2, ...... ] @@ -113,3 +113,122 @@ end def remove_singleton(groups) groups.delete_if { |_k, v| v.length < 2 } end
+# -------------------------------------------------------------------------------------------------- +# auto group job_list by user's template +# Example: +# Input: +# 1. jobs_list. +# 2. params from template include: +# groups_params(x_params): +# eg: ['block_size', 'package_size'] +# dimensions: +# eg: [ +# {'os' => 'openeuler', 'os_version' => '20.03'}, +# {'os' => 'centos', 'os_version' => '7.6'} +# ] +# metrics: +# eg: ['fio.read_iops', 'fio_write_iops'] +# Output: +# eg: +# { +# '4K|1G' => { +# 'openeuler 20.03' => [ +# {'stats' => {'fio.write_iops' => 312821.002387, 'fio.read_iops' => 212821.2387}}, +# {'stats' => {'fio.write_iops' => 289661.878453}}, +# ... +# ], +# 'centos 7.6' => [...] +# }, +# '16K|1G' => {...}, +# ... +# } +#
+def auto_group_by_template(jobs_list, group_params, dimensions, metrics)
- job_list = extract_jobs_list(jobs_list)
- get_group_by_template(job_list, group_params, dimensions, metrics)
+end
+def get_group_by_template(job_list, group_params, dimensions, metrics)
- groups = {}
- job_list.each do |job|
- next unless job['stats']
- group_key = get_user_group_key(job, group_params)
- dimension = get_user_dimension(job, dimensions)
- next unless group_key && dimension
- new_job = get_new_job_by_metrics(job, metrics)
- next if new_job.empty?
- groups[group_key] ||= {}
- groups[group_key][dimension] ||= []
- groups[group_key][dimension] << new_job
- end
- groups
+end
+# @group_params Array(String) +# eg: +# ['block_size', 'package_size'] +# return eg: +# '4K|1G' +def get_user_group_key(job, group_params)
- group_key_list = []
- group_params.each do |param|
- if job.key?(param)
group_key_list << job[param]
next
- end
- job.each_value do |v|
if v.is_a?(Hash) && v.key?(param)
group_key_list << v[param]
break
end
- end
- end
- return nil if group_key_list.size < group_params.size || group_key_list.empty?
- group_key_list.join('|')
+end
+# @dimension Array(Hash) +# eg: +# [ +# {os => openeuler, os_version => 20.03}, +# {os => centos, os_version => 7.6} +# ] +# return eg: +# 'openeuler 20.03' +def get_user_dimension(job, dimensions)
- dimension_list = []
- dimensions.each do |dim|
- dim.each do |key, value|
if job[key] == value
dimension_list << value
end
- end
- return nil if !dimension_list.empty? && dimension_list.size < dim.size
- end
- return nil if dimension_list.empty?
- dimension_list.join(' ')
+end
+# @metrics Array(String) +# eg: +# ["fio.read_iops", "fio.write_iops"] +# return new_job +# eg: +# {'stats' => {'fio.write_iops' => 312821.002387, 'fio.read_iops' => 212821.2387}}, +def get_new_job_by_metrics(job, metrics)
- new_job = {}
- metrics.each do |metric|
- if job['stats'].key?(metric)
new_job['stats'] ||= {}
new_job['stats'][metric] = job['stats'][metric]
- end
- end
- new_job
+end
2.23.0