Rastreie quem visualizou cada ticket no GLPI com Ticket Tracker

No GLPI padrão não há registro de leitura. O módulo gratuito Ticket Tracker grava cada visualização de ticket - contagem, primeira e última leitura e log de cada acesso por usuário - e ainda rende as consultas SQL para achar chamados que o responsável nunca abriu.

No GLPI padrão não existe registro de leitura: o histórico do chamado guarda o que mudou, nunca quem apenas abriu e leu. Na sustentação de parques GLPI de clientes, isso vira o clássico impasse do "o técnico nem olhou o chamado" contra "eu li, sim" - e sem um dado objetivo é a palavra de um contra a do outro. O módulo gratuito Ticket Tracker fecha essa lacuna registrando cada visualização de ticket. Este guia mostra como ele grava os dados, como configurá-lo sem inflar contadores e três consultas SQL que respondem "quem leu o quê" na hora.

Por que o GLPI não sabe quem leu um chamado

O histórico nativo (glpi_logs) só registra alterações: criação, mudança de status, novo acompanhamento, troca de técnico. Abrir o formulário e ler não muda nenhum campo, então não gera linha nenhuma. Não há, no núcleo do GLPI, um evento de "visualização". O Ticket Tracker resolve isso enganchando no ponto em que o formulário do ticket é renderizado (o hook postShowItem do Ticket): toda vez que uma sessão autenticada exibe um chamado, o módulo grava a visualização. Sem ação manual, sem campo novo no formulário.

As duas camadas de registro: resumo e log

O módulo grava em duas tabelas com propósitos distintos. A de resumo responde "quantas vezes e quando"; a de log responde "cada acesso, um a um":

