Criação de perfis de aplicações Python

Esta página descreve como modificar a sua aplicação Python para capturar dados de criação de perfis e enviar esses dados para o seu projeto do Google Cloud. Google CloudPara ver informações gerais acerca da criação de perfis, consulte o artigo Conceitos de criação de perfis.

Tipos de perfis para Python:

  • Tempo da CPU
  • Tempo total (thread principal)

Versões do idioma Python compatíveis:

  • Python 3.6 a 3.11.0.

Versões do agente de criação de perfis suportadas:

  • A versão mais recente do agente é suportada. Geralmente, as versões com mais de um ano não são suportadas. Recomendamos que use a versão do agente lançada mais recentemente.

Sistemas operativos compatíveis:

  • Linux. A criação de perfis de aplicações Python é suportada para kernels Linux cuja biblioteca C padrão é implementada com glibc ou com musl. Para ver informações de configuração específicas dos kernels do Linux Alpine, consulte o artigo Execução no Linux Alpine.

Ambientes suportados:

Ativar a API Profiler

Antes de usar o agente de criação de perfis, certifique-se de que a API Profiler subjacente está ativada. Pode verificar o estado da API e ativá-la, se necessário, através da CLI do Google Cloud ou da Google Cloud consola:

CLI gcloud

  1. Se ainda não instalou a CLI do Google Cloud na sua estação de trabalho, consulte a documentação da CLI do Google Cloud.

  2. Execute o seguinte comando:

    gcloud services enable cloudprofiler.googleapis.com
    

Para mais informações, consulte gcloud services.

Google Cloud consola

  1. Enable the required API.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the API

  2. Se for apresentada a mensagem API ativada, significa que a API já está ativada. Caso contrário, clique no botão Ativar.

Conceda a função do IAM à conta de serviço

Se estiver a implementar a sua aplicação em Google Cloud recursos e se estiver a usar a conta de serviço predefinida e não tiver modificado as concessões de funções para essa conta de serviço, pode ignorar esta secção.

Se realizar qualquer uma das seguintes ações, tem de conceder à conta de serviço a função do IAM de agente do Cloud Profiler (roles/cloudprofiler.agent):

  1. Está a usar a conta de serviço predefinida, mas modificou as concessões de funções.
  2. Está a usar uma conta de serviço criada pelo utilizador.
  3. Está a usar a identidade da carga de trabalho. Conceda a função de agente do Cloud Profiler à conta de serviço do Kubernetes.

Pode conceder uma função de IAM a uma conta de serviço através da Google Cloud consola ou da CLI do Google Cloud. Por exemplo, pode usar o comando gcloud projects add-iam-policy-binding:

gcloud projects add-iam-policy-binding GCP_PROJECT_ID \
    --member serviceAccount:MY_SVC_ACCT_ID@GCP_PROJECT_ID.iam.gserviceaccount.com \
    --role roles/cloudprofiler.agent

Antes de usar o comando anterior, substitua o seguinte:

  • GCP_PROJECT_ID: o ID do seu projeto.
  • MY_SVC_ACCT_ID: o nome da sua conta de serviço.

Para ver informações detalhadas, consulte o artigo Faça a gestão do acesso a projetos, pastas e organizações.

Usar o Cloud Profiler

Para ver as práticas recomendadas de utilização do Python, aceda a Configurar um ambiente de desenvolvimento Python.

Compute Engine

Para o Compute Engine, faça o seguinte:

  1. Instale o compilador C/C++ e as ferramentas de desenvolvimento:

    sudo apt-get install -y build-essential
    
  2. Instale o pip:

    sudo apt-get install -y python3-pip
    
  3. Instale o pacote do Profiler:

    pip3 install google-cloud-profiler
    
  4. Importe o módulo googlecloudprofiler e chame a função googlecloudprofiler.start o mais cedo possível no seu código de inicialização:

    import googlecloudprofiler
    
    
    def main():
        # Profiler initialization. It starts a daemon thread which continuously
        # collects and uploads profiles. Best done as early as possible.
        try:
            googlecloudprofiler.start(
                service="hello-profiler",
                service_version="1.0.1",
                # verbose is the logging level. 0-error, 1-warning, 2-info,
                # 3-debug. It defaults to 0 (error) if not set.
                verbose=3,
                # project_id must be set if not running on GCP.
                # project_id='my-project-id',
            )
        except (ValueError, NotImplementedError) as exc:
            print(exc)  # Handle errors here

    Tem de especificar o parâmetro service na função start. Para filtrar pela versão da aplicação na interface do Profiler, especifique o parâmetro service_version. Para ver informações sobre a resolução de problemas e exceções, consulte o artigo Resolução de problemas.

