diff --git a/docs/sources/configure-client/grafana-agent/ebpf/setup-linux.md b/docs/sources/configure-client/grafana-agent/ebpf/setup-linux.md index ae838d93fd..7fa1bac39e 100644 --- a/docs/sources/configure-client/grafana-agent/ebpf/setup-linux.md +++ b/docs/sources/configure-client/grafana-agent/ebpf/setup-linux.md @@ -62,10 +62,23 @@ We're [working on a more flexible configuration](https://github.com/grafana/agen Create a file named `agent.river` with the following content: ```river +discovery.process "all" { + +} + +discovery.relabel "agent" { + targets = discovery.process.all.targets + // Filter needed processes + rule { + source_labels = ["__meta_process_exe"] + regex = ".*/grafana-agent" + action = "keep" + } +} + pyroscope.ebpf "instance" { forward_to = [pyroscope.write.endpoint.receiver] - targets_only = false - default_target = {"service_name" = "local"} + targets = discovery.relabel.agent.targets } pyroscope.scrape "local" { @@ -124,3 +137,4 @@ To verify that the profiles are received by the Pyroscope server, go to the Pyro [pyroscope-ds]: /docs/grafana/latest/datasources/grafana-pyroscope/ [config-reference]: ../configuration/ [gcloud]: /products/cloud/ +[discovery.process](/docs/agent/next/flow/reference/components/discovery.process/) diff --git a/examples/ebpf/config.river b/examples/ebpf/config.river deleted file mode 100644 index 4af3350a7a..0000000000 --- a/examples/ebpf/config.river +++ /dev/null @@ -1,10 +0,0 @@ -pyroscope.ebpf "instance" { - forward_to = [pyroscope.write.endpoint.receiver] - targets_only = false - default_target = { "service_name" = "compose-example" } -} -pyroscope.write "endpoint" { - endpoint { - url = "http://pyroscope:4040" - } -} diff --git a/examples/ebpf/docker/config.river b/examples/ebpf/docker/config.river new file mode 100644 index 0000000000..dc72493831 --- /dev/null +++ b/examples/ebpf/docker/config.river @@ -0,0 +1,40 @@ + +discovery.docker "all" { + host = "unix:///var/run/docker.sock" +} + +discovery.relabel "pyroscope" { + targets = discovery.docker.all.targets + // Filter needed containers based on docker labels + // See more info at reference doc https://grafana.com/docs/agent/next/flow/reference/components/discovery.docker/ + rule { + source_labels = ["__meta_docker_container_name"] + regex = ".*pyroscope.*" + action = "keep" + } + // provide arbitrary service_name label, otherwise it will default to value of __meta_docker_container_name + rule { + source_labels = ["__meta_docker_container_name"] + regex = ".*pyroscope.*" + action = "replace" + target_label = "service_name" + replacement = "ebpf/docker/pyroscope" + } +} + + +pyroscope.ebpf "instance" { + forward_to = [pyroscope.write.endpoint.receiver] + targets = discovery.relabel.pyroscope.output +} + +pyroscope.write "endpoint" { + endpoint { + url = "http://pyroscope:4040" + // url = "" + // basic_auth { + // username = "" + // password = "" + // } + } +} diff --git a/examples/ebpf/docker/docker-compose.yml b/examples/ebpf/docker/docker-compose.yml new file mode 100644 index 0000000000..9b11911359 --- /dev/null +++ b/examples/ebpf/docker/docker-compose.yml @@ -0,0 +1,25 @@ +--- +version: '3.9' +services: + pyroscope: + image: grafana/pyroscope + ports: + - '4040:4040' + + grafana-agent: + image: 'grafana/agent:main' + user: root + privileged: true + pid: 'host' + environment: + - AGENT_MODE=flow + volumes: + - '/var/run/docker.sock:/var/run/docker.sock' + - ./config.river:/config.river + ports: + - '12345:12345' + command: + - 'run' + - '/config.river' + - '--storage.path=/tmp/agent' + - '--server.http.listen-addr=0.0.0.0:12345' diff --git a/examples/ebpf/k8s/config.river b/examples/ebpf/k8s/config.river new file mode 100644 index 0000000000..60df9f36ac --- /dev/null +++ b/examples/ebpf/k8s/config.river @@ -0,0 +1,68 @@ +// This is an example grafana agent config to set up eBPF profiling in kubernetes. +// for more info see https://grafana.com/docs/pyroscope/latest/configure-client/grafana-agent/ebpf/setup-kubernetes/ + +discovery.kubernetes "local_pods" { + selectors { + field = "spec.nodeName=" + env("HOSTNAME") // Note: this assume HOSTNAME is set to the node name + role = "pod" + } + role = "pod" +} + +discovery.relabel "specific_pods" { + targets = discovery.kubernetes.all_pods.targets + rule { + action = "drop" + regex = "Succeeded|Failed|Completed" + source_labels = ["__meta_kubernetes_pod_phase"] + } + rule { + action = "replace" + source_labels = ["__meta_kubernetes_namespace"] + target_label = "namespace" + } + rule { + action = "replace" + source_labels = ["__meta_kubernetes_pod_name"] + target_label = "pod" + } + rule { + action = "replace" + source_labels = ["__meta_kubernetes_pod_node_name"] + target_label = "node" + } + rule { + action = "replace" + source_labels = ["__meta_kubernetes_pod_container_name"] + target_label = "container" + } + // provide arbitrary service_name label, otherwise it will be set to {__meta_kubernetes_namespace}/{__meta_kubernetes_pod_container_name} + rule { + action = "replace" + regex = "(.*)@(.*)" + replacement = "ebpf/k8s/${1}/${2}" + separator = "@" + source_labels = ["__meta_kubernetes_namespace", "__meta_kubernetes_pod_container_name"] + target_label = "service_name" + } + // Filter specific targets to profile + rule { + source_labels = ["service_name"] + regex = "(ebpf/grafana-agent/agent|ebpf/pyroscope/pyroscope)" + action = "keep" + } +} + +pyroscope.ebpf "instance" { + forward_to = [pyroscope.write.endpoint.receiver] + targets = discovery.relabel.specific_pods.targets +} + +pyroscope.write "endpoint" { + url = "http://pyroscope:4040" + // url = "" + // basic_auth { + // username = "" + // password = "" + // } +} \ No newline at end of file diff --git a/examples/ebpf/local/config.river b/examples/ebpf/local/config.river new file mode 100644 index 0000000000..d10937a5e0 --- /dev/null +++ b/examples/ebpf/local/config.river @@ -0,0 +1,54 @@ + +// discovery.process produces targets with the following labels:` +// "__process_pid__" +// "__meta_process_exe" +// "__meta_process_cwd" +// "__meta_process_commandline" +// "__meta_process_username" +// "__meta_process_uid" +// "__container_id__" +// See reference doc for more info https://grafana.com/docs/agent/next/flow/reference/components/discovery.process/ + +discovery.process "all" { + +} + +discovery.relabel "agent" { + targets = discovery.process.all.targets + // Filter needed processes + rule { + source_labels = ["__meta_process_exe"] + regex = ".*/grafana-agent" + action = "keep" + } + // provide arbitrary service_name label, otherwise it will be "unspecified" + rule { + source_labels = ["__meta_process_exe"] + target_label = "service_name" + regex = ".*/grafana-agent" + action = "replace" + replacement = "ebpf/local/grafana-agent" + } +} + + +pyroscope.ebpf "instance" { + forward_to = [pyroscope.write.endpoint.receiver] + targets = concat( + discovery.relabel.agent.output, + [{"__process_pid__" = "1", "service_name" = "ebpf/local/init"}], + ) +} + + +pyroscope.write "endpoint" { + endpoint { + url = "http://pyroscope:4040" + // url = "" + // basic_auth { + // username = "" + // password = "" + // } + } +} + diff --git a/examples/ebpf/docker-compose.yml b/examples/ebpf/local/docker-compose.yml similarity index 92% rename from examples/ebpf/docker-compose.yml rename to examples/ebpf/local/docker-compose.yml index f591d5ceee..23b1a05e81 100644 --- a/examples/ebpf/docker-compose.yml +++ b/examples/ebpf/local/docker-compose.yml @@ -7,7 +7,7 @@ services: - '4040:4040' app: - image: 'grafana/agent:latest' + image: 'grafana/agent:main' user: root privileged: true pid: 'host'