tiagomacul
Giga Sage

 

tiagomacul_0-1740608225899.png

 

 

No universo do ServiceNow, rastrear as mudanças e atividades em registros é crucial para auditoria, depuração e entendimento do fluxo de trabalho. É aí que entram em cena as tabelas sys_history_set, sys_history_line e sys_audit, juntamente com o poder do GlideRecord.

 

GlideRecord: A Porta de Entrada para o Histórico

O GlideRecord é a ferramenta essencial para interagir com as tabelas do ServiceNow através de scripts. Com ele, podemos consultar, inserir, atualizar e deletar registros em qualquer tabela, incluindo as de histórico.

 

sys_history_set: O Agrupador de Mudanças

A tabela sys_history_set funciona como um contêiner, agrupando todas as mudanças realizadas em um registro em um determinado momento. Cada registro nesta tabela representa um conjunto de mudanças.

Limpo após 30 dias se não for utilizado 🧹.

https://<instance>.service-now.com/now/nav/ui/classic/params/target/sys_auto_flush_list.do%3Fsysparm_query%3DtablenameSTARTSWITHsys_history_set%26sysparm_first_row%3D1%26sysparm_view%3D%26sysparm_choice_query_raw%3D%26sysparm_list_header_search%3Dtrue

tiagomacul_0-1754685348167.png

 

 

sys_history_line: O Detalhamento das Mudanças

A tabela sys_history_line detalha as mudanças individuais dentro de um conjunto. Cada registro nesta tabela representa uma mudança específica em um campo do registro.

 

 

 

sys_audit: O Registro Completo de Auditoria

A tabela sys_audit é o registro completo de auditoria do ServiceNow. Ela armazena todas as mudanças realizadas em registros auditados, incluindo informações como o usuário que realizou a mudança, a data e hora da mudança, e os valores antigo e novo do campo alterado.

 

Como usar essas tabelas em scripts?

 

 

 

 

 

 

var grHistorySet = new GlideRecord('sys_history_set');
grHistorySet.addQuery('id', 'SYS_ID_DO_REGISTRO'); // Substitua pelo sys_id do registro
grHistorySet.query();

while (grHistorySet.next()) {
  // Acessar os registros sys_history_line relacionados
  var grHistoryLine = new GlideRecord('sys_history_line');
  grHistoryLine.addQuery('set', grHistorySet.sys_id);
  grHistoryLine.query();

  while (grHistoryLine.next()) {
    // Acessar os detalhes da mudança
    gs.log('Campo: ' + grHistoryLine.element + ', Valor antigo: ' + grHistoryLine.oldvalue + ', Valor novo: ' + grHistoryLine.newvalue);
  }
}

 

 

 

 

 

 

Como realmente deve ser executado em seus scripts usando HistoryWalker

 

 

 

var recordSysId = "1cf6094d1b99201070f10f60f54bcb2f"; // Substitua pelo sys_id correto
var tableName = "sys_history_set"; // Substitua pelo nome da tabela correta


var hw = new sn_hw.HistoryWalker(tableName, recordSysId, 'HISTORY'); // Substitua com os valores corretos

while (hw.walkForward()) {
  var walkedRecord = hw.getWalkedRecord();
  var fields = GlideScriptRecordUtil.get(walkedRecord).getChangedFieldNames();

  gs.log('Update number: ' + hw.getUpdateNumber());

  for (var i = 0; i < fields.length; i++) {
    var fieldName = fields[i];
    gs.log('Campo: ' + fieldName + ', Valor: ' + walkedRecord.getValue(fieldName));
  }
}

 

 

 

 

Acessando o Registro de Auditoria com GlideRecord:

 

 

 

 

 

 

var grAudit = new GlideRecord('sys_audit');
grAudit.addQuery('documentkey', 'SYS_ID_DO_REGISTRO'); // Substitua pelo sys_id do registro
grAudit.query();

while (grAudit.next()) {
  // Acessar os detalhes da auditoria
  gs.log('Campo: ' + grAudit.fieldname + ', Valor antigo: ' + grAudit.oldvalue + ', Valor novo: ' + grAudit.newvalue + ', Usuário: ' + grAudit.sys_created_by);
}

 

 

 

 

Utilizando HistoryWalker

 

 

 

var recordSysId = "1cf6094d1b99201070f10f60f54bcb2f"; // Substitua pelo sys_id correto
var tableName = "sys_audit"; // Substitua pelo nome da tabela correta

var hw = new sn_hw.HistoryWalker(tableName, recordSysId 'AUDIT'); // Substitua com os valores corretos

while (hw.walkForward()) {
  var walkedRecord = hw.getWalkedRecord();
  var fields = GlideScriptRecordUtil.get(walkedRecord).getChangedFieldNames();

  gs.log('Update number: ' + hw.getUpdateNumber());

  for (var i = 0; i < fields.length; i++) {
    var fieldName = fields[i];
    gs.log('Campo: ' + fieldName + ', Valor: ' + walkedRecord.getValue(fieldName));
  }
}

 

 

 

 

 

 

Sample

 

 

 

 

 

 