GKE

Para o GKE, faça o seguinte:

  1. Modifique o Dockerfile para instalar o pacote do Profiler:

    FROM python:3
    ...
    RUN apt-get update && apt-get install -y build-essential python3-pip
    RUN pip3 install google-cloud-profiler
    
  2. Importe o módulo googlecloudprofiler e chame a função googlecloudprofiler.start o mais cedo possível no seu código de inicialização:

    import googlecloudprofiler
    
    
    def main():
        # Profiler initialization. It starts a daemon thread which continuously
        # collects and uploads profiles. Best done as early as possible.
        try:
            googlecloudprofiler.start(
                service="hello-profiler",
                service_version="1.0.1",
                # verbose is the logging level. 0-error, 1-warning, 2-info,
                # 3-debug. It defaults to 0 (error) if not set.
                verbose=3,
                # project_id must be set if not running on GCP.
                # project_id='my-project-id',
            )
        except (ValueError, NotImplementedError) as exc:
            print(exc)  # Handle errors here

    Tem de especificar o parâmetro service na função start. Para filtrar pela versão da aplicação na interface do Profiler, especifique o parâmetro service_version. Para ver informações sobre a resolução de problemas e exceções, consulte o artigo Resolução de problemas.

Ambiente flexível

Para o ambiente flexível do App Engine, faça o seguinte:

  1. Adicione google-cloud-profiler ao seu ficheiro requirements.txt.

  2. Importe o módulo googlecloudprofiler e chame a função googlecloudprofiler.start o mais cedo possível no seu código de inicialização.

Para o App Engine, o service e o service_version são derivados do seu ambiente operacional. Para ver informações sobre a resolução de problemas e exceções, consulte o artigo Resolução de problemas.

Ambiente padrão

Para o ambiente padrão do App Engine, que requer a utilização do ambiente de execução do Python 3, faça o seguinte:

  1. Adicione google-cloud-profiler ao seu ficheiro requirements.txt.

  2. Importe o módulo googlecloudprofiler e chame a função googlecloudprofiler.start o mais cedo possível no seu código de inicialização.

Para o App Engine, o service e o service_version são derivados do seu ambiente operacional. Para ver informações sobre a resolução de problemas e exceções, consulte o artigo Resolução de problemas.

Função start

A função googlecloudprofiler.start cria um thread daemon que recolhe e carrega continuamente perfis. Deve chamar start uma vez e o mais cedo possível na sua aplicação.

Parâmetro Descrição
service1 (Obrigatório) O nome do serviço que está a ser analisado. Para ver restrições no nome do serviço, consulte os Argumentos de nome e versão do serviço.
service_version1 (Opcional) A versão do serviço que está a ser analisada. Para restrições na versão do serviço, consulte Argumentos de nome e versão do serviço.
verbose (Opcional) O nível de registo. Para ver detalhes sobre os níveis de registo, consulte o artigo Registo do agente.

O valor predefinido é 0 (Erro).
project_id2 (Opcional) O seu Google Cloud ID do projeto.
disable_cpu_profiling (Opcional) Para desativar a criação de perfis de tempo da CPU, defina disable_cpu_profiling=True.

Este parâmetro é suportado para as versões do Python 3.2 a 3.11.0. Para todas as outras versões do Python, a criação de perfis de tempo da CPU não é suportada e este parâmetro é ignorado.

O valor predefinido é False.
disable_wall_profiling (Opcional) Para desativar a criação de perfis de paredes, defina disable_wall_profiling=True.

Este parâmetro é suportado para as versões 3.6 a 3.11.0 do Python. Para todas as outras versões do Python, a criação de perfis de paredes não é suportada e este parâmetro é ignorado.

Para ver as restrições da função start quando a criação de perfis de paredes está ativada, consulte as Limitações.

O valor predefinido é False.

1 Apenas para o Compute Engine e o GKE. Para o App Engine, o valor é derivado do ambiente.
2 Para Google Cloud, o valor é derivado do ambiente. Para ambientes nãoGoogle Cloud , tem de fornecer um valor. Para mais informações, consulte o artigo Criar perfis de aplicações executadas fora Google Cloud.

Analisar dados

Depois de o Perfilador recolher dados, pode ver e analisar estes dados através da interface do Perfilador.

Na Google Cloud consola, aceda à página Profiler:

Aceda ao Profiler

