Grafana to Elastic stack migration

I wanna migrate from Grafana to Elastic stack .
I found this repository and few articles.
Can I download the binary files directly obs-migrate?(for windows 11 x64)

Hi @Ts_P,

I would recommend cloning the repository first and following the quick start rather than just downloading the migrate script.

Hope that helps!

Hi @Ts_P

I ping the internal team that owns this ... lets see if they come back with something.

Its pretty new.

Hi @Ts_P ,

I'm part of the team working on the Observability Migration Platform. There is no packaged binary today; the tool is a Python CLI, not a standalone installer. Simpler distribution via PyPI/uvx is on our roadmap, but not available yet.

The supported path is cloning the repo and following the Quick Start.

We haven't validated Windows 11 x64 and we are still in technical preview. The CLI itself is plain Python with no deliberate OS-specific logic, so it may work on Windows, but we can't guarantee it yet.

We'll be happy to assist if you run into any complications, please reach out or open a GitHub issue ( Issues · elastic/observability-migration-platform · GitHub ) with your OS, Python version, and the output of obs-migrate doctor, and we'll provide guidance or use the feedback to improve the tool.

Thanks for your interest in the tool, don't hesitate to reach back out if you encounter anything along the way.

thanks a lot @miguel-sanchez I will test it and let you know

@miguel-sanchez

$ ./obs-migrate.exe doctor
obs-migrate doctor
pinned kb-dashboard tool version: 0.4.1
uv on PATH: no
kb-dashboard-cli: available (installed)
kb-dashboard-lint: available (installed)

is the "uv on PATH" missing critical ?

no you can run without uv using standard the python toolchain.

@tommyers-elastic I quickly tested the dashboard against dashboard json from Grafana .
It went well . I even ingested it manually in Kibana.
I saw in the logs these messages.

Is this expected because it is an early version of that tool or because I run it on windows 11.

