Zabbix API integration Power BI

Matheus Andrade
Zabbix Brasil
Published in
5 min readJul 14, 2021

Hoje vamos de Zabbix e Power BI, como todos já sabem o Zabbix é um ferramenta poderosa de monitoramento, com um banco de dados repleto de informações que muitas das vezes não são 100% aproveitadas para gerar um relatório.

Pensando nisso veio a ideia de realizar uma integração com o Power BI, nessa integração vamos realizar a consulta via API, lembrando também que é possível realizar a integração direta ao banco de dados.

No exemplo que vou citar vou demonstrar a captura de todos os devices inventariados no Zabbix.

  • No Power BI Desktop, abra ‘Transform Data’.
No Power BI Desktop, abra ‘Transform Data’.
  • Configure quatro parâmetros de texto: um para seu usuário Zabbix, um para sua senha Zabbix, um para sua URL Zabbix e um para armazenar seu token Zabbix:

Abra o Editor avançado para ‘GetZabbixToken’ e copie e cole o código a seguir (este código pressupõe que você está usando parâmetros, conforme listado acima como uma etapa opcional). Este JSON fará uma chamada para o seu servidor Zabbix e recuperará um token único.

let
user=User,
password=Password,
url=ZabbixURL,
Body = "{
""jsonrpc"": ""2.0"",
""method"": ""user.login"",
""params"": {
""user"":""" & user & """,
""password"":""" & password & """
},
""auth"": null,
""id"": 1
}",
Source = Json.Document (
Web.Contents(
url,
[
Headers=[
#"Content-Type"="application/json"
],
Content = Text.ToBinary(Body)
]
)
)
in
Source
  • Ao fechar o editor avançado, seu JSON será executado. Se tudo estiver correto, você deverá ver resultados semelhantes à captura de tela abaixo, com um token no campo de resultado. Se você vir ‘erro’ no campo de resultado, clique nele para expandir o erro e ver o que está errado.
  • Copie o token gerado acima e cole no parâmetro ZabbixToken.
  • Desative a consulta GetZabbixToken. Observação: você também pode executar GetZabbixToken a cada vez e fazer referência a essa consulta em vez de usar um parâmetro. Eu escolho o método do parâmetro, pois você só precisa obter o token uma vez e não há necessidade de gerar um novo token toda vez que você atualizar os dados.

Obtenha dados do Zabbix

Agora que temos nosso Power BI configurado para se comunicar com o Zabbix via API, vamos realizar nossas consultas via API.

  • Crie outra consulta em branco e renomeie-a para ‘ZabbixUsers’. Abra o ‘Editor Avançado’, copie e cole o código abaixo. Isso usará o parâmetro token criado anteriormente e chamará o método user.get da API do Zabbix. Em seguida, ele converterá o JSON resultante em uma tabela e expandirá os dados:
let
token = ZabbixToken,
Body =
"{
""jsonrpc"": ""2.0"",
""method"": ""host.get"",
""params"": {
""selectInventory"":true,
""output"": ""extend""
},
""auth"": """ & token & """,
""id"": 1
}",
Source = Json.Document(
Web.Contents(
ZabbixURL,
[
Headers=[
#"Content-Type"="application/json"
],
Content = Text.ToBinary(Body)
]
)
),
result = Source[result],
#"Converted to Table" = Table.FromList(result, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
#"Expanded Column1" = Table.ExpandRecordColumn(#"Converted to Table", "Column1", {"hostid", "proxy_hostid", "host", "status", "disable_until", "error", "available", "errors_from", "lastaccess", "ipmi_authtype", "ipmi_privilege", "ipmi_username", "ipmi_password", "ipmi_disable_until", "ipmi_available", "snmp_disable_until", "snmp_available", "maintenanceid", "maintenance_status", "maintenance_type", "maintenance_from", "ipmi_errors_from", "snmp_errors_from", "ipmi_error", "snmp_error", "jmx_disable_until", "jmx_available", "jmx_errors_from", "jmx_error", "name", "flags", "templateid", "description", "tls_connect", "tls_accept", "tls_issuer", "tls_subject", "tls_psk_identity", "tls_psk", "proxy_address", "auto_compress", "discover", "inventory_mode", "inventory"}, {"hostid", "proxy_hostid", "host", "status", "disable_until", "error", "available", "errors_from", "lastaccess", "ipmi_authtype", "ipmi_privilege", "ipmi_username", "ipmi_password", "ipmi_disable_until", "ipmi_available", "snmp_disable_until", "snmp_available", "maintenanceid", "maintenance_status", "maintenance_type", "maintenance_from", "ipmi_errors_from", "snmp_errors_from", "ipmi_error", "snmp_error", "jmx_disable_until", "jmx_available", "jmx_errors_from", "jmx_error", "name", "flags", "templateid", "description", "tls_connect", "tls_accept", "tls_issuer", "tls_subject", "tls_psk_identity", "tls_psk", "proxy_address", "auto_compress", "discover", "inventory_mode", "inventory"}),
#"FILTER: inventory_mode = 1" = Table.SelectRows(#"Expanded Column1", each [inventory_mode] = "0"),
#"Expanded inventory" = Table.ExpandRecordColumn(#"FILTER: inventory_mode = 1", "inventory", {"type", "type_full", "name", "alias", "os", "os_full", "os_short", "serialno_a", "serialno_b", "tag", "asset_tag", "macaddress_a", "macaddress_b", "hardware", "hardware_full", "software", "software_full", "software_app_a", "software_app_b", "software_app_c", "software_app_d", "software_app_e", "contact", "location", "location_lat", "location_lon", "notes", "chassis", "model", "hw_arch", "vendor", "contract_number", "installer_name", "deployment_status", "url_a", "url_b", "url_c", "host_networks", "host_netmask", "host_router", "oob_ip", "oob_netmask", "oob_router", "date_hw_purchase", "date_hw_install", "date_hw_expiry", "date_hw_decomm", "site_address_a", "site_address_b", "site_address_c", "site_city", "site_state", "site_country", "site_zip", "site_rack", "site_notes", "poc_1_name", "poc_1_email", "poc_1_phone_a", "poc_1_phone_b", "poc_1_cell", "poc_1_screen", "poc_1_notes", "poc_2_name", "poc_2_email", "poc_2_phone_a", "poc_2_phone_b", "poc_2_cell", "poc_2_screen", "poc_2_notes"}, {"inventory.type", "inventory.type_full", "inventory.name", "inventory.alias", "inventory.os", "inventory.os_full", "inventory.os_short", "inventory.serialno_a", "inventory.serialno_b", "inventory.tag", "inventory.asset_tag", "inventory.macaddress_a", "inventory.macaddress_b", "inventory.hardware", "inventory.hardware_full", "inventory.software", "inventory.software_full", "inventory.software_app_a", "inventory.software_app_b", "inventory.software_app_c", "inventory.software_app_d", "inventory.software_app_e", "inventory.contact", "inventory.location", "inventory.location_lat", "inventory.location_lon", "inventory.notes", "inventory.chassis", "inventory.model", "inventory.hw_arch", "inventory.vendor", "inventory.contract_number", "inventory.installer_name", "inventory.deployment_status", "inventory.url_a", "inventory.url_b", "inventory.url_c", "inventory.host_networks", "inventory.host_netmask", "inventory.host_router", "inventory.oob_ip", "inventory.oob_netmask", "inventory.oob_router", "inventory.date_hw_purchase", "inventory.date_hw_install", "inventory.date_hw_expiry", "inventory.date_hw_decomm", "inventory.site_address_a", "inventory.site_address_b", "inventory.site_address_c", "inventory.site_city", "inventory.site_state", "inventory.site_country", "inventory.site_zip", "inventory.site_rack", "inventory.site_notes", "inventory.poc_1_name", "inventory.poc_1_email", "inventory.poc_1_phone_a", "inventory.poc_1_phone_b", "inventory.poc_1_cell", "inventory.poc_1_screen", "inventory.poc_1_notes", "inventory.poc_2_name", "inventory.poc_2_email", "inventory.poc_2_phone_a", "inventory.poc_2_phone_b", "inventory.poc_2_cell", "inventory.poc_2_screen", "inventory.poc_2_notes"})
in
#"Expanded inventory"