varTarget = "";
var grRecord = new GlideRecord("task");
grRecord.addQuery("sys_id", "1cf6094d1b99201070f10f60f54bcb2f");
grRecord.query();
if (grRecord.next()) 
{
  varTarget = grRecord.getValue("sys_id");
   gs.log("number = " + grRecord.number.getDisplayValue());
}
var LineID = "";
var grSet = new GlideRecord("sys_history_set");
grSet.addQuery("id", varTarget);
grSet.query();
if (grSet.next()) 
{
   gs.log("ID = " + grSet.id.getDisplayValue());
   LineID = grSet.getValue("sys_id");
}
var grLine =new GlideRecord("sys_history_line");
grLine.addQuery("set", LineID);
grLine.query();
if (grLine.next()) 
{
   gs.log("Line ID = " + grLine.set.getDisplayValue());
}
var grAudit = new GlideRecord("sys_audit");
grAudit.addQuery("documentkey", varTarget);
grAudit.query();
if (grAudit.next()) 
{
   gs.log("audit = " + grAudit.sys_id.getDisplayValue())
}

 

 

 

 

Utilizando HistoryWalker

 

 

var recordSysId = "1cf6094d1b99201070f10f60f54bcb2f"; // Substitua pelo sys_id correto
var tableName = "task"; // Substitua pelo nome da tabela correta

var grRecord = new GlideRecord(tableName);
grRecord.get(recordSysId);
if (grRecord.isValidRecord()) {
  gs.log("number = " + grRecord.number.getDisplayValue());

  var hw = new sn_hw.HistoryWalker(tableName, recordSysId, "CHECKPOINT");

  while (hw.walkForward()) {
    var walkedRecord = hw.getWalkedRecord();
    var fields = GlideScriptRecordUtil.get(walkedRecord).getChangedFieldNames();

    gs.log("Update number: " + hw.getUpdateNumber());

    for (var i = 0; i < fields.length; i++) {
      var fieldName = fields[i];
      gs.log("Campo: " + fieldName + ", Valor: " + walkedRecord.getValue(fieldName));
    }
  }
} else {
  gs.log("Registro não encontrado.");
}

 

 

 

 

tiagomacul_1-1740608274308.png

 

 

Considerações Importantes:

  • Desempenho: Consultar grandes volumes de dados de histórico pode impactar o desempenho da plataforma. Utilize filtros e queries eficientes e por isso é importante utilizar  [ServiceNow Developer] API Reference: HistoryWalker
  • Permissões: Verifique as permissões dos usuários que executam os scripts para garantir que eles tenham acesso às tabelas de histórico.
  • Boas práticas: Utilize as APIs e funções do ServiceNow para acessar e manipular os dados de histórico, evitando consultas diretas ao banco de dados sempre que possível.

 

As tabelas sys_history_set, sys_history_line e sys_audit, combinadas com o poder do GlideRecord, oferecem um conjunto de ferramentas robusto para rastrear e analisar as mudanças em registros no ServiceNow. Dominar essas ferramentas é essencial para administradores, desenvolvedores e auditores que desejam ter um controle completo sobre o histórico da plataforma.

 

 

obs: colaboração de Pankaj Kumar me atentou sobre o auto flush em seu post nol linkedin.

 

tiagomacul_2-1740608291066.jpeg

 

 

Participe, entre nas comunidades, acompanhem os posts:

Comments
Vivi Brasil
Kilo Sage

@tiagomaculOlá Tiago, parabéns por seus conteúdos, sempre colaboram demais com toda a comunidade do Brasil, além de sua ampla contribuição com toda a comunidade global! 👏

Eu só adicionaria um item brevemente aqui:

 

  • Para obter os dados destas tabelas por script, é recomendado usar a API chamada HistoryWalker

Algumas referências para a API:

 

 

Além da melhor performance ao obter os dados, há maior integridade nos resultados, pois as tabelas sys_history_set e sys_history_line, são tabelas que não retém os dados em todo o tempo (elas armazenam conforme os dados são usados/acessados, e depois há rotinas de saneamento do Table Cleaner e do Table Rotation que removem e rotacionam após determinado período).

Digo isso, porque nós tivemos um problema ao tentar obter os dados destas tabelas, usando a API do GlideRecord convencional, em determinado momento, parecia trazer o resultado esperado, mas após um período (quando os dados já não estavam mais armazenados), já não tínhamos a mesma integridade, foi quando identificamos a API do HistoryWalker e passamos a usa-la, o que resolveu.

 

Estes KB Articles abaixo, descrevem este comportamento da Audit e da History Set:

 

 

Abraço,
Vivi Brasil

tiagomacul
Giga Sage

Muito bom @Vivi Brasil Show, Ótima colaboração 

: )

 

vamos atualizar os exemplos.

Vivi Brasil
Kilo Sage

Eu quem agradeço por considerar @tiagomacul , e obrigada por atualizar os exemplos!

Artigos sempre impecáveis! 😃

Paulo Dias1
Tera Contributor

Bom dia!

 

Obrigado aos dois! Muito bom o artigo Macul, e o complemento Vivi.

Version history
Last update:
3 weeks ago
Updated by: