Configurar o log nas bibliotecas do Azure para Python

As Bibliotecas do Azure para Python baseadas em azure.core fornecem saída de log usando a biblioteca de log padrão do Python.

O processo geral para trabalhar com o registro em log é o seguinte:

  1. Adquira o objeto de log para a biblioteca desejada e defina o nível de log.
  2. Registre um manipulador para o fluxo de log.
  3. Para incluir informações HTTP, passe um logging_enable=True parâmetro para um construtor de objeto cliente, um construtor de objeto de credencial ou para um método específico.

Os detalhes são fornecidos nas seções restantes deste artigo.

Como regra geral, o melhor recurso para entender o uso de log nas bibliotecas é procurar o código-fonte do SDK em github.com/Azure/azure-sdk-for-python. Recomendamos que você clone esse repositório localmente para que possa pesquisar facilmente detalhes quando necessário, como sugerem as seções a seguir.

Definir níveis de registo

import logging

# ...

# Acquire the logger for a library (azure.mgmt.resource in this example)
logger = logging.getLogger('azure.mgmt.resource')

# Set the desired logging level
logger.setLevel(logging.DEBUG)
  • Este exemplo adquire o logger para a azure.mgmt.resource biblioteca e, em seguida, define o nível de log como logging.DEBUG.
  • Você pode ligar logger.setLevel a qualquer momento para alterar o nível de log para diferentes segmentos de código.

Para definir um nível para uma biblioteca diferente, use o logging.getLogger nome dessa biblioteca na chamada. Por exemplo, a biblioteca azure-eventhubs fornece um logger chamado azure.eventhubs, a biblioteca azure-storage-queue fornece um logger chamado azure.storage.queuee assim por diante. (O código-fonte do SDK usa frequentemente a instrução logging.getLogger(__name__), que adquire um registrador usando o nome do módulo que o contém.)

Você também pode usar namespaces mais gerais. Por exemplo,

import logging

# Set the logging level for all azure-storage-* libraries
logger = logging.getLogger('azure.storage')
logger.setLevel(logging.INFO)

# Set the logging level for all azure-* libraries
logger = logging.getLogger('azure')
logger.setLevel(logging.ERROR)

O azure logger é usado por algumas bibliotecas em vez de um logger específico. Por exemplo, a biblioteca azure-storage-blob usa o azure registrador.

Você pode usar o logger.isEnabledFor método para verificar se um determinado nível de log está habilitado:

print(
    f"Logger enabled for ERROR={logger.isEnabledFor(logging.ERROR)}, "
    f"WARNING={logger.isEnabledFor(logging.WARNING)}, "
    f"INFO={logger.isEnabledFor(logging.INFO)}, "
    f"DEBUG={logger.isEnabledFor(logging.DEBUG)}"
)

Os níveis de log são os mesmos que os níveis padrão da biblioteca de log. A tabela a seguir descreve o uso geral desses níveis de log nas bibliotecas do Azure para Python:

Nível de registo Uso típico
exploração madeireira. ERRO Falhas em que é improvável que o aplicativo se recupere (como falta de memória).
exploração madeireira. AVISO (padrão) Uma função falha ao executar a tarefa pretendida (mas não quando a função pode se recuperar, como tentar novamente uma chamada de API REST). As funções normalmente registram um aviso ao gerar exceções. O nível de aviso ativa automaticamente o nível de erro.
logging.INFO A função funciona normalmente ou uma chamada de serviço é cancelada. Os eventos informativos geralmente incluem solicitações, respostas e cabeçalhos. O nível de informação ativa automaticamente os níveis de erro e aviso.
exploração madeireira. DEPURAR Informações detalhadas que são comumente usadas para solução de problemas e incluem um rastreamento de pilha para exceções. O nível de depuração ativa automaticamente os níveis de informação, aviso e erro. CUIDADO: Se você também definir logging_enable=True, o nível de depuração inclui informações confidenciais, como chaves de conta em cabeçalhos e outras credenciais. Certifique-se de proteger esses logs para evitar comprometer a segurança.
exploração madeireira. NOTSET Desative todos os registros.

Comportamento de nível de log específico da biblioteca

O comportamento exato de registro em log em cada nível depende da biblioteca em questão. Algumas bibliotecas, como azure.eventhub, executam um log extensivo, enquanto outras bibliotecas fazem pouco.

A melhor maneira de examinar o log exato de uma biblioteca é pesquisar os níveis de log no código-fonte do SDK do Azure para Python:

  1. Na pasta do repositório, navegue até a pasta sdk e, em seguida, navegue até a pasta do serviço específico de interesse.

  2. Nessa pasta, procure qualquer uma das seguintes cadeias de caracteres:

    • _LOGGER.error
    • _LOGGER.warning
    • _LOGGER.info
    • _LOGGER.debug

Registrar um manipulador de fluxo de log

Para capturar a saída de log, você deve registrar pelo menos um manipulador de fluxo de log em seu código:

import logging
# Direct logging output to stdout. Without adding a handler,
# no logging output is visible.
handler = logging.StreamHandler(stream=sys.stdout)
logger.addHandler(handler)

Este exemplo registra um manipulador que direciona a saída de log para stdout. Você pode usar outros tipos de manipuladores conforme descrito em logging.handlers na documentação do Python ou usar o método padrão logging.basicConfig .

Habilitar o log HTTP para um objeto ou operação cliente