Também pode encontrar esta página através da barra de pesquisa.

Argumentos de nome e versão do serviço

Quando carrega o agente do Profiler, especifica um argumento service-name e um argumento service-version opcional para o configurar.

O nome do serviço permite que o Profiler recolha dados de criação de perfis para todas as réplicas desse serviço. O serviço de criação de perfis garante uma taxa de recolha de um perfil por minuto, em média, para cada nome de serviço em todas as combinações de versões e zonas de serviço.

Por exemplo, se tiver um serviço com duas versões em execução em réplicas em três zonas, o criador de perfis cria uma média de 6 perfis por minuto para esse serviço.

Se usar nomes de serviços diferentes para as suas réplicas, o serviço é perfilado com mais frequência do que o necessário, com uma sobrecarga correspondentemente mais elevada.

Ao selecionar um nome do serviço:

  • Escolha um nome que represente claramente o serviço na arquitetura da sua aplicação. A escolha do nome do serviço é menos importante se executar apenas um único serviço ou aplicação. É mais importante se a sua aplicação for executada como um conjunto de microsserviços, por exemplo.

  • Certifique-se de que não usa valores específicos do processo, como um ID do processo, na string service-name.

  • A string service-name tem de corresponder a esta expressão regular:

    ^[a-z0-9]([-a-z0-9_.]{0,253}[a-z0-9])?$

Uma boa diretriz é usar uma string estática como imageproc-service como o nome do serviço.

A versão do serviço é opcional. Se especificar a versão do serviço, o Profiler pode agregar informações de criação de perfis de várias instâncias e apresentá-las corretamente. Pode ser usado para marcar diferentes versões dos seus serviços à medida que são implementadas. A IU do Profiler permite-lhe filtrar os dados por versão do serviço. Desta forma, pode comparar o desempenho de versões mais antigas e mais recentes do código.

O valor do argumento service-version é uma string de forma livre, mas os valores deste argumento têm normalmente o aspeto de números de versão, por exemplo, 1.0.0 ou 2.1.2.

Registo do agente

Por predefinição, o agente de criação de perfis regista mensagens com um nível de gravidade de error. Para configurar o agente para registar mensagens com níveis de gravidade mais baixos, especifique o parâmetro verbose ao iniciar o agente. Existem quatro valores suportados para verbose:

  • 0 : Erro
  • 1 : Aviso
  • 2 : Informativo
  • 3 : Depurar

Se definir o parâmetro verbose como 1 na sua chamada para start, as mensagens com um nível de gravidade de Warning ou Error são registadas, enquanto as mensagens Informational e Debug são ignoradas.

Para registar todas as mensagens, defina verbose como 3 ao iniciar o agente:

googlecloudprofiler.start(service='service_name', verbose=3)

Resolução de problemas

Esta secção apresenta limitações, exceções e problemas conhecidos específicos da criação de perfis de aplicações Python. Consulte a resolução de problemas para obter ajuda com problemas comuns.

Limitações

Tipo de perfil Restrições e limitações
Tempo entre o início e o fim da tarefa
  • Apenas criação de perfis do thread principal.
  • A função start do perfil tem de ser chamada a partir da thread principal.
  • O controlador de sinais do Profiler é executado apenas na thread principal. Se o thread principal não puder ser executado, não são capturados dados de criação de perfis.

Exceções

Erro Causa Solução
NotImplementedError lançados durante start Aplicação executada num ambiente não Linux.
  • Execute a sua aplicação num ambiente Linux.
ValueError lançados durante start Os argumentos da função start são inválidos, não é possível determinar as informações necessárias a partir das variáveis de ambiente e dos argumentos, ou da criação de perfis se a criação de perfis de tempo de CPU e a criação de perfis de tempo real estiverem desativadas.
  • Certifique-se de que o nome e a versão do serviço cumprem os requisitos definidos nos argumentos de nome e versão do serviço.
  • Se a criação de perfis de paredes estiver ativada, certifique-se de que start é chamada a partir da thread principal.
  • Certifique-se de que está a usar uma versão suportada do Python e que a criação de perfis de tempo de CPU ou tempo real está ativada. Para mais informações, consulte a função start.
  • Verifique se especificou o parâmetro project_id como start se estiver a executar fora do Google Cloud. Para mais informações, consulte a função start.

Problemas conhecidos

Comportamento Causa Solução
Não tem dados do perfil ou ativou um novo tipo de perfil e não tem dados do perfil. As causas comuns estão relacionadas com a configuração. Consulte a resolução de problemas.
Está a usar o uWSGI e não tem dados de tempo de CPU nem de perfil de tempo real para todos os processos.

