Pular para o conteúdo principal

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

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>.cloud.databricks.com
  • endpoint do servidor: <workspace-id>.zerobus.<region>.cloud.databricks.com

Por exemplo:

  • URL do espaço de trabalho: https://dbc-a1b2c3d4-e5f6.cloud.databricks.com
  • endpoint do servidor: 1234567890123456.zerobus.us-west-2.cloud.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' = 'supported', -- optional
'delta.feature.variantType' = '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' = 'supported', -- optional
'delta.feature.variantType' = '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' = 'supported', -- optional
'delta.feature.variantType' = '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 usam a instrumentação zero-code do OpenTelemetry para coletar e encaminhar automaticamente rastreamentos, logs e métricas para o Zerobus Ingest sem nenhuma alteração de código em seu aplicativo. Você também pode usar outros exportadores compatíveis com OTLP que ofereçam suporte a 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.
  • Content-Type (Somente HTTP/Protobuf): application/x-protobuf ou application/proto. A maioria dos exportadores OTLP define isso automaticamente.

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

my-workspace.cloud.databricks.com

WORKSPACE_ID

1234567890123456

REGION

us-west-2

CATALOG

my_catalog

SCHEMA

my_schema

TABLE_PREFIX

my_prefix

Variável

Exemplo

DATABRICKS_CLIENT_ID

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

DATABRICKS_CLIENT_SECRET

dose1234...

WORKSPACE_URL

my-workspace.cloud.databricks.com

WORKSPACE_ID

1234567890123456

REGION

us-west-2

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}.cloud.databricks.com:443" \
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT="https://${WORKSPACE_ID}.zerobus.${REGION}.cloud.databricks.com:443" \
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT="https://${WORKSPACE_ID}.zerobus.${REGION}.cloud.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}.cloud.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}.cloud.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}.cloud.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

Recursos adicionais​