Pular para o conteúdo principal

Configure os clientes OpenTelemetry (OTLP) para enviar dados ao Unity Catalog

info

Beta

Este recurso está em versão Beta.

O Zerobus Ingest inclui um endpoint do protocolo Open Telemetry (OTLP) . Você pode enviar rastreamentos, logs e métricas diretamente para as tabelas Delta Unity Catalog usando os SDKs e coletores padrão do OpenTelemetry, sem bibliotecas personalizadas. Esta página aborda a recuperação do seu endpoint, a criação de tabelas de destino, a configuração de uma entidade de serviço e o envio dos seus primeiros dados de telemetria.

Obtenha o seu endpoint de ingestão do Zerobus e o URL do seu espaço de trabalho.

A URL do endpoint segue este padrão:

  • URL do espaço de trabalho: https://<databricks-instance>.gcp.databricks.com
  • endpoint do servidor: <workspace-id>.zerobus.<region>.gcp.databricks.com

Por exemplo:

  • URL do espaço de trabalho: https://1234567890123456.0.gcp.databricks.com
  • endpoint do servidor: 1234567890123456.zerobus.us-central1.gcp.databricks.com

Para obter mais detalhes sobre como encontrar o ID, URL e região do seu workspace , consulte Obter o URL do seu workspace e endpointde ingestão do Zerobus.

Crie tabelas de destino no Unity Catalog

Você deve criar as tabelas Delta de destino antes de enviar os dados. Cada tipo de sinal (rastreamentos, logs, números) requer sua própria tabela com um esquema específico.

Pré-requisitos:

Para preparar suas mesas:

  1. Substitua <catalog>.<schema>.<prefix> pelo seu catálogo, esquema e prefixo do nome da tabela desejada.
  2. Substitua <service-principal-uuid> pelo ID do aplicativo (UUID) da sua entidade de serviço. Para encontrá-lo, acesse a tab Configurações da entidade de serviço em seu workspace Databricks .
  3. execução do script no Databricks SQL.

Tabela de intervalos

A tabela spans armazena dados de rastreamento distribuído, incluindo tempo, status e atributos para cada span.

SQL
CREATE TABLE <catalog>.<schema>.<prefix>_otel_spans (
record_id STRING,
time TIMESTAMP,
date DATE,
service_name STRING,
trace_id STRING,
span_id STRING,
trace_state STRING,
parent_span_id STRING,
flags INT,
name STRING,
kind STRING,
start_time_unix_nano LONG,
end_time_unix_nano LONG,
attributes VARIANT,
dropped_attributes_count INT,
events ARRAY<STRUCT<
time_unix_nano: LONG,
name: STRING,
attributes: VARIANT,
dropped_attributes_count: INT
>>,
dropped_events_count INT,
links ARRAY<STRUCT<
trace_id: STRING,
span_id: STRING,
trace_state: STRING,
attributes: VARIANT,
dropped_attributes_count: INT,
flags: INT
>>,
dropped_links_count INT,
status STRUCT<
message: STRING,
code: STRING
>,
resource STRUCT<
attributes: VARIANT,
dropped_attributes_count: INT
>,
resource_schema_url STRING,
instrumentation_scope STRUCT<
name: STRING,
version: STRING,
attributes: VARIANT,
dropped_attributes_count: INT
>,
span_schema_url STRING
) USING DELTA
CLUSTER BY (time, service_name, trace_id)
TBLPROPERTIES (
'otel.schemaVersion' = 'v2',
'delta.checkpointPolicy' = 'classic',
'delta.enableVariantShredding' = 'true', -- optional
'delta.feature.variantShredding-preview' = 'supported', -- optional
'delta.feature.variantType-preview' = 'supported' -- optional
);

Tabela de logs

A tabela de logs armazena registros de log estruturados, incluindo atributos de gravidade, corpo e recurso.

