diff --git a/tezt/lib_cloud/cli.ml b/tezt/lib_cloud/cli.ml index c46e107a46677ae52a506f43c88822d7f344e200..74165942776d09a1145c65abb151b768c218590e 100644 --- a/tezt/lib_cloud/cli.ml +++ b/tezt/lib_cloud/cli.ml @@ -105,6 +105,16 @@ let grafana = ~description:"Flag to set whether to run grafana" (((not localhost) || proxy) && os = Os.Cos) +let grafana_legacy_source = + Clap.flag + ~section + ~set_long:"grafana-legacy-source" + ~description: + "Flag to indicate to use grafana legacy 'Prometheus' source name when \ + importing a prometheus snapshot. Newer dashboards should use \ + ${datasource} as source instead of the hardcoded 'Prometheus' name." + false + let alert_handlers = Clap.list_string ~section diff --git a/tezt/lib_cloud/cli.mli b/tezt/lib_cloud/cli.mli index c3a4d1b8e0fb2f08724519f769bcdd56a015c405..7e6509252818fd2a40f0b5d32fc067c64f9e2c89 100644 --- a/tezt/lib_cloud/cli.mli +++ b/tezt/lib_cloud/cli.mli @@ -47,6 +47,10 @@ val os : Types.Os.t (** Flag which indicates whether Grafana should be run or not. *) val grafana : bool +(** Flag which indicates whether Grafana should use legacy data source name or not. + Only used when importing prometheus snapshot. *) +val grafana_legacy_source : bool + (** The alert handlers to be registered by the alert manager. *) val alert_handlers : string list diff --git a/tezt/lib_cloud/env.ml b/tezt/lib_cloud/env.ml index ecd87a6e87e56f153b0b6487e06ad3045317bc28..0158098ef98c43852bf974268e67b09c875338cb 100644 --- a/tezt/lib_cloud/env.ml +++ b/tezt/lib_cloud/env.ml @@ -40,6 +40,8 @@ let prometheus_scrape_interval = Cli.prometheus_scrape_interval let grafana = Cli.grafana +let grafana_legacy_source = Cli.grafana_legacy_source + let website = Cli.website let website_port = Cli.website_port diff --git a/tezt/lib_cloud/env.mli b/tezt/lib_cloud/env.mli index 092db0a8795bf690cfaed669f867c02847ede837..e9853c5b681948ce1d2c4c95addeb603e998e33e 100644 --- a/tezt/lib_cloud/env.mli +++ b/tezt/lib_cloud/env.mli @@ -55,6 +55,9 @@ val prometheus_scrape_interval : int (** Equivalent to [Cli.grafana]. *) val grafana : bool +(** Equivalent to [Cli.grafana_legacy_source]. *) +val grafana_legacy_source : bool + (** Equivalent to [Cli.website]. *) val website : bool diff --git a/tezt/lib_cloud/grafana.ml b/tezt/lib_cloud/grafana.ml index 906e26831b342cd5203631f1c4fea7237c690104..67254f5a844cdfb1668dd3c89d8b64e2740ce086 100644 --- a/tezt/lib_cloud/grafana.ml +++ b/tezt/lib_cloud/grafana.ml @@ -47,7 +47,18 @@ let configuration admin_api_key : config = timeout = 2.0; } -let provisioning_directory () = +let default_source = + sf + {| +- name: Prometheus + type: prometheus + access: proxy + url: http://localhost:%d + isDefault: true +|} + Env.prometheus_port + +let provisioning_directory sources = let provisioning_directory = Filename.get_temp_dir_name () // "grafana" // "provisioning" in @@ -56,18 +67,7 @@ let provisioning_directory () = in let* () = Process.run "mkdir" ["-p"; provisioning_file |> Filename.dirname] in let content = - sf - {| -apiVersion: 1 - -datasources: - - name: Prometheus - type: prometheus - access: proxy - url: http://localhost:%d - isDefault: true -|} - Env.prometheus_port + "apiVersion: 1\n\ndatasources:\n" ^ String.concat "\n" sources in with_open_out provisioning_file (fun oc -> Stdlib.seek_out oc 0 ; @@ -89,7 +89,7 @@ let dashboards_filepaths () = in List.map (fun basename -> path // basename) basenames |> Lwt.return -let run () = +let run ?(sources = [default_source]) () = let cmd = "docker" in let* () = Process.run "mkdir" ["-p"; Filename.get_temp_dir_name () // "grafana"] @@ -100,7 +100,7 @@ let run () = let* () = Process.run "mkdir" ["-p"; dashboard_directory |> Filename.dirname] in - let* provisioning_directory = provisioning_directory () in + let* provisioning_directory = provisioning_directory sources in (* We generate a password to use admin features. This is not completely secured but this should prevent easy attacks if the grafana port is opened. *) let password = generate_password () in diff --git a/tezt/lib_cloud/grafana.mli b/tezt/lib_cloud/grafana.mli index 84628e457df2da76a3fc4f2ec8f316619c860a85..6fb65538734810e873ec5b62ac83b3ce424afe8d 100644 --- a/tezt/lib_cloud/grafana.mli +++ b/tezt/lib_cloud/grafana.mli @@ -9,7 +9,7 @@ include module type of Tezt_tezos_tezt_performance_regression.Grafana type t -val run : unit -> t Lwt.t +val run : ?sources:string list -> unit -> t Lwt.t val shutdown : t -> unit Lwt.t diff --git a/tezt/lib_cloud/prometheus.ml b/tezt/lib_cloud/prometheus.ml index b016b6fae7c1212fdf1283400e758fc58cb588b5..a65b54fe5e103b74177db0ec85cbcffc49f9bad2 100644 --- a/tezt/lib_cloud/prometheus.ml +++ b/tezt/lib_cloud/prometheus.ml @@ -63,6 +63,10 @@ type t = { groups : groups; } +let get_name (t : t) = t.name + +let get_port (t : t) = t.port + let netdata_source_of_agents agents = let name = "netdata" in let metrics_path = "/api/v1/allmetrics?format=prometheus&help=yes" in diff --git a/tezt/lib_cloud/prometheus.mli b/tezt/lib_cloud/prometheus.mli index 336742a8720724f4bd7281bcc6b94d5adc09b119..51ec1b1e1345ad469cc83d406726b853223a7903 100644 --- a/tezt/lib_cloud/prometheus.mli +++ b/tezt/lib_cloud/prometheus.mli @@ -7,6 +7,12 @@ type t +(** Get the docker container name *) +val get_name : t -> string + +(** Get the port used on localhost used for port [9090] of the docker machine *) +val get_port : t -> int + type target = {address : string; port : int; app_name : string} type alert diff --git a/tezt/lib_cloud/tezt_cloud.ml b/tezt/lib_cloud/tezt_cloud.ml index 0dfa6b0e317d9df8adf3e3469bc4cdee4c37a4da..8bf25ad48842e2f5330eed586fa8e38e59b876f0 100644 --- a/tezt/lib_cloud/tezt_cloud.ml +++ b/tezt/lib_cloud/tezt_cloud.ml @@ -96,13 +96,61 @@ let register_prometheus_import ~tags = (fun (path, port) -> Prometheus.run_with_snapshot port path) conf in + let* g = + if Env.grafana then + let sources = + if Env.grafana_legacy_source then + match prometheus with + | [p] -> + (* For legacy support of the existing grafana dashboards, when + using only one snapshot, we want to use the default + 'Prometheus' source name. *) + let port = Prometheus.get_port p in + [ + sf + {| +- name: Prometheus + type: prometheus + access: proxy + url: http://localhost:%d + isDefault: true +|} + port; + ] + | _ -> + Test.fail + "You need to provide one and only one snapshot when using the \ + legacy dashboard source name" + else + (* When using multiple snapshots we assume that they are used + with a dashboard that do not hard code the datasource + name. *) + List.map + (fun p -> + let name = Prometheus.get_name p in + let port = Prometheus.get_port p in + sf + {| +- name: %s + type: prometheus + access: proxy + url: http://localhost:%d +|} + name + port) + prometheus + in + Grafana.run ~sources () |> Lwt.map Option.some + else Lwt.return_none + in Log.info "Prometheus instances are now running. Write 'stop' in order to stop and \ remove docker containers." ; while read_line () <> "stop" do () done ; - Lwt_list.iter_s Prometheus.shutdown prometheus + let* () = Lwt_list.iter_s Prometheus.shutdown prometheus in + Option.map Grafana.shutdown g |> Option.value ~default:Lwt.return_unit let register_clean_up_vms ~tags = Cloud.register