Description of Architecture
There are 3 main components which make up the processor.
1. transformer
2. morpher
3. dbinterface
Additionally, we have a component benchmarker
which is used to measure and store timings of each request at each component.
Transformer
The transformer is a HTTP proxy which receives metrics in the Prometheus Remote Write format, calls a Transform function on the data and sends metrics in the Remote Write format.
It receives HTTP POST payloads containing metric data (encoded as Protobuf) from a listen
address, converts it into the prompb
format to perform processing on the metrics (through the Transform function) and finally encodes the prompb
back to HTTP payload and sends it to the target
address. The listen
and target
address are set through the processor's flags.
Morpher
The morpher manages the DAG chain and the compilation of the DAG from the user submitted format to the SQL query that needs to be executed. Users represent their processor DAG (more specifically a tree) as a yaml which is then compiled to build a set of interlinked SQL queries which use the previous DAG node output as input.
The morpher receiver exposes 2 endpoints, create
and delete
to update the DAG, which are described below. It further parses the selector and parameters before passing it to the morpher.
DBInterface
The dbinterface
mainly deals with managing the Database throughout the processor's lifecycle by inserting metrics into the db, executing the SQL commands corresponding to the DAG and finally moving metrics which need to be exported, from the database.
SQLite offers 2 modes, file mode and in-memory mode for managing the DB.
Processor API Endpoints
The processor exposes 2 endpoints to update DAGs dynamically at the 8100
port. This is the /morphchain
endpoint with the /create
and /delete
endpoints for creating and deleting DAGs respectively.
To create a DAG, call the create
endpoint with the DAG yaml as given in example ../contrib/processor_dag_examples/filter.yaml
curl IP:8100/morphchain/create --data-binary '@controller/dag_examples/filter.yaml'
To reset the DAG, call the delete
endpoint. This will reset to the default DAG, which sends all metrics at 30 sec frequency.
curl IP:8100/morphchain/delete
Running locally
The architecture has 4 main components which we need to bring up to run the end to end system locally:
1. Metric source: To generate metrics in the Prometheus format. While a tool like Avalanche can be used, it does not allow customization of the number and style of labels. We have built a custom generator which allows to customize the labels, in ec-metric-gen
.
2. Local metric collector: A metric collector agent which collects metrics from multiple metric sources and exposes it in the Prometheus Remote Write format. This could be Prometheus or some other tool. For further steps, we consider Prometheus.
3. Metric processor: This is the current repo. Compilation and running instructions are given below.
4. Central Metric collector: Metric collector agent which can receive from multiple metric collectors (in the Prometheus Remote Write format). Some tools for this are Thanos, Cortex or even Prometheus. For further steps, we consider Thanos.
Prometheus can be installed and run locally or run in a docker container. Similarly, Thanos can be installed locally or run in a docker container.
To compile the processor, run:
go build main.go
Running:
1. Start metric generator - we use the gen-metrics-gutentag.py
script. For more details on the different options it provides, check its README. It exposes port 8000 for Prometheus to scrape metrics.
$ cd ../contrib/ec-metric-gen/
$ python3 gen-metrics-gutentag.py --fake --nmetrics 1000 --nlabels 10
INFO:root:Generating 10 metrics excluding labels and 1000 metrics including labels
Setting the target to scrape from (the metric-gen prometheus scrape endpoint)
```
scrape_configs:
static_configs:
- targets: ["localhost:8000"]
```
and the push URL. This is the processor's transformer endpoint.
```
remote_write:
- url: "http://localhost:8081/api/v1/receive"
```
We run prometheus as:
```
$ prometheus --config.file="../contrib/ec-metric-gen/prometheus.yml"
```
Until the processor starts, prometheus may complain about connection being refused. Once the processor starts, it will start forwarding the metrics.
```
ts=2024-05-06T03:29:44.164Z caller=dedupe.go:112 component=remote level=warn remote_name=e5a93c url=http://localhost:8081/api/v1/push msg="Failed to send batch, retrying" err="Post \"http://localhost:8081/api/v1/push\": dial tcp [::1]:8081: connect: connection refused"
```
-
Start the PMF processor. It takes 2 flags, one for the target (this is the Thanos/Cortex endpoint) and one for the listen (this is the endpoint which listens for Prometheus Remote Write pusher).
Target needs to be configured based on the Central Metric Collector. Thanos listens on port
19291
and Cortex listens on port9090
.4. Start Thanos. Thanos has the receive and query components which need to start up:$ go run main.go --target http://localhost:19291" --listen "0.0.0.0:8081"
./thanos receive --grpc-address=0.0.0.0:10901 --remote-write.address=0.0.0.0:19291 --label=receive=\"true\" ./thanos query --grpc-address=0.0.0.0:20901 --http-address=0.0.0.0:19192 --store=0.0.0.0:10901
To visualize the metrics, you may additionally set up Grafana and connect to Thanos.