SQL
CREATE TABLE <catalog>.<schema>.<prefix>_otel_logs (
record_id STRING,
time TIMESTAMP,
date DATE,
service_name STRING,
event_name STRING,
trace_id STRING,
span_id STRING,
time_unix_nano LONG,
observed_time_unix_nano LONG,
severity_number STRING,
severity_text STRING,
body VARIANT,
attributes VARIANT,
dropped_attributes_count INT,
flags INT,
resource STRUCT<
attributes: VARIANT,
dropped_attributes_count: INT
>,
resource_schema_url STRING,
instrumentation_scope STRUCT<
name: STRING,
version: STRING,
attributes: VARIANT,
dropped_attributes_count: INT
>,
log_schema_url STRING
) USING DELTA
CLUSTER BY (time, service_name)
TBLPROPERTIES (
'otel.schemaVersion' = 'v2',
'delta.checkpointPolicy' = 'classic',
'delta.enableVariantShredding' = 'true', -- optional
'delta.feature.variantShredding-preview' = 'supported', -- optional
'delta.feature.variantType-preview' = 'supported' -- optional
);

Tabela de métricas

A tabela métricas armazena medições de gauge, soma e histograma, juntamente com seus atributos associados de escopo de recurso e instrumentação.

SQL
CREATE TABLE <catalog>.<schema>.<prefix>_otel_metrics (
record_id STRING,
time TIMESTAMP,
date DATE,
service_name STRING,
start_time_unix_nano LONG,
time_unix_nano LONG,
name STRING,
description STRING,
unit STRING,
metric_type STRING,
gauge STRUCT<
value: DOUBLE,
exemplars: ARRAY<STRUCT<
time_unix_nano: LONG,
value: DOUBLE,
span_id: STRING,
trace_id: STRING,
filtered_attributes: VARIANT
>>,
attributes: VARIANT,
flags: INT
>,
sum STRUCT<
value: DOUBLE,
exemplars: ARRAY<STRUCT<
time_unix_nano: LONG,
value: DOUBLE,
span_id: STRING,
trace_id: STRING,
filtered_attributes: VARIANT
>>,
attributes: VARIANT,
flags: INT,
aggregation_temporality: STRING,
is_monotonic: BOOLEAN
>,
histogram STRUCT<
count: LONG,
sum: DOUBLE,
bucket_counts: ARRAY<LONG>,
explicit_bounds: ARRAY<DOUBLE>,
exemplars: ARRAY<STRUCT<
time_unix_nano: LONG,
value: DOUBLE,
span_id: STRING,
trace_id: STRING,
filtered_attributes: VARIANT
>>,
attributes: VARIANT,
flags: INT,
min: DOUBLE,
max: DOUBLE,
aggregation_temporality: STRING
>,
exponential_histogram STRUCT<
attributes: VARIANT,
count: LONG,
sum: DOUBLE,
scale: INT,
zero_count: LONG,
positive_bucket: STRUCT<
offset: INT,
bucket_counts: ARRAY<LONG>
>,
negative_bucket: STRUCT<
offset: INT,
bucket_counts: ARRAY<LONG>
>,
flags: INT,
exemplars: ARRAY<STRUCT<
time_unix_nano: LONG,
value: DOUBLE,
span_id: STRING,
trace_id: STRING,
filtered_attributes: VARIANT
>>,
min: DOUBLE,
max: DOUBLE,
zero_threshold: DOUBLE,
aggregation_temporality: STRING
>,
summary STRUCT<
count: LONG,
sum: DOUBLE,
quantile_values: ARRAY<STRUCT<
quantile: DOUBLE,
value: DOUBLE
>>,
attributes: VARIANT,
flags: INT
>,
metadata VARIANT,
resource STRUCT<
attributes: VARIANT,
dropped_attributes_count: INT
>,
resource_schema_url STRING,
instrumentation_scope STRUCT<
name: STRING,
version: STRING,
attributes: VARIANT,
dropped_attributes_count: INT
>,
metric_schema_url STRING
) USING DELTA
CLUSTER BY (time, service_name)
TBLPROPERTIES (
'otel.schemaVersion' = 'v2',
'delta.checkpointPolicy' = 'classic',
'delta.enableVariantShredding' = 'true', -- optional
'delta.feature.variantShredding-preview' = 'supported', -- optional
'delta.feature.variantType-preview' = 'supported' -- optional
);

Crie uma entidade de serviço e conceda permissões.

Configure uma entidade de serviço com credenciais OAuth e conceda a ela acesso às suas tabelas. Para obter mais informações sobre a criação de uma entidade de serviço, consulte Autorizar o acesso da entidade de serviço ao Databricks com OAuth.