Você tera um resultado semelhante abaixo:

Agora ja temos uma tabela com todas informações de inventarios dos hosts, feito isso podemos realizar outras consultas, toda consulta via API nos retorna um resultado em JSON onde transformamos este resultado em uma tabela para visualização no Power BI.

Abaixo um exemplo para obter informações dos problems no Zabbix :

let
token = ZabbixToken,
Body =
"{
""jsonrpc"": ""2.0"",
""method"": ""problem.get"",
""params"": {
""output"": ""extend"",
""selectAcknowledges"": ""extend"",
""recent"": ""true""
},
""auth"": """ & token & """,
""id"": 2
}",
Source = Json.Document(
Web.Contents(
ZabbixURL,
[
Headers=[
#"Content-Type"="application/json"
],
Content = Text.ToBinary(Body)
]
)
),
result = Source[result],
#"Converted to Table" = Table.FromList(result, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
#"Expanded Column1" = Table.ExpandRecordColumn(#"Converted to Table", "Column1", {"eventid", "name", "severity", "clock"}),
#"Valor Substituído" = Table.ReplaceValue(#"Expanded Column1","3","média",Replacer.ReplaceText,{"severity"}),
#"Valor Substituído1" = Table.ReplaceValue(#"Valor Substituído","4","alto",Replacer.ReplaceText,{"severity"}),
#"Valor Substituído2" = Table.ReplaceValue(#"Valor Substituído1","2","aviso",Replacer.ReplaceText,{"severity"}),
#"Valor Substituído3" = Table.ReplaceValue(#"Valor Substituído2","1"," informação",Replacer.ReplaceText,{"severity"}),
#"Valor Substituído4" = Table.ReplaceValue(#"Valor Substituído3","5","desastre",Replacer.ReplaceText,{"severity"}),
#"Coluna Duplicada" = Table.DuplicateColumn(#"Valor Substituído4", "clock", "clock - Copiar"),
#"Tipo Alterado" = Table.TransformColumnTypes(#"Coluna Duplicada",{{"clock - Copiar", Int64.Type}}),
#"Colunas Renomeadas" = Table.RenameColumns(#"Tipo Alterado",{{"clock - Copiar", "data"}}),
#"Personalização Adicionada" = Table.AddColumn(#"Colunas Renomeadas", "Personalizar", each #datetime(1970,1,1,0,0,0) + #duration(0,0,0,[data])),
#"Tipo Alterado1" = Table.TransformColumnTypes(#"Personalização Adicionada",{{"Personalizar", type date}})
in
#"Tipo Alterado1"

Uma coisa interessante é que o Zabbix nos retorna as Datas no formato de Unix, dentro deste codigo acima eu já realizei a conversão do mesmo para date time.

Abaixo alguns exemplos de dashboard para visualização das informações:

(Nestes tutorial usamos como referencia o material da empresa spikefishsolutions)

Espero que seja util para vocês esse tutorial, forte abraço.

--

--