Configurar o log nas bibliotecas do Azure para Python

As bibliotecas do Azure para Python baseadas na página azure.core fornecem saída de log usando a biblioteca padrão de log 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 registros em log.
  2. Registre um manipulador para o fluxo de log.
  3. Para incluir informações HTTP, passe um parâmetro logging_enable=True para um construtor de objeto de cliente, um construtor de objeto de credencial ou 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 do log nas bibliotecas é procurar o código-fonte do SDK em github.com/Azure/azure-sdk-for-python. Incentivamos você a clonar esse repositório localmente para que possa pesquisar com facilidade os detalhes quando necessário, conforme sugerido nas seções a seguir.

Definir os níveis de registros em log

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 agente para a biblioteca azure.mgmt.resource e define o nível de registros em log como logging.DEBUG.
  • Você pode chamar logger.setLevel a qualquer momento para alterar o nível de registros em log de diferentes segmentos do código.

Para definir um nível para outra biblioteca, use o nome da biblioteca na chamada logging.getLogger. Por exemplo, a biblioteca azure-eventhubs fornece um agente chamado azure.eventhubs, a biblioteca azure-storage-queue fornece um agente chamado azure.storage.queue etc. (Com frequência, o código-fonte do SDK usa a instrução logging.getLogger(__name__), que adquire um agente usando o nome do módulo que o contém.)

Use também 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 agente azure é usado por algumas bibliotecas em vez de um agente específico. Por exemplo, a biblioteca azure-storage-blob usa o agente azure.

Use o método logger.isEnabledFor para verificar se um nível de registros em log específico 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 registros em log são os mesmos que os níveis padrão da biblioteca de log. A seguinte tabela descreve o uso geral desses níveis de registros em log nas bibliotecas do Azure para Python:

Nível de log Uso típico
logging.ERROR Falhas em que é improvável que o aplicativo seja recuperado (como memória insuficiente).
logging.WARNING (padrão) Uma função não consegue executar a tarefa pretendida (mas não quando a função pode ser recuperada, como a repetição de uma chamada à API REST). Normalmente, as funções registram um aviso em log ao gerar exceções. O nível de aviso habilita automaticamente o nível de erro.
logging.INFO A função opera normalmente ou uma chamada de serviço é cancelada. Os eventos de informações normalmente incluem solicitações, respostas e cabeçalhos. O nível de informação habilita automaticamente os níveis de erro e de aviso.
logging.DEBUG Informações detalhadas que normalmente são usadas para solucionar problemas e incluem um rastreamento de pilha para exceções. O nível de depuração habilita automaticamente os níveis de informação, de aviso e erro. CUIDADO: se você também definir logging_enable=True, o nível de depuração incluirá informações confidenciais, como chaves de conta em cabeçalhos e outras credenciais. Proteja esses logs para evitar comprometer a segurança.
logging.NOTSET Desabilita todo o log.

Comportamento do nível de registros em log específico da biblioteca

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

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

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

  2. Nessa pasta, pesquise 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, registre, pelo menos, um manipulador de fluxo de log no 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 logging.basicConfig padrão.

Habilitar o registro em log HTTP para uma operação ou um objeto de cliente

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

Cuidado

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

Habilitar o registro em log HTTP para um objeto de cliente (nível de 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)

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

Habilitar o registro em log HTTP para um objeto de credencial (nível de 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 registro em 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 de cliente que não envolvem autenticação.

Habilitar o registro em log para um método individual (nível 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)

Saída de log de exemplo

O código abaixo é o mesmo do Exemplo: Usar uma conta de armazenamento, mas ele também mostra como habilitar o registro em log HTTP e DEBUG:

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)

A saída é da seguinte maneira:

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''

Observação

Se ocorrer um erro de autorização, verifique se a identidade sob a qual você está executando foi atribuída à função “Colaborador de dados de blob de armazenamento” no contêiner de blob. Para saber mais, consulte Usar o armazenamento de blobs do código do aplicativo (guia Sem senha).