Elasticsearch MigrationClickHouse Workshops

Guía paso a paso de HyperDX

Configura fuentes de ClickStack, busca telemetría en tiempo real y recrea los dashboards de Kibana con AI Assistant.

HyperDX es la interfaz de observabilidad integrada en ClickStack e incluida en cada servicio de ClickHouse Cloud. Esta guía cubre cuatro tareas:

  1. Iniciar ClickStack desde el console de Cloud.
  2. Crear tres fuentes de datos, para trazas, logs y métricas OTEL, apuntando a la base otel rellenada en el Paso 2.
  3. Buscar logs en tiempo real en Search para confirmar el flujo.
  4. Crear un gráfico con el asistente de IA sin escribir SQL.

Requisitos previos: El Paso 4 de README.md pasó sin errores; otel.otel_logs_v2, otel.otel_traces y otel.otel_metrics_* reciben datos, confirmado mediante bash scripts/validate_migration.sh.


Paso A — Iniciar ClickStack

  1. Entra en clickhouse.cloud y abre el servicio aprovisionado en el Paso 1 del README.
  2. En la barra lateral izquierda del console SQL, baja hasta el final. Haz clic en el icono ↗ junto a ClickStack (Beta).
  3. ClickStack se abre en otra pestaña y autentica mediante SSO de Cloud.

Iniciar ClickStack desde la barra lateral del console de Cloud

Qué debes ver primero: la base otel en el selector, con las 11 tablas, 3 vistas materializadas y 2 diccionarios del Paso 2: otel_logs, otel_logs_v2, otel_traces, otel_metrics_* (5 tablas), geoip_data + geoip_country/geoip_city (1 tabla + 2 diccionarios), alert_error_rate*, logs_summary_1min*. Si falta algo, vuelve a ejecutar clickhouse/dictionaries.sql, clickhouse/schema.sql y clickhouse/alert-tables.sql.


Paso B — Crear las tres fuentes de datos

HyperDX consulta ClickHouse mediante «fuentes» con nombre que vinculan una pestaña (Search, Service Map, Chart Explorer, etc.) a una tabla y una convención de columnas. Crea una por tipo de señal.

Abre Team Settings abajo a la izquierda y después Data → Sources. Haz clic en Add source.

B.1 — Fuente de trazas

CampoValor
NameTraces
Source Data TypeTrace
Server ConnectionDefault
Databaseotel
Tableotel_traces
Timestamp ColumnTimestamp
Default SelectTimestamp, ServiceName as service, StatusCode as level, round(Duration / 1e6)
Duration ExpressionDuration
Duration PrecisionNanosecond
Trace Id / Span Id / Parent Span Id ExpressionTraceId / SpanId / ParentSpanId
Span Name / Span Kind ExpressionSpanName / SpanKind
Status Code / Status Message ExpressionStatusCode / StatusMessage

Configuración de la fuente de trazas en Team Settings

Haz clic en Save Source. Debe aparecer el resumen Trace, Default, otel.otel_traces.

B.2 — Fuente de logs

Haz clic de nuevo en Add source y configura:

CampoValor
Namelog
Source Data TypeLog
Server ConnectionDefault
Databaseotel
Tableotel_logs_v2
Timestamp ColumnTimestampTime
Default SelectTimestamp, ServiceName as service, SeverityText as level, Body

¿Por qué TimestampTime y no Timestamp? Timestamp es DateTime64(9) (nanosegundos). El selector temporal y los buckets de HyperDX usan precisión DateTime; la columna materializada TimestampTime evita conversiones implícitas en cada consulta.

Configuración de logs con otel_logs_v2 y TimestampTime

B.3 — Fuente de métricas OTEL

Haz clic en Add source y configura:

CampoValor
Nameotel_metrics
Source Data TypeOTEL Metrics
Server ConnectionDefault
Databaseotel
Gauge Tableotel_metrics_gauge
Histogram Tableotel_metrics_histogram
Sum Tableotel_metrics_sum
Summary Tableotel_metrics_summary
Exponential Histogram Tableotel_metrics_exponentialhistogram
Correlated Log Sourcelog

La fuente abarca las cinco tablas porque OTel representa cada tipo con formas distintas. HyperDX elige la tabla según la métrica. Correlated Log Source = log permite saltar de un gráfico a los logs relacionados.

Fuente OTEL Metrics con las cinco tablas

Al guardar, Sources debe mostrar Traces, log y otel_metrics, una entrada por fuente.


Paso C — Buscar logs en tiempo real

Haz clic en Search y selecciona la fuente log.