Por padrão, o registro em log nas bibliotecas do Azure não inclui nenhuma informação HTTP. Para incluir informações HTTP na saída de log (como nível de DEBUG), você deve passar logging_enable=True explicitamente para um cliente ou construtor de objeto de credencial ou para um método específico.

Atenção

O log HTTP pode incluir informações confidenciais, como chaves de conta em cabeçalhos e outras credenciais. Certifique-se de proteger esses logs para evitar comprometer a segurança.

Habilitar o log HTTP para um objeto cliente (nível DEBUG)

from azure.storage.blob import BlobClient
from azure.identity import DefaultAzureCredential

# Enable HTTP logging on the client object when using DEBUG level
# endpoint is the Blob storage URL.
client = BlobClient(endpoint, DefaultAzureCredential(), logging_enable=True)

A habilitação do log HTTP para um objeto cliente habilita o registro em log para todas as operações invocadas por meio desse objeto.

Habilitar o log HTTP para um objeto de credencial (nível DEBUG)

from azure.storage.blob import BlobClient
from azure.identity import DefaultAzureCredential

# Enable HTTP logging on the credential object when using DEBUG level
credential = DefaultAzureCredential(logging_enable=True)

# endpoint is the Blob storage URL.
client = BlobClient(endpoint, credential)

Habilitar o log HTTP para um objeto de credencial habilita o registro em log para todas as operações invocadas por meio desse objeto, mas não para operações em um objeto cliente que não envolvem autenticação.

Habilitar o registro em log para um método individual (nível de DEBUG)

from azure.storage.blob import BlobClient
from azure.identity import DefaultAzureCredential

# endpoint is the Blob storage URL.
client = BlobClient(endpoint, DefaultAzureCredential())

# Enable HTTP logging for only this operation when using DEBUG level
client.create_container("container01", logging_enable=True)

Exemplo de saída de log

O código a seguir é o mostrado em Exemplo: Use uma conta de armazenamento com a adição de habilitar DEBUG e log HTTP:

import logging
import os
import sys
import uuid

from azure.core import exceptions
from azure.identity import DefaultAzureCredential
from azure.storage.blob import BlobClient

logger = logging.getLogger("azure")
logger.setLevel(logging.DEBUG)

# Set the logging level for the azure.storage.blob library
logger = logging.getLogger("azure.storage.blob")
logger.setLevel(logging.DEBUG)

# Direct logging output to stdout. Without adding a handler,
# no logging output is visible.
handler = logging.StreamHandler(stream=sys.stdout)
logger.addHandler(handler)

print(
    f"Logger enabled for ERROR={logger.isEnabledFor(logging.ERROR)}, "
    f"WARNING={logger.isEnabledFor(logging.WARNING)}, "
    f"INFO={logger.isEnabledFor(logging.INFO)}, "
    f"DEBUG={logger.isEnabledFor(logging.DEBUG)}"
)

try:
    credential = DefaultAzureCredential()
    storage_url = os.environ["AZURE_STORAGE_BLOB_URL"]
    unique_str = str(uuid.uuid4())[0:5]

    # Enable logging on the client object
    blob_client = BlobClient(
        storage_url,
        container_name="blob-container-01",
        blob_name=f"sample-blob-{unique_str}.txt",
        credential=credential,
    )

    with open("./sample-source.txt", "rb") as data:
        blob_client.upload_blob(data, logging_body=True, logging_enable=True)

except (
    exceptions.ClientAuthenticationError,
    exceptions.HttpResponseError
) as e:
    print(e.message)

O resultado é o seguinte:

Logger enabled for ERROR=True, WARNING=True, INFO=True, DEBUG=True
Request URL: 'https://pythonazurestorage12345.blob.core.windows.net/blob-container-01/sample-blob-5588e.txt'
Request method: 'PUT'
Request headers:
    'Content-Length': '77'
    'x-ms-blob-type': 'BlockBlob'
    'If-None-Match': '*'
    'x-ms-version': '2023-11-03'
    'Content-Type': 'application/octet-stream'
    'Accept': 'application/xml'
    'User-Agent': 'azsdk-python-storage-blob/12.19.0 Python/3.10.11 (Windows-10-10.0.22631-SP0)'
    'x-ms-date': 'Fri, 19 Jan 2024 19:25:53 GMT'
    'x-ms-client-request-id': '8f7b1b0b-b700-11ee-b391-782b46f5c56b'
    'Authorization': '*****'
Request body:
b"Hello there, Azure Storage. I'm a friendly file ready to be stored in a blob."
Response status: 201
Response headers:
    'Content-Length': '0'
    'Content-MD5': 'SUytm0872jZh+KYqtgjbTA=='
    'Last-Modified': 'Fri, 19 Jan 2024 19:25:54 GMT'
    'ETag': '"0x8DC1924749AE3C3"'
    'Server': 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0'
    'x-ms-request-id': '7ac499fa-601e-006d-3f0d-4bdf28000000'
    'x-ms-client-request-id': '8f7b1b0b-b700-11ee-b391-782b46f5c56b'
    'x-ms-version': '2023-11-03'
    'x-ms-content-crc64': 'rtHLUlztgxc='
    'x-ms-request-server-encrypted': 'true'
    'Date': 'Fri, 19 Jan 2024 19:25:53 GMT'
Response content:
b''

Nota

Se você receber um erro de autorização, verifique se a identidade em que você está executando está atribuída a função "Colaborador de dados de Blob de armazenamento" no contêiner de blob. Para saber mais, consulte Usar armazenamento de blob com autenticação.