-- Resumo por (ticket, usuário): uma linha, atualizada a cada acesso.
CREATE TABLE `glpi_plugin_nextool_tickettracker_views` (
  `id`         int unsigned NOT NULL AUTO_INCREMENT,
  `tickets_id` int unsigned NOT NULL,
  `users_id`   int unsigned NOT NULL,
  `view_count` int unsigned NOT NULL DEFAULT 1,
  `first_view` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `last_view`  timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uniq_ticket_user` (`tickets_id`, `users_id`)
);

-- Log detalhado: uma linha por acesso individual.
CREATE TABLE `glpi_plugin_nextool_tickettracker_viewlog` (
  `id`         int unsigned NOT NULL AUTO_INCREMENT,
  `tickets_id` int unsigned NOT NULL,
  `users_id`   int unsigned NOT NULL,
  `view_date`  timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
);

A chave UNIQUE (tickets_id, users_id) é o coração da tabela de resumo: cada par ticket/usuário tem exatamente uma linha. A gravação usa INSERT ... ON DUPLICATE KEY UPDATE view_count = view_count + 1, um upsert atômico - dois acessos simultâneos do mesmo usuário não criam linha duplicada nem perdem contagem. A aba "Visualizações" no ticket lê o resumo (tabela com todos os visualizadores, contagem, primeira e última leitura) e oferece uma cascata expansível que puxa do log cada acesso individual, com data e hora.

Ativação e checklist de configuração

O módulo é gratuito e liga no catálogo NexTool. Depois de ativado, a configuração fica em Módulos > Ticket Tracker, aba Funcionalidades:

  1. Módulo ativo - o mesmo toggle da página de Módulos. Desligado, nada é rastreado.
  2. Tracking ativo (tracking_enabled) - liga a gravação das visualizações. Pode ficar ligado com a aba escondida, se você quiser coletar sem expor.
  3. Exibir aba no ticket (show_tab_on_ticket) - mostra ou oculta a aba "Visualizações" no formulário do chamado.
  4. Intervalo mínimo (s) (min_interval_seconds, padrão 60) - janela de debounce: acessos do mesmo usuário ao mesmo ticket dentro desse intervalo contam como um só.
  5. Ignorados (aba Permissões adicionais) - usuários, perfis ou grupos que visualizam sem serem rastreados. Tudo em branco = todos os acessos contam.

O erro de campo que infla (ou zera) os contadores

O erro comum é zerar o intervalo mínimo achando que "quanto mais granular, melhor". O gancho dispara a cada render do formulário - inclusive em recarregamentos, navegação de volta e reaberturas da aba. Com min_interval_seconds = 0, um técnico que deixa o chamado aberto e dá três F5 vira "três leituras", e o view_count perde o sentido de "quantas vezes ele de fato voltou ao assunto". O padrão de 60 segundos existe justamente para colapsar a rajada de recarregamentos numa leitura só. Use 0 apenas em diagnóstico pontual e volte ao padrão depois.

O segundo erro é mais sutil e nós batemos nele em cliente: até a versão 1.2.0 do módulo, a gravação dependia da permissão de ver a aba de Visualizações - ou seja, só perfis administrativos eram contados. O requerente e os observadores abriam o chamado e nada era registrado, então a base subnotificava exatamente quem mais interessa numa disputa de SLA. Desacoplamos o registro da permissão de ver a aba: hoje qualquer sessão autenticada que renderiza o ticket é contabilizada - requerente, observador ou técnico - independente do perfil. Se você opera uma versão anterior, atualize antes de confiar nos números.

Matriz de decisão: intervalo e ignorados por cenário

O ajuste certo depende do que você quer provar. A matriz que usamos no desenho:

Cenário de operaçãoTrackingIntervalo mínimo (s)Quem colocar em "ignorados"
Auditoria de leitura / SLA (padrão)Ligado60Ninguém
Parque com refresh automático ou painel de paredeLigado180 a 300Contas de integração / robôs
Supervisão que não deve inflar o contadorLigado60Perfil de gestores / auditores
Diagnóstico pontual (contar cada acesso)Ligado0 (temporário)Ninguém

Três consultas SQL que respondem na hora

A aba resolve o caso a caso; para visão de parque, vá direto ao banco. Chamados abertos atribuídos que o técnico responsável ainda não abriu (type = 2 em glpi_tickets_users é o técnico atribuído):

-- Chamados abertos atribuídos que o técnico responsável NUNCA visualizou.
SELECT t.id AS chamado, t.name AS titulo, u.name AS tecnico, t.date AS aberto_em
FROM glpi_tickets t
JOIN glpi_tickets_users tu ON tu.tickets_id = t.id AND tu.type = 2
JOIN glpi_users u ON u.id = tu.users_id
LEFT JOIN glpi_plugin_nextool_tickettracker_views v
       ON v.tickets_id = t.id AND v.users_id = tu.users_id
WHERE t.is_deleted = 0
  AND t.status IN (1, 2, 3, 4)   -- novo, atribuído, planejado, pendente
  AND v.id IS NULL               -- nenhuma leitura registrada pelo técnico
ORDER BY t.date ASC;

Latência de leitura - quantos minutos o chamado ficou aberto até a primeira leitura do técnico atribuído. É a métrica que antecede a primeira resposta e costuma explicar SLA estourado:

-- Minutos entre a abertura e a 1a leitura pelo técnico atribuído.
SELECT t.id AS chamado,
       TIMESTAMPDIFF(MINUTE, t.date, v.first_view) AS minutos_ate_1a_leitura
FROM glpi_tickets t
JOIN glpi_tickets_users tu ON tu.tickets_id = t.id AND tu.type = 2
JOIN glpi_plugin_nextool_tickettracker_views v
       ON v.tickets_id = t.id AND v.users_id = tu.users_id
WHERE t.is_deleted = 0
ORDER BY minutos_ate_1a_leitura DESC;

Os visualizadores mais ativos de um chamado específico, do resumo, para saber quem realmente acompanha (troque 12345 pelo ID do ticket):

-- Quem mais abriu o chamado 12345, do mais recorrente ao menos.
SELECT u.name AS usuario, v.view_count, v.first_view, v.last_view
FROM glpi_plugin_nextool_tickettracker_views v
JOIN glpi_users u ON u.id = v.users_id
WHERE v.tickets_id = 12345
ORDER BY v.view_count DESC;

Leitura não é resposta: o que o contador prova

O dado é poderoso, mas tem um limite honesto: ele prova que o formulário foi renderizado para aquele usuário, não que a pessoa leu com atenção nem que agiu. Um view_count alto sem acompanhamento é sinal amarelo - alguém está abrindo e fechando sem resolver. Um chamado com zero visualização do responsável e o SLA correndo é sinal vermelho - ninguém sequer olhou. Na sustentação, o valor real não é vigiar técnico, é fechar a lacuna probatória: quando o cliente pergunta "por que esse chamado ficou parado três dias?", a resposta deixa de ser opinião e passa a ter carimbo de data e hora.

Precisa de visibilidade real sobre o atendimento no seu GLPI, com os módulos certos ativados e ajustados ao seu fluxo? Conheça a sustentação de GLPI da NexTool.


Este conteúdo foi produzido com auxílio de inteligência artificial e revisado pela equipe Nextool Solutions.

Perguntas Frequentes

Não. O histórico (glpi_logs) só grava alterações de campos - status, acompanhamento, troca de técnico. Abrir e ler não muda nada, então não existe registro nativo de visualização. O Ticket Tracker preenche essa lacuna gravando cada exibição do formulário do ticket.

Não na versão atual. O log detalhado guarda ticket, usuário e data/hora de cada acesso; a identificação é pelo usuário autenticado do GLPI, não pelo IP. Para auditoria por pessoa, o users_id é mais confiável que IP, que muda com VPN, NAT e proxy.

Não, se o intervalo mínimo estiver configurado. O padrão de 60 segundos faz acessos do mesmo usuário ao mesmo ticket dentro da janela contarem como um. Só com intervalo 0 cada F5 vira uma leitura - use 0 apenas para diagnóstico e volte ao padrão.

Coloque o usuário, o perfil ou o grupo na lista de "ignorados" (aba Permissões adicionais). Quem se enquadra visualiza normalmente, mas o acesso não é registrado - útil para supervisão e para contas de integração.

Cruze glpi_tickets_users (type = 2, técnico atribuído) com a tabela de resumo do módulo por LEFT JOIN e filtre v.id IS NULL. A consulta do artigo lista exatamente os chamados abertos, atribuídos e nunca lidos pelo responsável.

Sim. É um módulo gratuito do NexTool, disponível para GLPI 10 e 11, e ativa direto pelo catálogo, sem configuração adicional obrigatória.

Precisa de ajuda?