Conceda à entidade de serviço acesso ao catálogo, ao esquema e a cada tabela. Conceder ALL PRIVILEGES não é suficiente. Você deve conceder explicitamente MODIFY e SELECT em cada tabela.

SQL
GRANT USE CATALOG ON CATALOG <catalog> TO `<service-principal-uuid>`;
GRANT USE SCHEMA ON SCHEMA <catalog>.<schema> TO `<service-principal-uuid>`;
GRANT MODIFY, SELECT ON TABLE <catalog>.<schema>.<prefix>_otel_spans TO `<service-principal-uuid>`;
GRANT MODIFY, SELECT ON TABLE <catalog>.<schema>.<prefix>_otel_logs TO `<service-principal-uuid>`;
GRANT MODIFY, SELECT ON TABLE <catalog>.<schema>.<prefix>_otel_metrics TO `<service-principal-uuid>`;

Configure seu exportador

Os exemplos a seguir utilizam a instrumentação sem código do OpenTelemetry para coletar e encaminhar automaticamente rastreamentos, logs e métricas para o Zerobus Ingest sem qualquer alteração de código em seu aplicativo. Você também pode usar outros exportadores compatíveis com OTLP que suportam gRPC e cabeçalhos de metadados personalizados.

Cabeçalhos obrigatórios

Todas as solicitações OTLP devem incluir os seguintes cabeçalhos de metadados:

  • x-databricks-zerobus-table-name: O nome completo da tabela do Unity Catalog no formato <catalog>.<schema>.<table> . Cada solicitação tem como alvo uma única tabela.
  • Authorization: Tokens portadores OAuth gerados a partir das credenciais da entidade de serviço.

Para gerar tokens de portador estático a partir de suas credenciais de entidade de serviço, consulte Autorizar o acesso da entidade de serviço ao Databricks com OAuth. Os tokens estáticos expiram após uma hora. Para aplicações de longa duração, consulte o OpenTelemetry Collector com refreshautomática de tokens.

Configuração variável

Defina essas variáveis antes de executar qualquer um dos exemplos:

Variável

Exemplo

DATABRICKS_CLIENT_ID

abc123-... (ID do aplicativo da entidade de serviço)

DATABRICKS_CLIENT_SECRET

dose1234...

WORKSPACE_URL

1234567890123456.0.gcp.databricks.com

WORKSPACE_ID

1234567890123456

REGION

us-central1

CATALOG

my_catalog

SCHEMA

my_schema

TABLE_PREFIX

my_prefix

Você pode definir essas variáveis como variável de ambiente usando Bash. Por exemplo:

Bash
export DATABRICKS_CLIENT_ID="<your-client-id>"
export DATABRICKS_CLIENT_SECRET="<your-client-secret>"

Comece rapidamente com tokens estáticos

O exemplo a seguir usa tokens de portador estáticos para cada tipo de sinal (rastreamentos, logs, métricas). Antes de executar este exemplo, gere tokens a partir das credenciais da sua entidade de serviço. Consulte Autorizar o acesso da entidade de serviço ao Databricks com OAuth.

Utilize essa abordagem para pipelines de curta duração ou ad hoc, onde o gerenciamento refresh de tokens não seja uma preocupação. Os tokens OAuth estáticos expiram após uma hora e não são adequados para processos de longa duração. Para cargas de trabalho de produção, utilize o coletor OpenTelemetry com refreshautomática de tokens .

Você deve gerar tokens separados para cada tipo de sinal. Na carga útil authorization_details , substitua $TABLE_NAME pelo nome completo da tabela para cada sinal, como ${TABLE_PREFIX}_otel_spans, ${TABLE_PREFIX}_otel_logs e ${TABLE_PREFIX}_otel_metrics.

Bash
authorization_details=$(cat <<EOF
[{
"type": "unity_catalog_privileges",
"privileges": ["USE CATALOG"],
"object_type": "CATALOG",
"object_full_path": "$CATALOG"
},
{
"type": "unity_catalog_privileges",
"privileges": ["USE SCHEMA"],
"object_type": "SCHEMA",
"object_full_path": "$CATALOG.$SCHEMA"
},
{
"type": "unity_catalog_privileges",
"privileges": ["SELECT", "MODIFY"],
"object_type": "TABLE",
"object_full_path": "$CATALOG.$SCHEMA.$TABLE_NAME"
}]
EOF
)