Debes ver:

  • Un histograma de recuentos (elige "Last 15 minutes" o "Last 1 hour")
  • Una tabla con Timestamp, service, level, body
  • Una barra de facetas con campos como ServiceName y SeverityText

Flujo de logs con histograma, tabla y facetas

Prueba lo siguiente:

  • Filtrar por servicio: pulsa inventory-service en la faceta ServiceName; la tabla se filtra en una fracción de segundo.
  • Buscar texto: escribe error. El índice de salto text(tokenizer='sparseGrams') de Body en schema.sql lo acelera frente a una exploración completa.
  • Inspeccionar una fila: ábrela; cada clave de LogAttributes se convierte en filtro.

Intervalo temporal: start_at: end hace que las líneas anteriores al Paso 3b no estén en otel_logs_v2. Si "Last 24 hours" está vacío al principio, es normal: los datos comienzan con el collector.


Paso D — Crear un gráfico con el asistente de IA

AI Assistant de HyperDX (etiquetado Experimental) traduce lenguaje natural a gráficos.

  1. Haz clic en Chart Explorer.

  2. Activa AI Assistant [A].

  3. Con log seleccionado, escribe por ejemplo:

    Error count by services for past 2 hours

  4. Pulsa Enter. El asistente rellena tipo (Line/Bar), fuente (log), agregación (Count of Events) y cláusula Where (SeverityText = 'ERROR').

  5. Ajusta intervalo o tipo con (Line/Bar, Table, Number, Pie, Search, Markdown).

AI Assistant traduciendo lenguaje natural a un gráfico

Guarda mediante Chart Name y el icono; aparecerá en Saved Searches / Dashboards.

Biblioteca de prompts — recrear todos los paneles de Kibana de la Parte 1

Los seis dashboards contienen 30 paneles. Las tablas ofrecen un prompt por panel:

  • Fuente: selecciónala antes (log para otel_logs_v2, Traces para otel_traces, otel_metrics para métricas).
  • Gráfico: pestaña del tipo de gráfico; consulta la leyenda.
  • Filtro: muchos paneles estaban limitados implícitamente por flujo. En ClickHouse se expresa con Where; si no se detecta, cambia al modo SQL y añade el Where sugerido.
  • Alternativa de campo: si queda vacío, edita Where / agregación con la Pista de campo.

Tipos de gráficos de HyperDX — leyenda

Chart Explorer ofrece (Line/Bar, Table, Number, Pie, Search, Markdown):

PestañaQué muestraSustituye en KibanaCuándo usarla
Line/BarGráfico 2D de líneas, áreas o barras, con tiempo en X al agrupar por fecha. La forma se elige dentro de la pestaña.line, area, vertical_bar, horizontal_barSeries, barras «top N» o áreas apiladas. Todos los paneles salvo 5 pizzas y 4 números se mapean aquí.
TableFilas ordenables; admite groupBy + varias agregaciones (count, avg, quantile, etc.).data_table, vista de tabla lensCifras exactas en listas, no codificación visual.
NumberUna cifra grande, normalmente una agregación (count, sum, avg, quantile).metric, goalKPI de una estadística.
PieRosca/pizza con proporciones.pieDistribuciones donde importa la proporción.
SearchPanel de búsqueda en tiempo real con facetas.Saved Search incrustadaFlujo de errores recientes junto a series.
MarkdownTexto estático con enlaces y encabezados.MarkdownNarrativa, runbooks y enlaces.

¿Dónde está "Histogram"? HyperDX lo integra en Line/Bar: elige un groupBy numérico o de fecha y forma bar. El histograma de Search del Paso C se renderiza automáticamente y no se crea a mano.

Diferencias de columnas respecto a ECS: request_path → RequestPath o RequestPage; request_type → RequestType; status → StatusCode; geo.country_name → GeoCountry; user_agent_parsed.name → BrowserFamily; service / service.name → ServiceName; level → LogLevel o SeverityText; event.severity → SeverityText; hostname → HostName; event.outcome → derivado de StatusCode; transaction.duration.us (μs) → Duration (nanosegundos, divide por 1000 para μs).

Visión general del tráfico web — 8 paneles

Filtra a logs web añadiendo RequestType != '' en AI Assistant o Where. En Kibana, este dashboard consultaba logs-web_access-lab.

