如何配置 Jinja 配置文件以包含基于通用值的服务检查?
How to configure a Jinja configuration file to include service checks based on generic values?
我公司的ansible被配置为为某些服务构建Nagios模板。
例如:
define service {
use rabbit-critical-service ; Name of service template to use
service_description RabbitMQ {{ queue_name }} queue size
check_command check_graphite_data!1000!15000!rabbitmq._.rabbitmq_messages.{{ queue_name }}.value
host_name {{ rabbitmq_server }}
notifications_enabled 1
servicegroups rabbitmq
}
该模板会自动为所有队列使用相同的阈值构建检查。队列名称在 ansible_playbooks/roles/nagios/defaults/main.yml
下的不同文件中配置,并使用 Jinja 自动生成。
我的任务是让我能够以一种稍微简单的方式编辑配置,以便为某些特定检查包含不同的阈值,但我很难理解如何去做。
我想过类似的事情:
添加到 service_check 模板类似这样的东西:
{% if queue_size_specific_vars is not defined %}
create the check using the current configuration...
{% else %}
create the check using the specific configuration which will be found in the `default/main.yml` file in the newly created generic value "queue_size_specific_vars" which is supposed to include two values, one for warning value and one for critical value.
{% endif %}
我的问题是:
- How do I achieve my goal (while taking into consideration two values instead of one)?
- I'm not sure this is the best way to achieve my goal, do you know a better way to do so?
编辑#1:
看来我没有解释清楚,让我向您展示模板的更大部分:
{% for queue_name in queues %}
define service {
use rabbit-critical-service ; Name of service template to use
service_description RabbitMQ {{ queue_name }} queue active consumers
check_command check_graphite_data!0.9!0.9!rabbitmq._.rabbitmq_consumers.{{ queue_name }}!reverse
host_name {{ rabbitmq_server }}
notifications_enabled 1
servicegroups rabbitmq
max_check_attempts 4
}
{% if vars_production is not defined %}
define service {
use generic-service
service_description RabbitMQ {{ queue_name }} queue read/write ratio
check_command check_graphite!'http://{{ graphite_server }}:{{ graphite_port }}/render/?from=-10minutes&target=scale(divideSeries(offset(prod-rabbit-1.rabbitmq._.rabbitmq_messages.{{queue_name}}.value,1),offset(derivative(sumSeries(prod-rabbit-1.rabbitmq._.rabbitmq_deliver_get.{{queue_name}})),1)),100)&rawData'!1500!2000!avg
host_name {{ rabbitmq_server }}
notifications_enabled 1
servicegroups rabbitmq
max_check_attempts 4
}
{% endif %}
define service {
use rabbit-critical-service ; Name of service template to use
service_description RabbitMQ {{ queue_name }} queue size
check_command check_graphite_data!1000!15000!rabbitmq._.rabbitmq_messages.{{ queue_name }}.value
host_name {{ rabbitmq_server }}
notifications_enabled 1
servicegroups rabbitmq
}
{% endfor %}
这意味着我应该实施的更改应该在队列级别而不是在主机名中,因为 ansible "knows" 仅托管而不 "know" 队列。
我们需要为每个队列设置 "RabbitMQ {{ queue_name }} queue size" 的选项,其余的都使用默认值。
我期望做的更改应该在模板文件本身中进行。
示例:
{% if special_queue_exists %}
do ....
{% else %}
create it in the normal method
{% endif %}
编辑#2:
我的经理希望我以类似于这样的方式来做:
我已经有了包含所有队列的文件,我们称这个文件为 "queues_file"。
他希望我创建另一个文件,其中将包含一个特定检查值列表(警告和关键),我们称这个文件为 "specific_values".
然后做这样的事情:
queues_with_specific_metrics:
- entities:
- warn: "1000"
- crit: "20000"
然后检查我正在 运行 宁(来自 for 循环)的队列是否在 "specific_values" 文件中有特定的配置,如果有,那么 "specific_values" 文件应该覆盖默认文件。
然后,我可以这样做:
{{ queues_with_specific_metrics.queue.warn | default(1000) }}
我是 Ansible 和 Jinja 的新手,这就是为什么我不太容易理解,对此深表歉意。
编辑#3:
我已经按照您的建议编辑了配置,但我不确定如何编写 if 语句...
defaults/main.yml 包含所有队列名称的列表。
我打开了一个名为 spec_params.yml
的新文件,它作为 main.yml
文件位于默认文件夹中。
spec_params.yml
文件:
nagios_specific_queue_params:
queue1: {}
entities:
warn: 2000
crit: 20000
和rabbitmq.cfg.j2
的相关部分:
{% if queue_name in nagios_specific_queue_params %}
define service {
use rabbit-critical-service ; Name of service template to use
service_description RabbitMQ {{ queue_name }} queue size
check_command check_graphite_data!{{ queues[queue_name] ['warn'] |default(1000) }}!{{ queues[queue_name] ['crit'] | default(15000) }}!rabbitmq._.rabbitmq_messages.{{ queue_name }}.value
host_name {{ rabbitmq_server }}
notifications_enabled 1
servicegroups rabbitmq
}
{% else %}
define service {
use rabbit-critical-service ; Name of service template to use
service_description RabbitMQ {{ queue_name }} queue size
check_command check_graphite_data!1000!15000!rabbitmq._.rabbitmq_messages.{{ queue_name }}.value
host_name {{ rabbitmq_server }}
notifications_enabled 1
servicegroups rabbitmq
}
{% endif %}
当我 运行 剧本时,出现以下错误:
fatal: [monitoring] => {'msg': "TypeError: argument of type 'StrictUndefined' is not iterable", 'failed': True}
fatal: [monitoring] => {'msg': 'One or more items failed.', 'failed': True, 'changed': False, 'results'
知道为什么会失败吗?
提前致谢
roles//defaults/ 中的变量可以被任何上层变量覆盖(/vars、group_vars、host_vars 和 inventory vars 中的变量)。
因此,如果您定义一个变量 queue_size
,在默认情况下您可以在 group/host_vars 文件中覆盖它。
# file: roles/nagios/deaults/main.yml
queue_size: "1000!15000"
# file: host_vars/host1.yml
queue_size: "2000!25000"
# file: host_vars/host2.yml
queue_size: "1000!5000"
# file: roles/nagios/templates/check.j2
define service {
use rabbit-critical-service ; Name of service template to use
service_description RabbitMQ {{ queue_name }} queue size
check_command check_graphite_data!{{ queue_size }}!rabbitmq._.rabbitmq_messages.{{ queue_name }}.value
host_name {{ rabbitmq_server }}
notifications_enabled 1
servicegroups rabbitmq
}
这应该可以回答您的两个问题。如果您想要更清晰的 vars 文件,您还可以指定 queue_size_min
和 queue_size_max
。
编辑:
为了更好地解释我在评论中的意思:
你有两种方法(我能想到的)来解决这个问题:
首先:使用一个单独的文件,其中包含非默认队列的值。这可能更干净,但您必须保留原始 var 文件中存在的所有队列:
# file vars/original_file.yml
queues:
- queue1
- entities
# file vars/specific.yml
queue_with_specific_metrics:
queue1: {}
entities:
warn: 1000
crit: 15000
其次:编辑原始文件以在需要时包含特定值
queues:
queue1: {}
entities:
warn: 1000
crit: 2000
在任何一种情况下,您都可以更改模板以采用值或分配默认值:
# case 1
check_command check_graphite_data!{{ queue_with_specific_metrics[queue_name]['warn'] | default(1000) }}!{{ queue_with_specific_metrics[queue_name]['crit'] | default(800) }}!rabbitmq._.rabbitmq_messages.{{ queue_name }}.value}
check_command check_graphite_data!{{ queues[queue_name]['warn'] | default(1000) }}!{{ queues[queue_name]['crit'] | default(800) }}!rabbitmq._.rabbitmq_messages.{{ queue_name }}.value}
这是我为完成任务所做的步骤:
在 nagios/defaults/main.yml
中,我添加了:
nagios_queue_size_default_values:
warn: 1000
crit: 15000
nagios_queue_size_override_values:
entities_prod_whatever_2:
warn: 600
crit: 900
然后,在 rabbitmq.cfg.j2
中,我将检查命令更改为这个:
check_command check_graphite_data!{{ nagios_queue_size_override_values.get(queue_name, nagios_queue_size_default_values).warn }}!{{ nagios_queue_size_override_values.get(queue_name, nagios_queue_size_default_values).crit }}!rabbitmq._.rabbitmq_messages.{{ queue_name }}.value
运行 剧本现在根据需要创建模板。
我公司的ansible被配置为为某些服务构建Nagios模板。
例如:
define service {
use rabbit-critical-service ; Name of service template to use
service_description RabbitMQ {{ queue_name }} queue size
check_command check_graphite_data!1000!15000!rabbitmq._.rabbitmq_messages.{{ queue_name }}.value
host_name {{ rabbitmq_server }}
notifications_enabled 1
servicegroups rabbitmq
}
该模板会自动为所有队列使用相同的阈值构建检查。队列名称在 ansible_playbooks/roles/nagios/defaults/main.yml
下的不同文件中配置,并使用 Jinja 自动生成。
我的任务是让我能够以一种稍微简单的方式编辑配置,以便为某些特定检查包含不同的阈值,但我很难理解如何去做。
我想过类似的事情: 添加到 service_check 模板类似这样的东西:
{% if queue_size_specific_vars is not defined %}
create the check using the current configuration...
{% else %}
create the check using the specific configuration which will be found in the `default/main.yml` file in the newly created generic value "queue_size_specific_vars" which is supposed to include two values, one for warning value and one for critical value.
{% endif %}
我的问题是:
- How do I achieve my goal (while taking into consideration two values instead of one)?
- I'm not sure this is the best way to achieve my goal, do you know a better way to do so?
编辑#1:
看来我没有解释清楚,让我向您展示模板的更大部分:
{% for queue_name in queues %}
define service {
use rabbit-critical-service ; Name of service template to use
service_description RabbitMQ {{ queue_name }} queue active consumers
check_command check_graphite_data!0.9!0.9!rabbitmq._.rabbitmq_consumers.{{ queue_name }}!reverse
host_name {{ rabbitmq_server }}
notifications_enabled 1
servicegroups rabbitmq
max_check_attempts 4
}
{% if vars_production is not defined %}
define service {
use generic-service
service_description RabbitMQ {{ queue_name }} queue read/write ratio
check_command check_graphite!'http://{{ graphite_server }}:{{ graphite_port }}/render/?from=-10minutes&target=scale(divideSeries(offset(prod-rabbit-1.rabbitmq._.rabbitmq_messages.{{queue_name}}.value,1),offset(derivative(sumSeries(prod-rabbit-1.rabbitmq._.rabbitmq_deliver_get.{{queue_name}})),1)),100)&rawData'!1500!2000!avg
host_name {{ rabbitmq_server }}
notifications_enabled 1
servicegroups rabbitmq
max_check_attempts 4
}
{% endif %}
define service {
use rabbit-critical-service ; Name of service template to use
service_description RabbitMQ {{ queue_name }} queue size
check_command check_graphite_data!1000!15000!rabbitmq._.rabbitmq_messages.{{ queue_name }}.value
host_name {{ rabbitmq_server }}
notifications_enabled 1
servicegroups rabbitmq
}
{% endfor %}
这意味着我应该实施的更改应该在队列级别而不是在主机名中,因为 ansible "knows" 仅托管而不 "know" 队列。
我们需要为每个队列设置 "RabbitMQ {{ queue_name }} queue size" 的选项,其余的都使用默认值。 我期望做的更改应该在模板文件本身中进行。
示例:
{% if special_queue_exists %}
do ....
{% else %}
create it in the normal method
{% endif %}
编辑#2:
我的经理希望我以类似于这样的方式来做: 我已经有了包含所有队列的文件,我们称这个文件为 "queues_file"。 他希望我创建另一个文件,其中将包含一个特定检查值列表(警告和关键),我们称这个文件为 "specific_values".
然后做这样的事情:
queues_with_specific_metrics:
- entities:
- warn: "1000"
- crit: "20000"
然后检查我正在 运行 宁(来自 for 循环)的队列是否在 "specific_values" 文件中有特定的配置,如果有,那么 "specific_values" 文件应该覆盖默认文件。 然后,我可以这样做:
{{ queues_with_specific_metrics.queue.warn | default(1000) }}
我是 Ansible 和 Jinja 的新手,这就是为什么我不太容易理解,对此深表歉意。
编辑#3: 我已经按照您的建议编辑了配置,但我不确定如何编写 if 语句...
defaults/main.yml 包含所有队列名称的列表。
我打开了一个名为 spec_params.yml
的新文件,它作为 main.yml
文件位于默认文件夹中。
spec_params.yml
文件:
nagios_specific_queue_params:
queue1: {}
entities:
warn: 2000
crit: 20000
和rabbitmq.cfg.j2
的相关部分:
{% if queue_name in nagios_specific_queue_params %}
define service {
use rabbit-critical-service ; Name of service template to use
service_description RabbitMQ {{ queue_name }} queue size
check_command check_graphite_data!{{ queues[queue_name] ['warn'] |default(1000) }}!{{ queues[queue_name] ['crit'] | default(15000) }}!rabbitmq._.rabbitmq_messages.{{ queue_name }}.value
host_name {{ rabbitmq_server }}
notifications_enabled 1
servicegroups rabbitmq
}
{% else %}
define service {
use rabbit-critical-service ; Name of service template to use
service_description RabbitMQ {{ queue_name }} queue size
check_command check_graphite_data!1000!15000!rabbitmq._.rabbitmq_messages.{{ queue_name }}.value
host_name {{ rabbitmq_server }}
notifications_enabled 1
servicegroups rabbitmq
}
{% endif %}
当我 运行 剧本时,出现以下错误:
fatal: [monitoring] => {'msg': "TypeError: argument of type 'StrictUndefined' is not iterable", 'failed': True}
fatal: [monitoring] => {'msg': 'One or more items failed.', 'failed': True, 'changed': False, 'results'
知道为什么会失败吗?
提前致谢
roles//defaults/ 中的变量可以被任何上层变量覆盖(/vars、group_vars、host_vars 和 inventory vars 中的变量)。
因此,如果您定义一个变量 queue_size
,在默认情况下您可以在 group/host_vars 文件中覆盖它。
# file: roles/nagios/deaults/main.yml
queue_size: "1000!15000"
# file: host_vars/host1.yml
queue_size: "2000!25000"
# file: host_vars/host2.yml
queue_size: "1000!5000"
# file: roles/nagios/templates/check.j2
define service {
use rabbit-critical-service ; Name of service template to use
service_description RabbitMQ {{ queue_name }} queue size
check_command check_graphite_data!{{ queue_size }}!rabbitmq._.rabbitmq_messages.{{ queue_name }}.value
host_name {{ rabbitmq_server }}
notifications_enabled 1
servicegroups rabbitmq
}
这应该可以回答您的两个问题。如果您想要更清晰的 vars 文件,您还可以指定 queue_size_min
和 queue_size_max
。
编辑: 为了更好地解释我在评论中的意思:
你有两种方法(我能想到的)来解决这个问题:
首先:使用一个单独的文件,其中包含非默认队列的值。这可能更干净,但您必须保留原始 var 文件中存在的所有队列:
# file vars/original_file.yml
queues:
- queue1
- entities
# file vars/specific.yml
queue_with_specific_metrics:
queue1: {}
entities:
warn: 1000
crit: 15000
其次:编辑原始文件以在需要时包含特定值
queues:
queue1: {}
entities:
warn: 1000
crit: 2000
在任何一种情况下,您都可以更改模板以采用值或分配默认值:
# case 1
check_command check_graphite_data!{{ queue_with_specific_metrics[queue_name]['warn'] | default(1000) }}!{{ queue_with_specific_metrics[queue_name]['crit'] | default(800) }}!rabbitmq._.rabbitmq_messages.{{ queue_name }}.value}
check_command check_graphite_data!{{ queues[queue_name]['warn'] | default(1000) }}!{{ queues[queue_name]['crit'] | default(800) }}!rabbitmq._.rabbitmq_messages.{{ queue_name }}.value}
这是我为完成任务所做的步骤:
在 nagios/defaults/main.yml
中,我添加了:
nagios_queue_size_default_values:
warn: 1000
crit: 15000
nagios_queue_size_override_values:
entities_prod_whatever_2:
warn: 600
crit: 900
然后,在 rabbitmq.cfg.j2
中,我将检查命令更改为这个:
check_command check_graphite_data!{{ nagios_queue_size_override_values.get(queue_name, nagios_queue_size_default_values).warn }}!{{ nagios_queue_size_override_values.get(queue_name, nagios_queue_size_default_values).crit }}!rabbitmq._.rabbitmq_messages.{{ queue_name }}.value
运行 剧本现在根据需要创建模板。