Quando o uWSGI usa vários trabalhadores para processar pedidos, o comportamento predefinido é realizar a inicialização da aplicação apenas no processo principal ("mestre"). Os processos ramificados não executam a sequência de inicialização.

Se configurar o agente de criação de perfis na sequência de inicialização da sua aplicação, por exemplo, em AppConfig.ready() numa aplicação Django, o efeito é que o agente de criação de perfis não é configurado para os processos ramificados.

Para realizar a inicialização da aplicação em todos os processos de trabalho, defina a flag lazy-apps como true.

Consulte o tópico seguinte nesta tabela para ver um problema relacionado.

Está a usar o uWSGI e não tem dados do perfil de parede, mas tem dados do perfil de tempo da CPU.

O Wall profiler depende do módulo de sinal do Python. Quando o intérprete Python é compilado com suporte de threads, a configuração predefinida desativa o processamento de sinais personalizados para processos bifurcados.

Para aplicações uWSGI, ative o processamento de sinais personalizado definindo a flag py-call-osafterfork como true.

Consulte o tópico anterior nesta tabela para ver um problema relacionado.

Depois de ativar o criador de perfis, o registo de erros contém novas entradas:

BlockingIOError: [Errno 11] Resource temporarily unavailable Exception ignored when trying to write to the signal wakeup fd

Problema do GitHub

A sua aplicação registou-se no descritor de ficheiros de ativação de sinal, signal.set_wakeup_fd. Por predefinição, se o buffer do descritor de ficheiro ficar cheio, é registado um aviso no stderr.

Quando o Cloud Profiler recolhe perfis, aciona sinais com alta frequência. Este comportamento pode fazer com que o buffer do descritor de ficheiro fique cheio.

Se a sua aplicação puder ser executada em segurança quando os sinais são perdidos, pode usar o Cloud Profiler. Se estiver a usar o Python 3.7 ou posterior e quiser desativar as mensagens de aviso, transmita warn_on_full_buffer=False como um parâmetro para signal.set_wakeup_fd.

Se a sua aplicação não puder ser executada em segurança quando os sinais são perdidos, recomendamos que deixe de usar o Cloud Profiler. A utilização contínua pode causar a perda de números de sinais e entradas excessivas no registo de erros.

Execução com o Linux Alpine

O agente de criação de perfis do Python para Linux Alpine só é suportado para configurações do Google Kubernetes Engine.

Para criar o agente de criação de perfis do Python, tem de instalar o pacote build-base. Para usar o agente de criação de perfis do Python no Alpine sem instalar dependências adicionais na imagem final do Alpine, pode usar uma compilação de duas fases e compilar o agente de criação de perfis do Python na primeira fase. Por exemplo, a seguinte imagem do Docker usa uma compilação de várias fases para compilar e instalar o agente de criação de perfis do Python:

FROM python:3.7-alpine as builder

# Install build-base to allow for compilation of the profiling agent.
RUN apk add --update --no-cache build-base

# Compile the profiling agent, generating wheels for it.
RUN pip3 wheel --wheel-dir=/tmp/wheels google-cloud-profiler

FROM python:3.7-alpine

# Copy over the directory containing wheels for the profiling agent.
COPY --from=builder /tmp/wheels /tmp/wheels

# Install the profiling agent.
RUN pip3 install --no-index --find-links=/tmp/wheels google-cloud-profiler

# Install any other required modules or dependencies, and copy an app which
# enables the profiler as described in "Enable the profiler in your
# application".
COPY ./bench.py .

# Run the application when the docker image is run, using either CMD (as is done
# here) or ENTRYPOINT.
CMD python3 -u bench.py

Erro de autenticação

Se usar imagens do Docker executadas com o Linux Alpine (como golang:alpine ou apenas alpine), pode ver o seguinte erro de autenticação:

connection error: desc = "transport: authentication handshake failed: x509: failed to load system roots and no roots provided"

Tenha em atenção que, para ver o erro, tem de ter o registo do agente ativado.

O erro indica que as imagens do Docker com o Linux Alpine não têm os certificados SSL de raiz instalados por predefinição. Esses certificados são necessários para que o agente de criação de perfis comunique com a API Profiler. Para resolver este erro, adicione o seguinte comando apk ao seu Dockerfile:

FROM alpine
...
RUN apk add --no-cache ca-certificates

Em seguida, tem de recriar e voltar a implementar a aplicação.

O que se segue?