#Panel originalPrompt de AI AssistantFuenteGráficoPista de campo
1Solicitudes en el tiempoRequests over time grouped by minute for the past 1 hour where RequestType is not emptylogLine/Bar (línea)count() por tiempo
2Distribución de estadosDistribution of StatusCode as a pie chart for the past 1 hour where RequestType is not emptylogPiegroupBy(StatusCode)
3Recuento de errores 5xxTotal count of events where StatusCode is greater than or equal to 500 in the past 1 hourlogNumbercountIf(StatusCode >= 500)
4Tiempo medio de respuesta (s)Average of LogAttributes['run_time'] for the past 1 hour where RequestType is not emptylogNumberavg(toFloat64OrZero(LogAttributes['run_time']))
5Rutas principalesTop 10 RequestPage by event count for the past 1 hour where RequestType is not emptylogLine/Bar (barra horizontal)groupBy(RequestPage) desc
6Países principalesTop 10 GeoCountry by event count for the past 1 hour where RequestType is not empty and GeoCountry is not emptylogLine/Bar (barra horizontal)groupBy(GeoCountry)
7Distribución de métodos HTTPDistribution of RequestType (GET, POST, etc.) as a pie chart for the past 1 hourlogPiegroupBy(RequestType)
8Principales user-agentsTop 10 BrowserFamily by event count for the past 1 hour where RequestType is not empty and BrowserFamily is not emptylogLine/Bar (barra horizontal)groupBy(BrowserFamily)

Salud de aplicaciones — 5 paneles

Los logs de aplicación tienen nivel, pero RequestType vacío. Filtro: LogLevel != '' AND RequestType = ''.

#Panel originalPrompt de AI AssistantFuenteGráficoPista de campo
9Volumen por severidadLog volume over time stacked by SeverityText for the past 1 hour where RequestType is empty and SeverityText is not emptylogLine/Bar (área apilada)count() por tiempo, groupBy(SeverityText)
10Distribución de nivelesDistribution of SeverityText as a pie chart for the past 1 hour where RequestType is emptylogPiegroupBy(SeverityText)
11Recuento de erroresCount of error logs for the past 1 hour where SeverityText equals 'ERROR' and RequestType is emptylogNumbercountIf(SeverityText='ERROR')
12Errores por servicioTop 10 ServiceName by error count for the past 1 hour where SeverityText equals 'ERROR' and RequestType is emptylogLine/Bar (barra horizontal)groupBy(ServiceName) de errores
13Errores en el tiempoError log volume over time grouped by minute for the past 1 hour where SeverityText equals 'ERROR' and RequestType is emptylogLine/Bar (línea)count() por tiempo

Visión general de infraestructura — 4 paneles

Las filas syslog tienen ServiceName comenzando por k8s- (regex_parser promueve el hostname a service.name). Filtro: ServiceName LIKE 'k8s-%'.

#Panel originalPrompt de AI AssistantFuenteGráficoPista de campo
14Volumen syslog por hostLog volume over time stacked by ServiceName for the past 1 hour where ServiceName starts with k8s-logLine/Bar (área apilada)ServiceName es el host
15Procesos principalesTop 10 LogAttributes['process'] by event count for the past 1 hour where ServiceName starts with k8s-logLine/Bar (barra horizontal)groupBy(LogAttributes['process']); usa SQL si falla la sintaxis Map
16Distribución de severidadDistribution of SeverityText as a pie chart for the past 1 hour where ServiceName starts with k8s-logPiegroupBy(SeverityText)
17Volumen por procesoLog volume over time grouped by minute and stacked by LogAttributes['process'] for the past 1 hour where ServiceName starts with k8s-logLine/Bar (área apilada)misma salvedad Map que nº 15

OTel Demo — Trazas APM — 6 paneles

Las trazas llegan a otel.otel_traces. Cambia la fuente a Traces.

#Panel originalPrompt de AI AssistantFuenteGráficoPista de campo
18Volumen de trazas APMTrace span volume over time grouped by minute for the past 1 hourTracesLine/Bar (línea)count() por tiempo
19Distribución de resultadosPie chart of trace outcome (StatusCode = 0 or empty as success, otherwise failure) for the past 1 hourTracesPieSQL: if(StatusCode IN ('','STATUS_CODE_OK','STATUS_CODE_UNSET'),'success','failure') como grupo
20Estados HTTPDistribution of SpanAttributes['http.response.status_code'] as a pie chart for the past 1 hourTracesPieSolo spans HTTP; añade Where SpanAttributes['http.response.status_code'] != ''
21Lenguajes de serviciosPie chart of ResourceAttributes['telemetry.sdk.language'] for the past 1 hourTracesPieEl campo es telemetry.sdk.language, no service.language.name de ECS
22Servicios por spansTop 10 ServiceName by span count for the past 1 hourTracesLine/Bar (barra horizontal)groupBy(ServiceName)
23Nombres de transaccionesTop 10 SpanName by event count for the past 1 hour where SpanKind equals 'SPAN_KIND_SERVER' or SpanKind equals 'Server'TracesLine/Bar (barra horizontal)groupBy(SpanName) filtrado a spans de servidor («transacciones» de Kibana)

