Metrics
Introduce metrics into the evitaDB. The servlet for metric should start as separate API on different port (or part of a system API). Although we are used to Prometheus API, we should analyze different options - namely Open Telemetry.
Metrics proposals
- [x] consider removing metrics type from name
- [x] add tracing to evitaDB core on more places and not only QueryPlan
System metrics
- [X] JVM metrics
- [x] Liveness probe metrics
- [x] Readiness probe metrics (with labeled API)
- [x] Java errors counter
- [x] evitaDB InternalError counter
Storage metrics
Transactions
- [x] number of active transactions
- [x] age of transaction in seconds
- [x] number of commits
- [x] number of rollbacks
- [x] age of oldest active transaction in seconds
- [x] number of transactions writing to disk
- [x] oldest WAL record age in seconds (write history)
- [x] number of WAL records to process
- [x] number of WAL records to processed
- [x] latency between transaction commit and finalization
- [x] latency of transaction stage execution time
- [x] WAL offheap memory size (+ used off heap memory)
- [x] transaction queue lag - for each stage
Storage
Per collection
- [x] offset index size (memory)
- [x] offset index waste size (disk)
- [x] offset index active dataset size (disk)
- [x] number of opened file handles
- [x] non-flushed record count
- [x] non-flushed record size in Bytes
- [x] max record size in bytes
- [x] record count
- [x] record count per record type
- [x] offset index size - total (disk)
- [x] oldest record age in seconds (read history)
- [x] compaction occurrences
- [x] compaction time in seconds
Per catalog
- [x] collection count
- [x] offset index size (memory) - ∑ of entity collection
- [x] offset index waste size (disk) - ∑ of entity collection
- [x] offset index active dataset size (disk) - ∑ of entity collection
- [x] number of opened file handles - ∑ of entity collection + WAL + file transactions
- [x] record count - ∑ of entity collection
- [x] offset index size - total (disk) - ∑ of entity collection
- [x] total folder size - total (disk)
- [x] oldest catalog header version in seconds (read history)
- [x] compaction occurrences - ∑ of all
- [x] compaction time in seconds - ∑ of all
- [x] number of cached opened outputs (ObservableOutputKeeper)
- [x] number of WAL cached locations (CatalogWriteAheadLog)
Per instance
- [x] catalog count
- [x] offset index size (memory) - ∑ of catalogs
- [x] offset index waste size (disk) - ∑ of catalogs
- [x] offset index active dataset size (disk) - ∑ of catalogs
- [x] number of opened file handles - ∑ of entity catalogs
- [x] record count - ∑ of catalogs
- [x] offset index size - total (disk) - ∑ of catalogs
- [x] total folders size - total (disk) - ∑ of catalogs
- [x] compaction occurrences - ∑ of all compactions
- [x] compaction time in seconds - ∑ of all compactions
- [x] number of cached opened outputs (ObservableOutputKeeper) - ∑ of catalogs
- [x] number of WAL cached locations (CatalogWriteAheadLog) - ∑ of catalogs
Engine metrics
Queries
- [x] query process time (tag: catalog, collection)
- [x] query complexity (tag: catalogn, collection)
- [x] query records returned (tag: catalog, collection)
- [x] query records fetched from disk - count (tag: catalog, collection)
- [x] query records fetched from disk - size in Bytes (tag: catalog, collection)
- [x] active sessions (tag: catalog)
- [x] sessions killed (tag: catalog)
- [x] queries per session
- [x] age of sessions in seconds
- [x] age of oldest session in seconds
Per instance
- [x] query process time (tag: catalog, collection) - ∑ of catalogs
- [x] query complexity (tag: catalog, collection) - ∑ of catalogs
- [x] query records returned (tag: catalog, collection) - ∑ of catalogs
- [x] active sessions (tag: catalog) - ∑ of catalogs
- [x] executor threads
- [x] executor used threads (tag: process name, catalog)
- [x] executor thread execution time (tag: process name, catalog)
Cache
- [ ] cache size in Bytes
- [ ] duration of cache re-evaluation
- [ ] number of records in cache
- [ ] number of records per type in cache
- [ ] size of records in Bytes
- [ ] size of records in Bytes per type in cache
- [ ] cache adepts weighted and found wanting
- [ ] cache adepts elevated to records
- [ ] cache records in cool-down
- [ ] cache records surviving
- [ ] cache records overall complexity per type
- [ ] cache hits
- [ ] cache misses
- [ ] cache records initialized
- [ ] anteroom record count
- [ ] anteroom cycles wasted
Web API metrics
- [ ] active requests (tag: catalog, tag: API[gRPC,REST,GraphQL])
- [ ] request count (+ requests per second, tag: catalog, API[gRPC,REST,GraphQL], result:[TIMEOUT, ERROR, OK])
- [ ] thread pool size
- [ ] used threads
- [ ] ingress Bytes (tag: catalog, API[gRPC,REST,GraphQL])
- [ ] egress Bytes (tag: catalog, API[gRPC,REST,GraphQL])
- [x] query process time API overhead (tag: catalog, collection, API[gRPC,REST,GraphQL])
- [x] query process time with API overhead (tag: catalog, collection, API[gRPC,REST,GraphQL])
- [x] JSON query deserialization into internal structures (tag: catalog, collection, API[gRPC, REST, GraphQL])
- [x] query require constraints reconstruction time (tag: catalog, collection, API[GraphQL])
- [x] input data deserialization time (tag: catalog, collection, API[gRPC,REST, GraphQL])
- [x] API schema building time - new and refresh (tag: catalog, API[REST, GraphQL])
- [x] API refresh count (tag: catalog, API[REST, GraphQL])
- [x] API schema DSL lines count (tag: catalog, API[REST, GraphQL]) ??
- [x] number of API endpoints (tag: catalog, API[REST, GraphQL]) ??
- [x] number of gRPC messages (sent / received, with status ok / error / canceled)
- [x] number of gRPC messages per second (tag: catalog, methodName)
- [x] latency of gRPC messages (histogram)
I will be happy to help and build Zabbix template "evitaDB by Prom"
I will be happy to help and build Zabbix template "evitaDB by Prom"
We'll get in touch before we start working on this issue. ETA is the December 23 / January 24.
We should also investigate this approach:
- https://www.morling.dev/blog/rest-api-monitoring-with-custom-jdk-flight-recorder-events/
- https://www.infoq.com/presentations/jfr-observability/
Interesting slide - three pillars of observability:
I think it might be beneficial to provide a basic access to all three of them in evitaLab.
I'd suggest creating a prototype where:
- try to implement example JFR events according to blog post: https://www.morling.dev/blog/rest-api-monitoring-with-custom-jdk-flight-recorder-events/
- create event that covers evitaDB
QueryPlanexecution - try to record / stream events and visualize them
- try to filter them by predefined template (e.g. collection type for example)
- try to integrate them to metrics: https://opentelemetry.io/docs/instrumentation/java/ and measure the slowdown of the system (I'd like to integrate directly with OpenTelemetry and avoid MicroProfile Metrics)
- open servlets for Prometheus scraping
- create example dashboard in Grafana
It would be interesting also to test https://www.jaegertracing.io/ and its integration into https://grafana.com/docs/grafana/latest/datasources/jaeger/ - it's somehow similar to our https://github.com/FgForrest/evitaDB/issues/148 and we should discuss whether it makes sense to move toward some standard instead of our proprietary solution (the principle should be very similar so it shouldn't be hard to migrate).
This should help us too: https://plugins.jetbrains.com/plugin/20937-java-jfr-profiler
I'd suggest creating a prototype where:
* try to implement example JFR events according to blog post: https://www.morling.dev/blog/rest-api-monitoring-with-custom-jdk-flight-recorder-events/ * create event that covers evitaDB `QueryPlan` execution * try to record / stream events and visualize them * try to filter them by predefined template (e.g. collection type for example) * try to integrate them to metrics: https://opentelemetry.io/docs/instrumentation/java/ and measure the slowdown of the system (I'd like to integrate directly with OpenTelemetry and avoid MicroProfile Metrics) * open servlets for Prometheus scraping * create example dashboard in Grafana
If EvitaDB will be able to use Prometheus format, it is possible to get metrics into Zabbix using https://www.zabbix.com/documentation/current/en/manual/config/items/itemtypes/prometheus it is also possible to use LLD - Low lever Discovery technique for some schema instances etc.
Notes from first prototype showdown and what needs to be added into the prototype:
- how to filter JFR events to be generated = stored
- maybe prepare an alternative to JvmMetrics for evitaMetrics
- check how to make JFR Event enabled work properly
- try to see if some JVM events can be "disabled" - e.g. the flamegraph must be quite demanding?!
- find out how to plug in the OpenTelemetry abstraction
- metrics will have their own API
We'we been recommended by Láďa Prskavec to stick to Prometheus metrics and don't use OTEL for database monitoring purposes. The recommendation was:
- expose metrics via Prometheus endpoint
- log data including "tracing information" - i.e. client id + request id to logs in standardized format
The OTEL is then used on SRE side to integrate multiple vendors together.
As localhost tracing viewer we've been recommended to use https://github.com/CtrlSpice/otel-desktop-viewer and for shared Grafana service https://grafana.com/oss/tempo/
Very minimal set of metrics published at: http://demo.evitadb.io:5557/observability/metrics ... when we get the prototype up and running, we'll expand the metrics list according to the set defined in the issue header.
We need to update the Monitor docs https://evitadb.io/documentation/operate/monitor with the new IDs.
We probably don't need to suffix metrics with type - it's visible in the metrics as comment:
# HELP io_evitadb_core_metric_event_query_plan_step_executed_event_timegauge Time taken
# TYPE io_evitadb_core_metric_event_query_plan_step_executed_event_timegauge gauge
io_evitadb_core_metric_event_query_plan_step_executed_event_timegauge 72500.0
Initial version of metrics is done and released in 2024.7 release:
The issue won't be closed since there are still some metrics missing and also we need to properly document them.
Most of the metrics is done by now. We have also pretty looking dashboard in Grafana that's getting useful. I postpone closing this issue to be finalized later. We still need to:
- [ ] visualize cache metrics, but this is related to #37 being solved
- [ ] visualize thread pools usage
- [ ] finalize documentation (descriptions etc.) - base is already available at https://evitadb.io/documentation/operate/observe?lang=evitaql#metrics
- [ ] extract and document Grafana dashboard to JSON and make available for downloading - we also know, that current filters will not match requirements by K8S pod selection, so we need to investigate this as well