templates-zabbix-itguys/templates_gold/nginx_agent/generate_nginx_satellite.py

139 lines
6.2 KiB
Python

import yaml
import uuid
import sys
# Schema based on the user's 'detailed_proxy' log_format
LOG_FIELDS = [
# Group, Key, Type, Description, JSONPath
("Timestamps", "timestamp", "TEXT", "Time ISO8601", "$.@timestamp"),
("Timestamps", "request_id", "TEXT", "Unique Request ID", "$.request_id"),
("Network", "remote_addr", "TEXT", "Client IP", "$.remote_addr"),
("Network", "real_ip", "TEXT", "Real IP (X-Forwarded-For)", "$.real_ip"),
("Network", "remote_user", "TEXT", "Authenticated User", "$.remote_user"),
("Request", "request_method", "TEXT", "HTTP Method", "$.request_method"),
("Request", "host_header", "TEXT", "Host Header", "$.host_header"),
("Request", "uri", "TEXT", "URI", "$.uri"),
("Request", "request_length", "UNSIGNED", "Request Length (bytes)", "$.request_length"),
("Response", "status", "UNSIGNED", "HTTP Status Code", "$.status"),
("Response", "body_bytes_sent", "UNSIGNED", "Body Bytes Sent", "$.body_bytes_sent"),
("Response", "bytes_sent", "UNSIGNED", "Total Bytes Sent", "$.bytes_sent"),
("Performance", "request_time", "FLOAT", "Request Time (Total)", "$.request_time"),
("Performance", "upstream_connect_time", "FLOAT", "Upstream Connect Time", "$.upstream_connect_time"),
("Performance", "upstream_header_time", "FLOAT", "Upstream Header Time", "$.upstream_header_time"),
("Performance", "upstream_response_time", "FLOAT", "Upstream Response Time", "$.upstream_response_time"),
("Performance", "upstream_cache_status", "TEXT", "Cache Status", "$.upstream_cache_status"),
("GeoIP", "geoip_country_code", "TEXT", "GeoIP Country Code", "$.geoip_country_code"),
("GeoIP", "geoip_city_name", "TEXT", "GeoIP City Name", "$.geoip_city_name"),
("GeoIP", "geoip_isp", "TEXT", "GeoIP ISP", "$.geoip_isp"),
("Security", "is_bad_bot", "TEXT", "Bad Bot Flag", "$.is_bad_bot"),
("Security", "block_request", "TEXT", "WAF Block Flag", "$.block_request"),
("Security", "ssl_protocol", "TEXT", "SSL Protocol", "$.ssl_protocol"),
("Security", "ssl_cipher", "TEXT", "SSL Cipher", "$.ssl_cipher"),
]
def generate_satellite_template(output_file):
template_uuid = "sat00000-0000-0000-0000-000000000001" # Fixed UUID for consistency
group_uuid = "7df96b18c230490a9a0a9e2307226338" # Templates/Applications group
items = []
# MASTER ITEM
# We assume the host is the site itself, so we might need a macro for the log path or
# assume a standard path based on the host name.
# The user said: "encontrar todos os arquivos .conf... e usar este nome para criar um novo host"
# And "o caminho sempre vai ser o padrao".
# We will use {$NGINX.SITE.LOG} macro which will be populated by the Discovery rule on the Manager level.
master_item_uuid = str(uuid.uuid4())
master_item = {
'uuid': master_item_uuid,
'name': 'Access Log Stream',
'type': 'ZABBIX_ACTIVE',
'key': 'log[{$NGINX.SITE.LOG}]',
'delay': '1s',
'value_type': 'LOG',
'history': '7d',
'tags': [{'tag': 'component', 'value': 'log_stream'}]
}
items.append(master_item)
# DEPENDENT ITEMS
for group, key_suffix, value_type, desc, path in LOG_FIELDS:
# Some items might be strings in JSON but we want Numbers in Zabbix
# If value_type is FLOAT/UNSIGNED, we should ensure preprocessing handles it correctly.
# Determine strict type
zabbix_type = 'TEXT'
if value_type == 'FLOAT':
zabbix_type = 'FLOAT'
elif value_type == 'UNSIGNED':
zabbix_type = 'FLOAT' # Use Float for safety with numbers, standardizing
item = {
'uuid': str(uuid.uuid4()),
'name': f'Nginx Site: {desc}',
'type': 'DEPENDENT',
'key': f'nginx.site.{key_suffix}',
'delay': '0',
'value_type': zabbix_type,
'description': desc,
'history': '30d',
'preprocessing': [
{
'type': 'JSONPATH',
'parameters': [path],
'error_handler': 'DISCARD_VALUE' # Discard if field missing
}
],
'master_item': {'key': master_item['key']},
'tags': [{'tag': 'component', 'value': group.lower()}]
}
items.append(item)
# Add calculated/special items (Trigger-based)
# Example: Cache Hit Ratio calculation is best done in Grafana or via Calculated Item if we have aggregate data.
# Since these are log-based, 'DEPENDENT' items are per-line.
# To get "Ratio per minute", we need aggregate items (Calculated from Discovery rules on the Manager, OR separate calculated items here).
# BUT, dependent items only fire on each log line. You can't calculate "Ratio of last minute" easily from a stream of dependent items without using "Trend/History" functions in Calculated Items.
# We will add simple Calculated Items for Stats.
# 5XX Errors Rate
items.append({
'uuid': str(uuid.uuid4()),
'name': 'Nginx Site: HTTP 5xx Rate',
'type': 'CALCULATED',
'key': 'nginx.site.status.5xx.rate',
'params': 'count(//nginx.site.status, 1m, "ge", 500)',
'value_type': 'FLOAT',
'units': 'rps',
'delay': '1m',
'tags': [{'tag': 'component', 'value': 'availability'}]
})
template = {
'zabbix_export': {
'version': '7.0',
'template_groups': [{'uuid': group_uuid, 'name': 'Templates/Applications'}],
'templates': [{
'uuid': template_uuid,
'template': 'Template Nginx Custom Site Analysis',
'name': 'Template Nginx Custom Site Analysis',
'description': 'Analyzes JSON logs for a specific Nginx site host.',
'groups': [{'name': 'Templates/Applications'}],
'items': items,
}]
}
}
with open(output_file, 'w', encoding='utf-8') as f:
yaml.dump(template, f, sort_keys=False, allow_unicode=True)
print(f"Generated {output_file}")
if __name__ == "__main__":
generate_satellite_template("template_nginx_site_analysis.yaml")