OTel Demo — Latencia — 4 paneles

#Panel originalPrompt de AI AssistantFuenteGráficoPista de campo
24Duración media en el tiempoAverage Duration in milliseconds over time grouped by minute for the past 1 hour where SpanKind is 'SPAN_KIND_SERVER'TracesLine/Bar (línea)avg(Duration / 1e6) para ms; Kibana usaba μs, usa 1e3
25Duración media por servicioTop 10 ServiceName by average Duration in milliseconds for the past 1 hour where SpanKind is 'SPAN_KIND_SERVER'TracesLine/Bar (barra horizontal)avg(Duration / 1e6) por ServiceName
26Transacciones fallidas por servicioTop 10 ServiceName by count of spans where StatusCode equals 'STATUS_CODE_ERROR' for the past 1 hourTracesLine/Bar (barra horizontal)fallo: StatusCode = 'STATUS_CODE_ERROR'
27Fallos en el tiempoCount of spans over time grouped by minute where StatusCode equals 'STATUS_CODE_ERROR' for the past 1 hourTracesLine/Bar (línea)mismo filtro que nº 26

OTel Demo — Logs — 3 paneles

Los logs de servicios OTel Demo llegan a otel.otel_logs_v2; no tienen RequestType ni LogLevel. Distínguelos con ServiceName NOT LIKE 'k8s-%' AND RequestType = ''.

#Panel originalPrompt de AI AssistantFuenteGráficoPista de campo
28Volumen OTel por servicioLog volume over time stacked by ServiceName for the past 1 hour where ServiceName not like 'k8s-%' and RequestType is emptylogLine/Bar (área apilada)count() por tiempo, groupBy(ServiceName)
29Servicios por volumenTop 10 ServiceName by log count for the past 1 hour where ServiceName not like 'k8s-%' and RequestType is emptylogLine/Bar (barra horizontal)groupBy(ServiceName)
30Logs por lenguajePie chart of ResourceAttributes['telemetry.sdk.language'] for the past 1 hour where ServiceName not like 'k8s-%' and RequestType is emptylogPieIgual que nº 21: telemetry.sdk.language, no service.language.name

Consejos cuando AI Assistant se equivoca

  1. Cambia a SQL en Where. Puedes editar cualquier campo; el selector Schema muestra columnas y tipos.
  2. Fija el intervalo. Respeta "for the past N hours / today / yesterday", pero si se omite usa el selector del gráfico.
  3. Columnas Map (LogAttributes, ResourceAttributes, SpanAttributes) suelen fallar. Si genera WHERE process = 'kernel' en lugar de WHERE LogAttributes['process'] = 'kernel', corrígelo en SQL.
  4. Guarda la versión funcional con Chart Name y colócala en un dashboard de HyperDX.

Siguientes pasos

  • Service Map (beta): visualiza las llamadas de OTel Demo desde otel_traces; basta la fuente Traces.
  • Alerts: define alertas en búsquedas o gráficos. Se usan en el Paso 8; consulta README.md § Paso 8 Opción A para web-5xx-errors y heartbeat.
  • Notebooks (preview): combina gráficos, consultas y Markdown.

Al terminar, vuelve al Paso 6 de README.md y verifica TTL.


Solución de problemas

Sources queda vacío después de guardar. HyperDX guarda definiciones por sesión. Fuerza la recarga (Cmd-Shift-R / Ctrl-Shift-R). Si sigue vacío, comprueba Team Settings → Data → Server Connection: debe ser Default y el mismo servicio CH Cloud.

Search no muestra filas, pero validate_migration.sh informa miles.

  • Comprueba el intervalo, predeterminado "Last 15 minutes"; prueba "Last 24 hours".
  • Default Select debe usar TimestampTime, no Timestamp. Síntoma: histograma visible y tabla con "no rows".
  • Database debe ser otel, no default.

AI Assistant devuelve "I couldn't translate that." El asistente se limita al esquema seleccionado:

  • Preguntas de trazas ("p95 latency") necesitan Traces, no log.
  • Sé explícito: count by ServiceName funciona mejor que count by service.

En esta página

ES