curl -X POST \
-u "$DATABRICKS_CLIENT_ID:$DATABRICKS_CLIENT_SECRET" \
-d "grant_type=client_credentials" \
-d "scope=all-apis" \
-d "resource=api://databricks/workspaces/$WORKSPACE_ID/zerobusDirectWriteApi" \
--data-urlencode "authorization_details=$authorization_details" \
"https://$WORKSPACE_URL/oidc/v1/token"

Salve os três access tokens retornados como TOKEN_SPANS, TOKEN_LOGS e TOKEN_METRICS antes de instalar o pacote de instrumentação automática. Em seguida, execute sua aplicação:

Bash
OTEL_SERVICE_NAME="my-service" \
OTEL_EXPORTER_OTLP_PROTOCOL="grpc" \
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="https://${WORKSPACE_ID}.zerobus.${REGION}.gcp.databricks.com:443" \
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT="https://${WORKSPACE_ID}.zerobus.${REGION}.gcp.databricks.com:443" \
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT="https://${WORKSPACE_ID}.zerobus.${REGION}.gcp.databricks.com:443" \
OTEL_EXPORTER_OTLP_TRACES_HEADERS="authorization=Bearer ${TOKEN_SPANS},x-databricks-zerobus-table-name=${CATALOG}.${SCHEMA}.${TABLE_PREFIX}_otel_spans" \
OTEL_EXPORTER_OTLP_LOGS_HEADERS="authorization=Bearer ${TOKEN_LOGS},x-databricks-zerobus-table-name=${CATALOG}.${SCHEMA}.${TABLE_PREFIX}_otel_logs" \
OTEL_EXPORTER_OTLP_METRICS_HEADERS="authorization=Bearer ${TOKEN_METRICS},x-databricks-zerobus-table-name=${CATALOG}.${SCHEMA}.${TABLE_PREFIX}_otel_metrics" \
OTEL_TRACES_EXPORTER="otlp" \
OTEL_METRICS_EXPORTER="otlp" \
OTEL_LOGS_EXPORTER="otlp" \
opentelemetry-instrument python my_app.py

Coletor OpenTelemetry com refreshautomática de tokens.

Os tokens OAuth do Databricks expiram após uma hora. Em vez de gerenciar refresh de tokens no código do seu aplicativo, implemente um coletor OpenTelemetry como um proxy entre seu aplicativo e o Zerobus Ingest. O Collector usa o oauth2clientauthextension para cunhar tokens a partir das credenciais da sua entidade de serviço na startup e refresh los automaticamente antes do vencimento.

Essa é a abordagem recomendada para cargas de trabalho de longa duração e em produção. Diferentemente da abordagem com tokens estáticos, o Collector lida com a aquisição e refresh de tokens OAuth automaticamente — seu código de aplicação não precisa de alterações.

O Collector fica entre sua aplicação e o Zerobus Ingest. Seu aplicativo envia OTLP simples para o coletor em localhost:4317 sem autenticação. O coletor adiciona os tokens OAuth e o cabeçalho da tabela a cada solicitação e a encaminha para o endpoint de ingestão do Zerobus.

Configuração do coletor

Crie um arquivo collector.yaml para configurar seu coletor:

YAML
extensions:
oauth2client/spans:
client_id: ${env:DATABRICKS_CLIENT_ID}
client_secret: ${env:DATABRICKS_CLIENT_SECRET}
token_url: https://${env:WORKSPACE_URL}/oidc/v1/token
scopes: ['all-apis']
endpoint_params:
resource: 'api://databricks/workspaces/${env:WORKSPACE_ID}/zerobusDirectWriteApi'
authorization_details:
- '[{"type":"unity_catalog_privileges","privileges":["USE CATALOG"],"object_type":"CATALOG","object_full_path":"${env:CATALOG}"},{"type":"unity_catalog_privileges","privileges":["USE SCHEMA"],"object_type":"SCHEMA","object_full_path":"${env:CATALOG}.${env:SCHEMA}"},{"type":"unity_catalog_privileges","privileges":["SELECT","MODIFY"],"object_type":"TABLE","object_full_path":"${env:CATALOG}.${env:SCHEMA}.${env:TABLE_PREFIX}_otel_spans"}]'

