Verificando a integridade da aplicação ASP.NET Core com Health Checks \| TreinaWeb               Promoção no ar   Matricule-se agora e garanta **54% de desconto**  

  Termina em   Tempo restante da oferta: 06 Horas 

 43 Min 

 43 Seg 

   Tempo restante da oferta: 06 43 43 

  [Assinar →](https://www.treinaweb.com.br/checkout/pagamento/plano/anual?cupom=TW-SCLIENTE26) 

   [                ](https://www.treinaweb.com.br)  Explorar  

 [ Quanto custa? ](#assinatura) [ FAQ ](https://www.treinaweb.com.br#faq) [Matricule-se](#assinatura) [ Entrar ](https://www.treinaweb.com.br/login) 

     [ Início ](https://www.treinaweb.com.br) [ Artigos ](https://www.treinaweb.com.br/blog) Verificando a integridade da aplicação ASP.NET Core com Health Checks  [ C# ](https://www.treinaweb.com.br/blog/categoria/csharp) [ ASP .NET ](https://www.treinaweb.com.br/blog/categoria/asp-net) [ .NET Core ](https://www.treinaweb.com.br/blog/categoria/net-core) 

# Verificando a integridade da aplicação ASP.NET Core com Health Checks

 Verificar e monitorar a integridade de uma aplicação web é algo essencial, principalmente em ambientes distribuídos. O ASP.NET Core facilita esta tarefa através de Health Checks, como você verá neste artigo.

 [ Wladimilson M. Nascimento ](https://www.treinaweb.com.br/blog/autor/wladimilson-m-nascimento) 7 anos atrás

  ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/08/14131229/HEALTH-CHECKS.png)  

Alguns artigos passados falei sobre as ferramentas de linha de comando que permitem [diagnosticar uma aplicação no .NET Core 3.0](https://www.treinaweb.com.br/blog/diagnosticando-uma-aplicacao-no-net-core-3-0/). Por serem ferramentas de linha de comando, elas requerem acesso a máquina onde a aplicação está instalada. Infelizmente em muitos cenários algo assim não é possível, mas o monitoramento do status da aplicação não deixa de ser importante nesses casos.

Se tratando de aplicações ASP.NET, antigamente o comum era criar um endpoint que retornasse o estado da aplicação ou menos nada era definido. Mas com a adoção cada vez maior de microsserviços e a criação de aplicações para um ambiente distribuído, implementar a verificação da integridade da aplicação se tornou algo essencial.

[  ![C# (C Sharp) Básico](https://d2knvm16wkt3ia.cloudfront.net/assets/svg-icon/csharp.svg)   Curso C# (C Sharp) Básico Conhecer o curso ](https://www.treinaweb.com.br/curso/csharp-basico)

Felizmente, a partir da versão 2.2 do ASP.NET Core, foi introduzido os Health Checks que facilitam este trabalho.

## Conhecendo os Health Checks

Health check é um middleware que fornece um endpoint que retorna o status da aplicação. Na sua versão básica, a aplicação é considerada saudável caso retorne o código 200 (OK) para uma solicitação web. Mas também são fornecidas bibliotecas que nos permite verificar o status de serviços utilizados pela aplicação, como: banco de dados, sistema de mensageria, cache, logging, serviços externos ou mesmo a criação de um health check customizado.

## Aplicação que terá a integridade verificada

Para exemplificar o uso do health check, vou utilizar uma aplicação ASP.NET Core Web API simples, que já foi mostrada no artigo sobre a [documentação de uma ASP.NET Core Web API com o Swagger](https://www.treinaweb.com.br/blog/documentando-uma-asp-net-core-web-api-com-o-swagger/), que você pode ver no meu [Github](https://github.com/wladimilson/TodoAPI).

## Adicionando o Health Check na aplicação

Agora que já temos a aplicação, já podemos ativar o health check nela. Para isso, basta adicionar o service no método `ConfigureServices` da classe `Startup` e indicar a URL dele no método `Configure`:

```csharp
public void ConfigureServices(IServiceCollection services)
{
    //....
    services.AddHealthChecks();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    //...

    //Ativa o HealthChecks
    app.UseHealthChecks("/status");
    //...
}

```

Agora, ao executar a aplicação e acessar a URL `/status` será exibido se ela está saudável ou não:

![](https://dkrn4sk0rn31v.cloudfront.net/2019/08/13172144/aplicacao-saudavel.png)

Como está sendo testado apenas se ela responde a uma requisição, a aplicação é considerada saudável.

## Integridade do banco de dados

Existem várias formas de testar a integridade do banco de dados. É fornecido uma gama de pacotes que nos permite testar a integridade do banco de acordo com o SGBD:

- **SQL Server:** `AspNetCore.HealthChecks.SqlServer`;
- **MySQL:** `AspNetCore.HealthChecks.MySql`;
- **PostgreSQL:** `AspNetCore.HealthChecks.Npgsql`;
- **SQLite:** `AspNetCore.HealthChecks.SqLite`;
- **Oracle:** `AspNetCore.HealthChecks.Oracle`;
- **MongoDb:** `AspNetCore.HealthChecks.MongoDb`.

Caso esteja trabalhando com o Entity Framework, também há o pacote `Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore`, que será o que utilizaremos na aplicação:

```dos
dotnet add package Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore

```

Com isso, basta adicionar a classe `DbContext`, que o estado da conexão com o banco será verificada:

```csharp
public void ConfigureServices(IServiceCollection services)
{
    //...
    services.AddHealthChecks()
            .AddDbContextCheck();
}

```

Se o banco estiver saudável, o resultado não será alterado:

![](https://dkrn4sk0rn31v.cloudfront.net/2019/08/13172144/aplicacao-saudavel.png)

Caso haja algum problema com a conexão com o banco, a aplicação não será considerada saudável:

![](https://dkrn4sk0rn31v.cloudfront.net/2019/08/13172143/aplicacao-nao-saudavel.png)

## Alterando as informações exibidas

No momento, somos informados apenas se a aplicação está ou não saudável. Para uma aplicação pequena, isso pode ser útil, mas imagine uma aplicação que verifica vários serviços? Apenas com esta informação não conseguiremos saber qual serviço não está funcionando corretamente.

Para obter esses dados, podemos customizar as informações de saída do health check, definindo um delegate na opção `ResponseWriter`:

```csharp
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    //...

    //Ativa o HealthChecks
    app.UseHealthChecks("/status", new HealthCheckOptions()
    {
        // WriteResponse é um delegate que permite alterar a saída.
        ResponseWriter = (httpContext, result) => {
            httpContext.Response.ContentType = "application/json";

            var json = new JObject(
                new JProperty("status", result.Status.ToString()),
                new JProperty("results", new JObject(result.Entries.Select(pair =>
                    new JProperty(pair.Key, new JObject(
                        new JProperty("status", pair.Value.Status.ToString()),
                        new JProperty("description", pair.Value.Description),
                        new JProperty("data", new JObject(pair.Value.Data.Select(
                            p => new JProperty(p.Key, p.Value))))))))));
            return httpContext.Response.WriteAsync(json.ToString(Formatting.Indented));
        }
    });
    //...
}

```

Com isso, obteremos a causa do problema da aplicação:

![](https://dkrn4sk0rn31v.cloudfront.net/2019/08/13172143/aplicacao-nao-saudavel-detalhes.png)

## Criando health checks customizados

Existe uma grande gama de health checks definidos, mas em algumas situações, pode ser necessário definir um customizado. Para isso, é necessário definir uma classe que implemente a interface `IHealthCheck` e definir no método `CheckHealthAsync` qual tipo de verificação ele fará:

```csharp
public class SelfHealthCheck : IHealthCheck
{
    public Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
    {
        return Task.FromResult(new HealthCheckResult(
            HealthStatus.Healthy,
            description: "API up!"));
    }
}

```

Acima é definido um health check simples, que apenas indica que a API está funcionando.

[  ![C# (C Sharp) Intermediário](https://d2knvm16wkt3ia.cloudfront.net/assets/svg-icon/csharp.svg)   Curso C# (C Sharp) Intermediário Conhecer o curso ](https://www.treinaweb.com.br/curso/csharp-intermediario)

Agora é necessário adicioná-lo ao serviço com o método `AddCheck`:

```csharp
public void ConfigureServices(IServiceCollection services)
{
    //...
    services.AddHealthChecks()
            .AddDbContextCheck()
            .AddCheck("Self");
}

```

Também pode ser definido um método de extensão:

```csharp
public static class HealthCheckBuilderExtensions
{
    public static IHealthChecksBuilder AddSelfCheck(this IHealthChecksBuilder builder, string name, HealthStatus? failureStatus = null, IEnumerable tags = null)
    {
        // Register a check of type SelfHealthCheck
        builder.AddCheck(name, failureStatus ?? HealthStatus.Degraded, tags);

        return builder;
    }
}

```

E utilizá-lo para registrar o health check:

```csharp
public void ConfigureServices(IServiceCollection services)
{
    //...
    services.AddHealthChecks()
            .AddDbContextCheck()
            .AddSelfCheck("Self");
}

```

Ao acessar a aplicação, ele também será mostrado:

![](https://dkrn4sk0rn31v.cloudfront.net/2019/08/13172142/aplicacao-saudavel-custom-health-checker.png)

## Adicionando uma interface

No momento o resultado do status da aplicação é um JSON, mas existe um pacote que nos permite visualizar as informações em uma interface gráfica. Para isso, adicione na aplicação os pacotes `AspNetCore.HealthChecks.UI` e `AspnetCore.HealthChecks.UI.Client`:

```dos
dotnet add package AspNetCore.HealthChecks.UI
dotnet add package AspnetCore.HealthChecks.UI.Client

```

Em seguida é necessário habilitar o *Health Checks UI* nos métodos `ConfigureServices` e `Configure` da classe `Startup`:

```csharp
public void ConfigureServices(IServiceCollection services)
{
    //....
    services.AddHealthChecks()
            .AddDbContextCheck()
            .AddSelfCheck("Self");

    services.AddHealthChecksUI();
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    //...

    //Ativa o HealthChecks
    app.UseHealthChecks("/status", new HealthCheckOptions()
    {
        // WriteResponse is a delegate used to write the response.
        ResponseWriter = (httpContext, result) => {
            httpContext.Response.ContentType = "application/json";

            var json = new JObject(
                new JProperty("status", result.Status.ToString()),
                new JProperty("results", new JObject(result.Entries.Select(pair =>
                    new JProperty(pair.Key, new JObject(
                        new JProperty("status", pair.Value.Status.ToString()),
                        new JProperty("description", pair.Value.Description),
                        new JProperty("data", new JObject(pair.Value.Data.Select(
                            p => new JProperty(p.Key, p.Value))))))))));
            return httpContext.Response.WriteAsync(json.ToString(Formatting.Indented));
        }
    });

    //Ativa o HealthChecks utilizado pelo HealthCheckUI
    app.UseHealthChecks("/status-api", new HealthCheckOptions()
    {
        Predicate = _ => true,
        ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
    });

    app.UseHealthChecksUI(opt => {
        opt.UIPath = "/status-dashboard";
    });

    //...
}

```

Além de habilitar o *Health Checks UI* note que também é definido um novo endpoint para o health check, configurado para o delegate `UIResponseWriter.WriteHealthCheckUIResponse`. Este é um delegate criado pelo *Health Checks UI*, e configura um arquivo JSON que será lido pela biblioteca.

Para que ele seja lido, é necessário especificá-lo no arquivo **appsettings.json**:

```json
{
  "HealthChecks-UI": {
    "HealthChecks": [
      {
        "Name": "Status-API",
        "Uri": "https://localhost:5001/status-api"
      }
    ]
  }
}

```

Com isso, ao executar a aplicação e acessar a URL `/status-dashboard` a interface será exibida:

![](https://dkrn4sk0rn31v.cloudfront.net/2019/08/13172141/aplicacao-saudavel-healthcheckerui.png)

Por hoje é isso :)

[  ![C# (C Sharp) Avançado](https://d2knvm16wkt3ia.cloudfront.net/assets/svg-icon/csharp.svg)   Curso C# (C Sharp) Avançado Conhecer o curso ](https://www.treinaweb.com.br/curso/csharp-avancado)

Lembrando que você pode ver o código da aplicação no [Github](https://github.com/wladimilson/TodoAPI).

- [ #API ](https://www.treinaweb.com.br/blog/tag/api)
- [ #.NET Core ](https://www.treinaweb.com.br/blog/tag/net-core)
- [ #ASP .NET Core ](https://www.treinaweb.com.br/blog/tag/asp-net-core)
- [ #Web API ](https://www.treinaweb.com.br/blog/tag/web-api)

Autor

 ![Wladimilson M. Nascimento](//secure.gravatar.com/avatar/f0dd442f156a3eacd2880e9cd0eafbd1?d=mm)

## Wladimilson M. Nascimento

 Instrutor, nerd, cinéfilo e desenvolvedor nas horas vagas. Graduado em Ciências da Computação pela Universidade Metodista de São Paulo. 

 [Todos os artigos](https://www.treinaweb.com.br/blog/autor/wladimilson-m-nascimento)  

## Continue estudando

 Transforme leitura em prática com os cursos e formações da TreinaWeb.

 [Ver cursos](https://www.treinaweb.com.br/cursos)   

  Continue lendo

## Artigos relacionados

- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/07/29063746/0-400x280.png)  [ Carreira ](https://www.treinaweb.com.br/blog/categoria/carreira) 

     7 anos atrás

    ##  [ Como funciona uma empresa de desenvolvimento de software? ](https://www.treinaweb.com.br/blog/como-funciona-uma-empresa-de-desenvolvimento-de-software) 

     Veja de forma resumida como é trabalhar em uma empresa de desenvolvimento de software.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2017/07/checklist-de-seguranca-para-autenticacao-400x280.png)  [ Segurança da Informação ](https://www.treinaweb.com.br/blog/categoria/seguranca-da-informacao) 

     10 anos atrás

    ##  [ Checklist de segurança para autenticação ](https://www.treinaweb.com.br/blog/checklist-de-seguranca-para-autenticacao) 

     Cuidar da segurança é um dos pilares para a sustentação de qualquer aplicação na web. Sem o mínimo não é possível nem mesmo garantir uma razoável disponibilidade.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/08/01225056/CERTIFICADO-SSL-400x280.png)  [ Tecnologia ](https://www.treinaweb.com.br/blog/categoria/tecnologia) 

     7 anos atrás

    ##  [ Para que serve o certificado SSL? ](https://www.treinaweb.com.br/blog/para-que-serve-o-certificado-ssl) 

     Confira neste artigo o que é um certificado SSL e como ele funciona.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/07/capa-termos-comuns-segurança-400x280.png)  [ Segurança da Informação ](https://www.treinaweb.com.br/blog/categoria/seguranca-da-informacao) 

     6 anos atrás

    ##  [ Termos comuns de segurança ](https://www.treinaweb.com.br/blog/termos-comuns-de-seguranca) 

     Quando falamos sobre a área de Segurança dentro da Tecnologia da Informação, é comum que existam termos que até já ouvimos falar, mas não sabemos ao certo o que significam. Por isso, neste artigo, vamos abordar alguns termos comuns de segurança.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2023/09/guia-termos-comuns-seguranca-400x280.png)  [ Guias ](https://www.treinaweb.com.br/blog/categoria/guias) 

     3 anos atrás

    ##  [ Guia de termos comuns de segurança ](https://www.treinaweb.com.br/blog/guia-de-termos-comuns-de-seguranca) 

     Neste guia de segurança veremos alguns dos principais ataques que podem acontecer na web.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2023/05/capa-programacao-defensiva-min-400x280.png)  [ Desenvolvimento ](https://www.treinaweb.com.br/blog/categoria/desenvolvimento) 

     3 anos atrás

    ##  [ Programação defensiva: uma estratégia para prevenção de erros ](https://www.treinaweb.com.br/blog/programacao-defensiva-uma-estrategia-para-prevencao-de-erros) 

     Como proteger o código de possíveis erros? Confira neste artigo o que vem a ser a programação defensiva.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/10/pilares-da-seguranca-da-informacao-400x280.png)  [ Segurança da Informação ](https://www.treinaweb.com.br/blog/categoria/seguranca-da-informacao) 

     6 anos atrás

    ##  [ Pilares da Segurança da Informação ](https://www.treinaweb.com.br/blog/pilares-da-seguranca-da-informacao) 

     As empresas tem se atentado aos pilares da segurança da informação, para garantir a proteção de seus dados. Confira neste artigo quais são esses pilares.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2018/01/15145849/planos-de-acao-utilizando-ferramenta-de-gestao-5w2h-400x280.png)  [ Testes e Projetos ](https://www.treinaweb.com.br/blog/categoria/testes-e-projetos) 

     9 anos atrás

    ##  [ Planos de ação utilizando a ferramenta de gestão 5W2H ](https://www.treinaweb.com.br/blog/planos-de-acao-utilizando-ferramenta-de-gestao-5w2h) 

     O 5W2H é uma ferramenta para auxiliar no mapeamento de atividades que deverão ser realizadas.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2022/12/NEST-JS-400x280.png)  [ Desenvolvimento Back-end ](https://www.treinaweb.com.br/blog/categoria/desenvolvimento-back-end) 

     4 anos atrás

    ##  [ Autenticação: Refresh Token com NestJS ](https://www.treinaweb.com.br/blog/autenticacao-refresh-token-com-nestjs) 

     Neste artigo vamos continuar no assunto de autenticação, abordando a estratégia de refresh token com o NestJS.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2021/03/como-instalar-o-dart-e-executar-seu-primeiro-exemplo-400x280.png)  [ Dart ](https://www.treinaweb.com.br/blog/categoria/dart) 

     6 anos atrás

    ##  [ Estruturas condicionais e de repetição no Dart ](https://www.treinaweb.com.br/blog/estruturas-condicionais-e-de-repeticao-no-dart) 

     Neste artigo conheceremos as estruturas condicionais e estruturas de repetição na linguagem de programação Dart.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/07/SEO-WORDPRESS-YOAST-400x280.png)  [ CMS's e E-commerce ](https://www.treinaweb.com.br/blog/categoria/cmss-e-e-commerce) 

     6 anos atrás

    ##  [ Otimizando conteúdo para SEO no Wordpress com Yoast ](https://www.treinaweb.com.br/blog/otimizando-conteudo-para-seo-no-wordpress-com-yoast) 

     Aprenda a otimizar o SEO de suas páginas e posts utilizando o Plugin Yoast SEO para Wordpress e eleve os resultados do seu blog!

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/04/15150148/design-thinking-400x280.png)  [ Design ](https://www.treinaweb.com.br/blog/categoria/design) 

     7 anos atrás

    ##  [ O que é Design Thinking? ](https://www.treinaweb.com.br/blog/o-que-e-design-thinking) 

     Confira neste artigo o que vem a ser o Design Thinking e quais são suas etapas.

     Ler artigo

## Um ano de acesso total para você viver de programação.

 Todos os cursos e formações da TreinaWeb numa única assinatura, com professores que atuam no mercado, suporte direto e certificados. Do primeiro `console.log` ao mercado de trabalho.

- **1 ano** de acesso a **todos os cursos**
- Cursos novos **toda semana**
- Suporte **direto com professores**
- Plano de carreira **personalizado**
- **Certificados digitais** inclusos
- **Aplicativos** para Android e iOS, com **acesso offline**

    **Garantia incondicional de satisfação** 

 Teste por 7 dias e, se não fizer sentido para você, devolvemos seu dinheiro.

### Acesso completo a todos os cursos e dezenas de Formações.

 12 meses 

  Economize R$ 840,00  54% OFF 

 de 12x R$ 129,00 por apenas

 12x  R$ 59,00

 sem juros no cartão de crédito ou R$ 599,00 à vista

  Oferta termina em  **06h 43min 43s**

- Acesso imediato e ilimitado durante 1 ano.
- Plano de carreira personalizado.
- Suporte direto com professores.
- E muito mais!

 [Matricule-se agora](https://www.treinaweb.com.br/checkout/pagamento/plano/anual?cupom=TW-SCLIENTE26)

     [                ](https://www.treinaweb.com.br)

 Escola online de programação, tecnologia e IA.

- [  ](https://www.facebook.com/TreinaWeb/)
- [  ](https://www.instagram.com/treinaweb/)
- [  ](https://www.youtube.com/user/TreinaWeb)
- [  ](https://twitter.com/treinaweb)
- [  ](https://www.linkedin.com/company/treinaweb)
- [  ](https://github.com/treinaweb)

## Inscreva-se em nossa newsletter

Receba lançamentos, promoções e novidades.

   Seu nome     Seu WhatsApp     Seu melhor e-mail   Inscrever-se 

## Cursos

- [ Base para Devs ](https://www.treinaweb.com.br/categoria/base-para-devs)
- [ Front-end ](https://www.treinaweb.com.br/categoria/desenvolvimento-front-end)
- [ Back-end ](https://www.treinaweb.com.br/categoria/desenvolvimento-back-end)
- [ Mobile ](https://www.treinaweb.com.br/categoria/desenvolvimento-mobile)
- [ Bancos de Dados ](https://www.treinaweb.com.br/categoria/bancos-de-dados)
- [ Cloud ](https://www.treinaweb.com.br/categoria/cloud-computing)
- [ IA ](https://www.treinaweb.com.br/categoria/ia)
- [ E mais ](https://www.treinaweb.com.br/categoria/e-mais)
- [ Ver todos os cursos ](https://www.treinaweb.com.br/cursos)

## Conteúdo

- [ Formações ](https://www.treinaweb.com.br/formacoes)
- [ Projetos práticos ](https://www.treinaweb.com.br/projetos-praticos)
- [ Direto ao ponto ](https://www.treinaweb.com.br/direto-ao-ponto)
- [ Planos ](https://www.treinaweb.com.br#assinatura)
- [ Depoimentos ](https://www.treinaweb.com.br#depoimentos)
- [ Comunidade ](https://www.treinaweb.com.br#comunidade)
- [ Corpo docente ](https://www.treinaweb.com.br#docente)

## A empresa

- [ Sobre a TreinaWeb ](https://www.treinaweb.com.br#sobre)
- [ Perguntas frequentes ](https://www.treinaweb.com.br#faq)
- [ Vantagens de estudar na TreinaWeb ](https://www.treinaweb.com.br/vantagens-de-estudar-na-treinaweb)
- [ Cursos para empresas ](https://www.treinaweb.com.br/empresas)
- [ Sugira um novo curso ](https://www.treinaweb.com.br/sugerir-curso)
- [ Trabalhe conosco ](https://www.treinaweb.com.br/trabalhe-conosco)
- [ Artigos ](https://www.treinaweb.com.br/blog)
- [ Desenvolvedores e agentes ](https://www.treinaweb.com.br/developers)
- [ Contato ](https://www.treinaweb.com.br/contato)
- [ Política de privacidade ](https://www.treinaweb.com.br/politica-de-privacidade)
- [ Termos de uso ](https://www.treinaweb.com.br/termos-de-uso)

## Baixe nosso aplicativo

 [   Disponível na **App Store**  ](https://apps.apple.com/us/app/treinaweb/id1322729447) [   Disponível no **Google Play**  ](https://play.google.com/store/apps/details?id=br.com.treinaweb.mobile) 

  Av. Paulista, 1765, Conj 71 e 72 · Bela Vista · São Paulo · SP · 01311-200   © 2004 – 2026 TreinaWeb Tecnologia LTDA · CNPJ 06.156.637/0001-58