NOT FEASIBLE (20 panels):
[OpenTelemetry Collector] Spans: BY/WITHOUT clause contains Grafana template variable ($grouping); grouping dimension is unknown at migration time and requires manual redesign
PromQL: sum(${metric:value}(otelcol_receiver_accepted_spans${suffix}{receiver=~"$receiver",job="$job"}[$_ra
[OpenTelemetry Collector] Metric Points: BY/WITHOUT clause contains Grafana template variable ($grouping); grouping dimension is unknown at migration time and requires manual redesign
PromQL: sum(${metric:value}(otelcol_receiver_accepted_metric_points${suffix}{receiver=~"$receiver",job="$job
[OpenTelemetry Collector] Log Records: BY/WITHOUT clause contains Grafana template variable ($grouping); grouping dimension is unknown at migration time and requires manual redesign
PromQL: sum(${metric:value}(otelcol_receiver_accepted_log_records${suffix}{receiver=~"$receiver",job="$job"}
[OpenTelemetry Collector] Spans: BY/WITHOUT clause contains Grafana template variable ($grouping); grouping dimension is unknown at migration time and requires manual redesign
PromQL: sum(${metric:value}(otelcol_processor_accepted_spans${suffix}{processor=~"$processor",job="$job"}[$
[OpenTelemetry Collector] Metric Points: BY/WITHOUT clause contains Grafana template variable ($grouping); grouping dimension is unknown at migration time and requires manual redesign
PromQL: sum(${metric:value}(otelcol_processor_accepted_metric_points${suffix}{processor=~"$processor",job="$
[OpenTelemetry Collector] Log Records: BY/WITHOUT clause contains Grafana template variable ($grouping); grouping dimension is unknown at migration time and requires manual redesign
PromQL: sum(${metric:value}(otelcol_processor_accepted_log_records${suffix}{processor=~"$processor",job="$jo
[OpenTelemetry Collector] Batch Metrics 1: BY/WITHOUT clause contains Grafana template variable ($grouping); grouping dimension is unknown at migration time and requires manual redesign
PromQL: sum(${metric:value}(otelcol_processor_batch_batch_send_size_count{processor=~"$processor",job="$job"
[OpenTelemetry Collector] Batch Metrics 2: BY/WITHOUT clause contains Grafana template variable ($grouping); grouping dimension is unknown at migration time and requires manual redesign
PromQL: sum(${metric:value}(otelcol_processor_batch_batch_size_trigger_send${suffix}{processor=~"$processor"
[OpenTelemetry Collector] Spans: BY/WITHOUT clause contains Grafana template variable ($grouping); grouping dimension is unknown at migration time and requires manual redesign
PromQL: sum(${metric:value}(otelcol_exporter_sent_spans${suffix}{exporter=~"$exporter",job="$job"}[$rate_i
[OpenTelemetry Collector] Metric Points: BY/WITHOUT clause contains Grafana template variable ($grouping); grouping dimension is unknown at migration time and requires manual redesign
PromQL: sum(${metric:value}(otelcol_exporter_sent_metric_points${suffix}{exporter=~"$exporter",job="$job"}[$
[OpenTelemetry Collector] Log Records: BY/WITHOUT clause contains Grafana template variable ($grouping); grouping dimension is unknown at migration time and requires manual redesign
PromQL: sum(${metric:value}(otelcol_exporter_sent_log_records${suffix}{exporter=~"$exporter",job="$job"}[$
[OpenTelemetry Collector] Exporter Queue Size: BY/WITHOUT clause contains Grafana template variable ($grouping); grouping dimension is unknown at migration time and requires manual redesign
PromQL: max(otelcol_exporter_queue_size{exporter=~"$exporter",job="$job"}) by (exporter $grouping)
[OpenTelemetry Collector] Exporter Queue Capacity: BY/WITHOUT clause contains Grafana template variable ($grouping); grouping dimension is unknown at migration time and requires manual redesign
PromQL: min(otelcol_exporter_queue_capacity{exporter=~"$exporter",job="$job"}) by (exporter $grouping)
[OpenTelemetry Collector] Exporter Queue Usage: BY/WITHOUT clause contains Grafana template variable ($grouping); grouping dimension is unknown at migration time and requires manual redesign
PromQL: max(
otelcol_exporter_queue_size{
exporter=~"$exporter", job="$job"
}
) by (expo
[OpenTelemetry Collector] Total RSS Memory: BY/WITHOUT clause contains Grafana template variable ($grouping); grouping dimension is unknown at migration time and requires manual redesign
PromQL: max(otelcol_process_memory_rss{job="$job"}) by (job $grouping)
[OpenTelemetry Collector] Total Runtime Sys Memory: BY/WITHOUT clause contains Grafana template variable ($grouping); grouping dimension is unknown at migration time and requires manual redesign
PromQL: max(otelcol_process_runtime_total_sys_memory_bytes{job="$job"}) by (job $grouping)
[OpenTelemetry Collector] Total Runtime Heap Memory: BY/WITHOUT clause contains Grafana template variable ($grouping); grouping dimension is unknown at migration time and requires manual redesign
PromQL: max(otelcol_process_runtime_heap_alloc_bytes{job="$job"}) by (job $grouping)
[OpenTelemetry Collector] CPU Usage: BY/WITHOUT clause contains Grafana template variable ($grouping); grouping dimension is unknown at migration time and requires manual redesign
PromQL: max(rate(otelcol_process_cpu_seconds${suffix}{job="$job"}[$__rate_interval])*100) by (job $grouping)
[OpenTelemetry Collector] RPC server responses by GRPC status code (receivers): AST parse failed (unknown function with name 'label_metric'), using regex fragment parser
PromQL: sum by(rpc_grpc_status_code) (${metric:value}(otelcol_rpc_server_responses_per_rpc_count{}[$__rate_i
[OpenTelemetry Collector] RPC client responses by GRPC status code (exporters): AST parse failed (unknown function with name 'label_metric'), using regex fragment parser
PromQL: sum by(rpc_grpc_status_code) (${metric:value}(otelcol_rpc_client_responses_per_rpc_count{}[$__rate_i

thanks for the detail! some of this is expected (i.e. we don't currently support it) e.g. late binding variables. but some are potentially bugs e.g. [OpenTelemetry Collector] RPC client responses by GRPC status code (exporters): AST parse failed (unknown function with name 'label_metric'), using regex fragment parser

we'll look into it !

awesome thanks a lot.
I have tested with another sample dashboard json from grafana.

NOT FEASIBLE (4 panels):
[Kubewarden] 90th percentile evaluation latency: histogram_quantile target field type could not be determined; cannot safely translate to ES|QL PERCENTILE() (verify the base metric is a histogram or exponential_histogram field on the target index)
PromQL: histogram_quantile(.90, sum(rate(kubewarden_policy_evaluation_latency_milliseconds_bucket[$__interva
[Kubewarden] policy accepted request percentage: PromQL arithmetic with divergent filters/groupings cannot be translated safely yet
PromQL: sum(kubewarden_policy_evaluations_total{accepted="true",mutated="false", policy_name="$policy_name"
[Kubewarden] policy request rejection percentage: PromQL arithmetic with divergent filters/groupings cannot be translated safely yet
PromQL: sum(kubewarden_policy_evaluations_total{accepted="false", policy_name="$policy_name" })*100/sum(kube
[Kubewarden] policy mutation request percentage: PromQL arithmetic with divergent filters/groupings cannot be translated safely yet
PromQL: sum(kubewarden_policy_evaluations_total{mutated="true", policy_name="$policy_name" })*100/sum(kubewa