oauth2client/logs:
client_id: ${env:DATABRICKS_CLIENT_ID}
client_secret: ${env:DATABRICKS_CLIENT_SECRET}
token_url: https://${env:WORKSPACE_URL}/oidc/v1/token
scopes: ['all-apis']
endpoint_params:
resource: 'api://databricks/workspaces/${env:WORKSPACE_ID}/zerobusDirectWriteApi'
authorization_details:
- '[{"type":"unity_catalog_privileges","privileges":["USE CATALOG"],"object_type":"CATALOG","object_full_path":"${env:CATALOG}"},{"type":"unity_catalog_privileges","privileges":["USE SCHEMA"],"object_type":"SCHEMA","object_full_path":"${env:CATALOG}.${env:SCHEMA}"},{"type":"unity_catalog_privileges","privileges":["SELECT","MODIFY"],"object_type":"TABLE","object_full_path":"${env:CATALOG}.${env:SCHEMA}.${env:TABLE_PREFIX}_otel_logs"}]'

oauth2client/metrics:
client_id: ${env:DATABRICKS_CLIENT_ID}
client_secret: ${env:DATABRICKS_CLIENT_SECRET}
token_url: https://${env:WORKSPACE_URL}/oidc/v1/token
scopes: ['all-apis']
endpoint_params:
resource: 'api://databricks/workspaces/${env:WORKSPACE_ID}/zerobusDirectWriteApi'
authorization_details:
- '[{"type":"unity_catalog_privileges","privileges":["USE CATALOG"],"object_type":"CATALOG","object_full_path":"${env:CATALOG}"},{"type":"unity_catalog_privileges","privileges":["USE SCHEMA"],"object_type":"SCHEMA","object_full_path":"${env:CATALOG}.${env:SCHEMA}"},{"type":"unity_catalog_privileges","privileges":["SELECT","MODIFY"],"object_type":"TABLE","object_full_path":"${env:CATALOG}.${env:SCHEMA}.${env:TABLE_PREFIX}_otel_metrics"}]'

exporters:
otlp/spans:
endpoint: ${env:WORKSPACE_ID}.zerobus.${env:REGION}.gcp.databricks.com:443
auth:
authenticator: oauth2client/spans
headers:
x-databricks-zerobus-table-name: '${env:CATALOG}.${env:SCHEMA}.${env:TABLE_PREFIX}_otel_spans'

otlp/logs:
endpoint: ${env:WORKSPACE_ID}.zerobus.${env:REGION}.gcp.databricks.com:443
auth:
authenticator: oauth2client/logs
headers:
x-databricks-zerobus-table-name: '${env:CATALOG}.${env:SCHEMA}.${env:TABLE_PREFIX}_otel_logs'

otlp/metrics:
endpoint: ${env:WORKSPACE_ID}.zerobus.${env:REGION}.gcp.databricks.com:443
auth:
authenticator: oauth2client/metrics
headers:
x-databricks-zerobus-table-name: '${env:CATALOG}.${env:SCHEMA}.${env:TABLE_PREFIX}_otel_metrics'

receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317

processors:
batch:
timeout: 5s # adjust as needed
send_batch_size: 10 # adjust as needed

service:
extensions: [oauth2client/spans, oauth2client/logs, oauth2client/metrics]
pipelines:
traces:
receivers: [otlp] # adjust as needed
processors: [batch]
exporters: [otlp/spans]
logs:
receivers: [otlp]
processors: [batch]
exporters: [otlp/logs]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [otlp/metrics]

Em seguida, execute o coletor:

Bash
./otelcol-contrib --config collector.yaml

Instrumente sua aplicação

Defina as variáveis necessárias antes de executar este exemplo de código. Em seguida instale o pacote de autoinstrumentação e execute sua aplicação.

Bash
OTEL_SERVICE_NAME=my-service \
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 \
OTEL_EXPORTER_OTLP_PROTOCOL=grpc \
OTEL_TRACES_EXPORTER=otlp \
OTEL_METRICS_EXPORTER=otlp \
OTEL_LOGS_EXPORTER=otlp \
opentelemetry-instrument python my_app.py

Próximos passos