mirror of
				https://github.com/XRPLF/clio.git
				synced 2025-11-04 11:55:51 +00:00 
			
		
		
		
	@@ -18,6 +18,7 @@
 | 
			
		||||
  "editable": true,
 | 
			
		||||
  "fiscalYearStartMonth": 0,
 | 
			
		||||
  "graphTooltip": 0,
 | 
			
		||||
  "id": 1,
 | 
			
		||||
  "links": [],
 | 
			
		||||
  "liveNow": false,
 | 
			
		||||
  "panels": [
 | 
			
		||||
@@ -85,9 +86,11 @@
 | 
			
		||||
          "fields": "",
 | 
			
		||||
          "values": false
 | 
			
		||||
        },
 | 
			
		||||
        "textMode": "auto"
 | 
			
		||||
        "showPercentChange": false,
 | 
			
		||||
        "textMode": "auto",
 | 
			
		||||
        "wideLayout": true
 | 
			
		||||
      },
 | 
			
		||||
      "pluginVersion": "10.2.0",
 | 
			
		||||
      "pluginVersion": "10.4.0",
 | 
			
		||||
      "targets": [
 | 
			
		||||
        {
 | 
			
		||||
          "datasource": {
 | 
			
		||||
@@ -105,6 +108,372 @@
 | 
			
		||||
      "title": "Service state",
 | 
			
		||||
      "type": "stat"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "datasource": {
 | 
			
		||||
        "type": "prometheus",
 | 
			
		||||
        "uid": "PBFA97CFB590B2093"
 | 
			
		||||
      },
 | 
			
		||||
      "fieldConfig": {
 | 
			
		||||
        "defaults": {
 | 
			
		||||
          "color": {
 | 
			
		||||
            "mode": "thresholds"
 | 
			
		||||
          },
 | 
			
		||||
          "mappings": [
 | 
			
		||||
            {
 | 
			
		||||
              "options": {
 | 
			
		||||
                "0": {
 | 
			
		||||
                  "color": "blue",
 | 
			
		||||
                  "index": 0,
 | 
			
		||||
                  "text": "No"
 | 
			
		||||
                },
 | 
			
		||||
                "1": {
 | 
			
		||||
                  "color": "green",
 | 
			
		||||
                  "index": 1,
 | 
			
		||||
                  "text": "Yes"
 | 
			
		||||
                }
 | 
			
		||||
              },
 | 
			
		||||
              "type": "value"
 | 
			
		||||
            }
 | 
			
		||||
          ],
 | 
			
		||||
          "thresholds": {
 | 
			
		||||
            "mode": "absolute",
 | 
			
		||||
            "steps": [
 | 
			
		||||
              {
 | 
			
		||||
                "color": "green",
 | 
			
		||||
                "value": null
 | 
			
		||||
              }
 | 
			
		||||
            ]
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "overrides": []
 | 
			
		||||
      },
 | 
			
		||||
      "gridPos": {
 | 
			
		||||
        "h": 8,
 | 
			
		||||
        "w": 3,
 | 
			
		||||
        "x": 3,
 | 
			
		||||
        "y": 0
 | 
			
		||||
      },
 | 
			
		||||
      "id": 14,
 | 
			
		||||
      "options": {
 | 
			
		||||
        "colorMode": "value",
 | 
			
		||||
        "graphMode": "area",
 | 
			
		||||
        "justifyMode": "auto",
 | 
			
		||||
        "orientation": "auto",
 | 
			
		||||
        "reduceOptions": {
 | 
			
		||||
          "calcs": [
 | 
			
		||||
            "lastNotNull"
 | 
			
		||||
          ],
 | 
			
		||||
          "fields": "",
 | 
			
		||||
          "values": false
 | 
			
		||||
        },
 | 
			
		||||
        "showPercentChange": false,
 | 
			
		||||
        "textMode": "auto",
 | 
			
		||||
        "wideLayout": true
 | 
			
		||||
      },
 | 
			
		||||
      "pluginVersion": "10.4.0",
 | 
			
		||||
      "targets": [
 | 
			
		||||
        {
 | 
			
		||||
          "datasource": {
 | 
			
		||||
            "type": "prometheus",
 | 
			
		||||
            "uid": "PBFA97CFB590B2093"
 | 
			
		||||
          },
 | 
			
		||||
          "editorMode": "code",
 | 
			
		||||
          "expr": "read_only",
 | 
			
		||||
          "instant": false,
 | 
			
		||||
          "legendFormat": "__auto",
 | 
			
		||||
          "range": true,
 | 
			
		||||
          "refId": "A"
 | 
			
		||||
        }
 | 
			
		||||
      ],
 | 
			
		||||
      "title": "Read only",
 | 
			
		||||
      "type": "stat"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "datasource": {
 | 
			
		||||
        "type": "prometheus",
 | 
			
		||||
        "uid": "PBFA97CFB590B2093"
 | 
			
		||||
      },
 | 
			
		||||
      "fieldConfig": {
 | 
			
		||||
        "defaults": {
 | 
			
		||||
          "color": {
 | 
			
		||||
            "mode": "thresholds"
 | 
			
		||||
          },
 | 
			
		||||
          "mappings": [
 | 
			
		||||
            {
 | 
			
		||||
              "options": {
 | 
			
		||||
                "0": {
 | 
			
		||||
                  "color": "blue",
 | 
			
		||||
                  "index": 0,
 | 
			
		||||
                  "text": "No"
 | 
			
		||||
                },
 | 
			
		||||
                "1": {
 | 
			
		||||
                  "color": "green",
 | 
			
		||||
                  "index": 1,
 | 
			
		||||
                  "text": "Yes"
 | 
			
		||||
                }
 | 
			
		||||
              },
 | 
			
		||||
              "type": "value"
 | 
			
		||||
            }
 | 
			
		||||
          ],
 | 
			
		||||
          "thresholds": {
 | 
			
		||||
            "mode": "absolute",
 | 
			
		||||
            "steps": [
 | 
			
		||||
              {
 | 
			
		||||
                "color": "green",
 | 
			
		||||
                "value": null
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                "color": "red",
 | 
			
		||||
                "value": 80
 | 
			
		||||
              }
 | 
			
		||||
            ]
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "overrides": []
 | 
			
		||||
      },
 | 
			
		||||
      "gridPos": {
 | 
			
		||||
        "h": 8,
 | 
			
		||||
        "w": 3,
 | 
			
		||||
        "x": 6,
 | 
			
		||||
        "y": 0
 | 
			
		||||
      },
 | 
			
		||||
      "id": 15,
 | 
			
		||||
      "options": {
 | 
			
		||||
        "colorMode": "value",
 | 
			
		||||
        "graphMode": "area",
 | 
			
		||||
        "justifyMode": "auto",
 | 
			
		||||
        "orientation": "auto",
 | 
			
		||||
        "reduceOptions": {
 | 
			
		||||
          "calcs": [
 | 
			
		||||
            "lastNotNull"
 | 
			
		||||
          ],
 | 
			
		||||
          "fields": "",
 | 
			
		||||
          "values": false
 | 
			
		||||
        },
 | 
			
		||||
        "showPercentChange": false,
 | 
			
		||||
        "textMode": "auto",
 | 
			
		||||
        "wideLayout": true
 | 
			
		||||
      },
 | 
			
		||||
      "pluginVersion": "10.4.0",
 | 
			
		||||
      "targets": [
 | 
			
		||||
        {
 | 
			
		||||
          "datasource": {
 | 
			
		||||
            "type": "prometheus",
 | 
			
		||||
            "uid": "PBFA97CFB590B2093"
 | 
			
		||||
          },
 | 
			
		||||
          "editorMode": "code",
 | 
			
		||||
          "expr": "etl_writing",
 | 
			
		||||
          "instant": false,
 | 
			
		||||
          "legendFormat": "__auto",
 | 
			
		||||
          "range": true,
 | 
			
		||||
          "refId": "A"
 | 
			
		||||
        }
 | 
			
		||||
      ],
 | 
			
		||||
      "title": "Writing data to DB",
 | 
			
		||||
      "type": "stat"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "datasource": {
 | 
			
		||||
        "type": "prometheus",
 | 
			
		||||
        "uid": "PBFA97CFB590B2093"
 | 
			
		||||
      },
 | 
			
		||||
      "fieldConfig": {
 | 
			
		||||
        "defaults": {
 | 
			
		||||
          "color": {
 | 
			
		||||
            "mode": "thresholds"
 | 
			
		||||
          },
 | 
			
		||||
          "mappings": [
 | 
			
		||||
            {
 | 
			
		||||
              "options": {
 | 
			
		||||
                "0": {
 | 
			
		||||
                  "color": "green",
 | 
			
		||||
                  "index": 0,
 | 
			
		||||
                  "text": "No"
 | 
			
		||||
                },
 | 
			
		||||
                "1": {
 | 
			
		||||
                  "color": "red",
 | 
			
		||||
                  "index": 1,
 | 
			
		||||
                  "text": "Yes"
 | 
			
		||||
                }
 | 
			
		||||
              },
 | 
			
		||||
              "type": "value"
 | 
			
		||||
            }
 | 
			
		||||
          ],
 | 
			
		||||
          "thresholds": {
 | 
			
		||||
            "mode": "absolute",
 | 
			
		||||
            "steps": [
 | 
			
		||||
              {
 | 
			
		||||
                "color": "green",
 | 
			
		||||
                "value": null
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                "color": "red",
 | 
			
		||||
                "value": 80
 | 
			
		||||
              }
 | 
			
		||||
            ]
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "overrides": []
 | 
			
		||||
      },
 | 
			
		||||
      "gridPos": {
 | 
			
		||||
        "h": 8,
 | 
			
		||||
        "w": 3,
 | 
			
		||||
        "x": 9,
 | 
			
		||||
        "y": 0
 | 
			
		||||
      },
 | 
			
		||||
      "id": 16,
 | 
			
		||||
      "options": {
 | 
			
		||||
        "colorMode": "value",
 | 
			
		||||
        "graphMode": "area",
 | 
			
		||||
        "justifyMode": "auto",
 | 
			
		||||
        "orientation": "auto",
 | 
			
		||||
        "reduceOptions": {
 | 
			
		||||
          "calcs": [
 | 
			
		||||
            "lastNotNull"
 | 
			
		||||
          ],
 | 
			
		||||
          "fields": "",
 | 
			
		||||
          "values": false
 | 
			
		||||
        },
 | 
			
		||||
        "showPercentChange": false,
 | 
			
		||||
        "textMode": "auto",
 | 
			
		||||
        "wideLayout": true
 | 
			
		||||
      },
 | 
			
		||||
      "pluginVersion": "10.4.0",
 | 
			
		||||
      "targets": [
 | 
			
		||||
        {
 | 
			
		||||
          "datasource": {
 | 
			
		||||
            "type": "prometheus",
 | 
			
		||||
            "uid": "PBFA97CFB590B2093"
 | 
			
		||||
          },
 | 
			
		||||
          "editorMode": "code",
 | 
			
		||||
          "expr": "etl_amendment_blocked",
 | 
			
		||||
          "instant": false,
 | 
			
		||||
          "legendFormat": "__auto",
 | 
			
		||||
          "range": true,
 | 
			
		||||
          "refId": "A"
 | 
			
		||||
        }
 | 
			
		||||
      ],
 | 
			
		||||
      "title": "Amendment blocked",
 | 
			
		||||
      "type": "stat"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "datasource": {
 | 
			
		||||
        "type": "prometheus",
 | 
			
		||||
        "uid": "PBFA97CFB590B2093"
 | 
			
		||||
      },
 | 
			
		||||
      "fieldConfig": {
 | 
			
		||||
        "defaults": {
 | 
			
		||||
          "color": {
 | 
			
		||||
            "mode": "palette-classic"
 | 
			
		||||
          },
 | 
			
		||||
          "custom": {
 | 
			
		||||
            "axisBorderShow": false,
 | 
			
		||||
            "axisCenteredZero": false,
 | 
			
		||||
            "axisColorMode": "text",
 | 
			
		||||
            "axisLabel": "",
 | 
			
		||||
            "axisPlacement": "auto",
 | 
			
		||||
            "barAlignment": 0,
 | 
			
		||||
            "drawStyle": "line",
 | 
			
		||||
            "fillOpacity": 0,
 | 
			
		||||
            "gradientMode": "none",
 | 
			
		||||
            "hideFrom": {
 | 
			
		||||
              "legend": false,
 | 
			
		||||
              "tooltip": false,
 | 
			
		||||
              "viz": false
 | 
			
		||||
            },
 | 
			
		||||
            "insertNulls": false,
 | 
			
		||||
            "lineInterpolation": "linear",
 | 
			
		||||
            "lineWidth": 1,
 | 
			
		||||
            "pointSize": 5,
 | 
			
		||||
            "scaleDistribution": {
 | 
			
		||||
              "type": "linear"
 | 
			
		||||
            },
 | 
			
		||||
            "showPoints": "auto",
 | 
			
		||||
            "spanNulls": false,
 | 
			
		||||
            "stacking": {
 | 
			
		||||
              "group": "A",
 | 
			
		||||
              "mode": "none"
 | 
			
		||||
            },
 | 
			
		||||
            "thresholdsStyle": {
 | 
			
		||||
              "mode": "off"
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          "mappings": [],
 | 
			
		||||
          "thresholds": {
 | 
			
		||||
            "mode": "absolute",
 | 
			
		||||
            "steps": [
 | 
			
		||||
              {
 | 
			
		||||
                "color": "green",
 | 
			
		||||
                "value": null
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                "color": "red",
 | 
			
		||||
                "value": 80
 | 
			
		||||
              }
 | 
			
		||||
            ]
 | 
			
		||||
          },
 | 
			
		||||
          "unit": "s"
 | 
			
		||||
        },
 | 
			
		||||
        "overrides": []
 | 
			
		||||
      },
 | 
			
		||||
      "gridPos": {
 | 
			
		||||
        "h": 8,
 | 
			
		||||
        "w": 12,
 | 
			
		||||
        "x": 12,
 | 
			
		||||
        "y": 0
 | 
			
		||||
      },
 | 
			
		||||
      "id": 13,
 | 
			
		||||
      "options": {
 | 
			
		||||
        "legend": {
 | 
			
		||||
          "calcs": [],
 | 
			
		||||
          "displayMode": "list",
 | 
			
		||||
          "placement": "bottom",
 | 
			
		||||
          "showLegend": true
 | 
			
		||||
        },
 | 
			
		||||
        "tooltip": {
 | 
			
		||||
          "mode": "single",
 | 
			
		||||
          "sort": "none"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "targets": [
 | 
			
		||||
        {
 | 
			
		||||
          "datasource": {
 | 
			
		||||
            "type": "prometheus",
 | 
			
		||||
            "uid": "PBFA97CFB590B2093"
 | 
			
		||||
          },
 | 
			
		||||
          "editorMode": "code",
 | 
			
		||||
          "exemplar": false,
 | 
			
		||||
          "expr": "timestamp(etl_last_publish_seconds) - etl_last_publish_seconds",
 | 
			
		||||
          "format": "time_series",
 | 
			
		||||
          "instant": false,
 | 
			
		||||
          "legendFormat": "ledger age",
 | 
			
		||||
          "range": true,
 | 
			
		||||
          "refId": "A"
 | 
			
		||||
        }
 | 
			
		||||
      ],
 | 
			
		||||
      "title": "Ledger Age",
 | 
			
		||||
      "transformations": [
 | 
			
		||||
        {
 | 
			
		||||
          "id": "filterByValue",
 | 
			
		||||
          "options": {
 | 
			
		||||
            "filters": [
 | 
			
		||||
              {
 | 
			
		||||
                "config": {
 | 
			
		||||
                  "id": "lower",
 | 
			
		||||
                  "options": {
 | 
			
		||||
                    "value": 31500000
 | 
			
		||||
                  }
 | 
			
		||||
                },
 | 
			
		||||
                "fieldName": "ledger age"
 | 
			
		||||
              }
 | 
			
		||||
            ],
 | 
			
		||||
            "match": "all",
 | 
			
		||||
            "type": "include"
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      ],
 | 
			
		||||
      "type": "timeseries"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "datasource": {
 | 
			
		||||
        "type": "prometheus",
 | 
			
		||||
@@ -166,9 +535,9 @@
 | 
			
		||||
      },
 | 
			
		||||
      "gridPos": {
 | 
			
		||||
        "h": 8,
 | 
			
		||||
        "w": 9,
 | 
			
		||||
        "x": 3,
 | 
			
		||||
        "y": 0
 | 
			
		||||
        "w": 12,
 | 
			
		||||
        "x": 0,
 | 
			
		||||
        "y": 8
 | 
			
		||||
      },
 | 
			
		||||
      "id": 2,
 | 
			
		||||
      "options": {
 | 
			
		||||
@@ -263,7 +632,7 @@
 | 
			
		||||
        "h": 8,
 | 
			
		||||
        "w": 12,
 | 
			
		||||
        "x": 12,
 | 
			
		||||
        "y": 0
 | 
			
		||||
        "y": 8
 | 
			
		||||
      },
 | 
			
		||||
      "id": 9,
 | 
			
		||||
      "options": {
 | 
			
		||||
@@ -358,7 +727,7 @@
 | 
			
		||||
        "h": 8,
 | 
			
		||||
        "w": 12,
 | 
			
		||||
        "x": 0,
 | 
			
		||||
        "y": 8
 | 
			
		||||
        "y": 16
 | 
			
		||||
      },
 | 
			
		||||
      "id": 11,
 | 
			
		||||
      "options": {
 | 
			
		||||
@@ -453,7 +822,7 @@
 | 
			
		||||
        "h": 8,
 | 
			
		||||
        "w": 12,
 | 
			
		||||
        "x": 12,
 | 
			
		||||
        "y": 8
 | 
			
		||||
        "y": 16
 | 
			
		||||
      },
 | 
			
		||||
      "id": 6,
 | 
			
		||||
      "options": {
 | 
			
		||||
@@ -550,7 +919,7 @@
 | 
			
		||||
        "h": 8,
 | 
			
		||||
        "w": 12,
 | 
			
		||||
        "x": 0,
 | 
			
		||||
        "y": 16
 | 
			
		||||
        "y": 24
 | 
			
		||||
      },
 | 
			
		||||
      "id": 10,
 | 
			
		||||
      "options": {
 | 
			
		||||
@@ -645,7 +1014,7 @@
 | 
			
		||||
        "h": 8,
 | 
			
		||||
        "w": 12,
 | 
			
		||||
        "x": 12,
 | 
			
		||||
        "y": 16
 | 
			
		||||
        "y": 24
 | 
			
		||||
      },
 | 
			
		||||
      "id": 8,
 | 
			
		||||
      "options": {
 | 
			
		||||
@@ -740,7 +1109,7 @@
 | 
			
		||||
        "h": 8,
 | 
			
		||||
        "w": 12,
 | 
			
		||||
        "x": 0,
 | 
			
		||||
        "y": 24
 | 
			
		||||
        "y": 32
 | 
			
		||||
      },
 | 
			
		||||
      "id": 4,
 | 
			
		||||
      "options": {
 | 
			
		||||
@@ -839,7 +1208,7 @@
 | 
			
		||||
        "h": 8,
 | 
			
		||||
        "w": 12,
 | 
			
		||||
        "x": 12,
 | 
			
		||||
        "y": 24
 | 
			
		||||
        "y": 32
 | 
			
		||||
      },
 | 
			
		||||
      "id": 12,
 | 
			
		||||
      "options": {
 | 
			
		||||
@@ -973,7 +1342,7 @@
 | 
			
		||||
        "h": 8,
 | 
			
		||||
        "w": 12,
 | 
			
		||||
        "x": 0,
 | 
			
		||||
        "y": 32
 | 
			
		||||
        "y": 40
 | 
			
		||||
      },
 | 
			
		||||
      "id": 5,
 | 
			
		||||
      "options": {
 | 
			
		||||
@@ -1081,7 +1450,7 @@
 | 
			
		||||
        "h": 8,
 | 
			
		||||
        "w": 12,
 | 
			
		||||
        "x": 12,
 | 
			
		||||
        "y": 32
 | 
			
		||||
        "y": 40
 | 
			
		||||
      },
 | 
			
		||||
      "id": 3,
 | 
			
		||||
      "options": {
 | 
			
		||||
@@ -1186,9 +1555,9 @@
 | 
			
		||||
      },
 | 
			
		||||
      "gridPos": {
 | 
			
		||||
        "h": 8,
 | 
			
		||||
        "w": 10,
 | 
			
		||||
        "w": 12,
 | 
			
		||||
        "x": 0,
 | 
			
		||||
        "y": 40
 | 
			
		||||
        "y": 48
 | 
			
		||||
      },
 | 
			
		||||
      "id": 7,
 | 
			
		||||
      "options": {
 | 
			
		||||
@@ -1222,7 +1591,7 @@
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "refresh": "5s",
 | 
			
		||||
  "schemaVersion": 38,
 | 
			
		||||
  "schemaVersion": 39,
 | 
			
		||||
  "tags": [],
 | 
			
		||||
  "templating": {
 | 
			
		||||
    "list": []
 | 
			
		||||
@@ -1235,6 +1604,6 @@
 | 
			
		||||
  "timezone": "",
 | 
			
		||||
  "title": "Clio",
 | 
			
		||||
  "uid": "aeaae84e-c194-47b2-ad65-86e45eebb815",
 | 
			
		||||
  "version": 3,
 | 
			
		||||
  "version": 1,
 | 
			
		||||
  "weekStart": ""
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -276,7 +276,7 @@ ETLService::ETLService(
 | 
			
		||||
{
 | 
			
		||||
    startSequence_ = config.maybeValue<uint32_t>("start_sequence");
 | 
			
		||||
    finishSequence_ = config.maybeValue<uint32_t>("finish_sequence");
 | 
			
		||||
    state_.isReadOnly = config.valueOr("read_only", state_.isReadOnly);
 | 
			
		||||
    state_.isReadOnly = config.valueOr("read_only", static_cast<bool>(state_.isReadOnly));
 | 
			
		||||
    extractorThreads_ = config.valueOr<uint32_t>("extractor_threads", extractorThreads_);
 | 
			
		||||
    txnThreshold_ = config.valueOr<size_t>("txn_threshold", txnThreshold_);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -212,8 +212,8 @@ public:
 | 
			
		||||
        boost::json::object result;
 | 
			
		||||
 | 
			
		||||
        result["etl_sources"] = loadBalancer_->toJson();
 | 
			
		||||
        result["is_writer"] = state_.isWriting.load();
 | 
			
		||||
        result["read_only"] = state_.isReadOnly;
 | 
			
		||||
        result["is_writer"] = static_cast<int>(state_.isWriting);
 | 
			
		||||
        result["read_only"] = static_cast<int>(state_.isReadOnly);
 | 
			
		||||
        auto last = ledgerPublisher_.getLastPublish();
 | 
			
		||||
        if (last.time_since_epoch().count() != 0)
 | 
			
		||||
            result["last_publish_age_seconds"] = std::to_string(ledgerPublisher_.lastPublishAgeSeconds());
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,10 @@
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "util/prometheus/Bool.hpp"
 | 
			
		||||
#include "util/prometheus/Label.hpp"
 | 
			
		||||
#include "util/prometheus/Prometheus.hpp"
 | 
			
		||||
 | 
			
		||||
#include <atomic>
 | 
			
		||||
 | 
			
		||||
namespace etl {
 | 
			
		||||
@@ -33,9 +37,19 @@ struct SystemState {
 | 
			
		||||
     * In strict read-only mode, the process will never attempt to become the ETL writer, and will only publish ledgers
 | 
			
		||||
     * as they are written to the database.
 | 
			
		||||
     */
 | 
			
		||||
    bool isReadOnly = false;
 | 
			
		||||
    util::prometheus::Bool isReadOnly = PrometheusService::boolMetric(
 | 
			
		||||
        "read_only",
 | 
			
		||||
        util::prometheus::Labels{},
 | 
			
		||||
        "Whether the process is in strict read-only mode"
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    /** @brief Whether the process is writing to the database. */
 | 
			
		||||
    util::prometheus::Bool isWriting = PrometheusService::boolMetric(
 | 
			
		||||
        "etl_writing",
 | 
			
		||||
        util::prometheus::Labels{},
 | 
			
		||||
        "Whether the process is writing to the database"
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    std::atomic_bool isWriting = false;     /**< @brief Whether the process is writing to the database. */
 | 
			
		||||
    std::atomic_bool isStopping = false;    /**< @brief Whether the software is stopping. */
 | 
			
		||||
    std::atomic_bool writeConflict = false; /**< @brief Whether a write conflict was detected. */
 | 
			
		||||
 | 
			
		||||
@@ -46,7 +60,11 @@ struct SystemState {
 | 
			
		||||
     * arrived from rippled and therefore can't extract the ledger diff. When this happens, Clio can't proceed with ETL
 | 
			
		||||
     * and should log this error and only handle RPC requests.
 | 
			
		||||
     */
 | 
			
		||||
    std::atomic_bool isAmendmentBlocked = false;
 | 
			
		||||
    util::prometheus::Bool isAmendmentBlocked = PrometheusService::boolMetric(
 | 
			
		||||
        "etl_amendment_blocked",
 | 
			
		||||
        util::prometheus::Labels{},
 | 
			
		||||
        "Whether clio detected an amendment block"
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}  // namespace etl
 | 
			
		||||
 
 | 
			
		||||
@@ -25,6 +25,8 @@
 | 
			
		||||
#include "etl/SystemState.hpp"
 | 
			
		||||
#include "util/Assert.hpp"
 | 
			
		||||
#include "util/log/Logger.hpp"
 | 
			
		||||
#include "util/prometheus/Counter.hpp"
 | 
			
		||||
#include "util/prometheus/Prometheus.hpp"
 | 
			
		||||
 | 
			
		||||
#include <boost/asio/io_context.hpp>
 | 
			
		||||
#include <boost/asio/strand.hpp>
 | 
			
		||||
@@ -75,8 +77,11 @@ class LedgerPublisher {
 | 
			
		||||
    std::chrono::time_point<ripple::NetClock> lastCloseTime_;
 | 
			
		||||
    mutable std::shared_mutex closeTimeMtx_;
 | 
			
		||||
 | 
			
		||||
    std::chrono::time_point<std::chrono::system_clock> lastPublish_;
 | 
			
		||||
    mutable std::shared_mutex publishTimeMtx_;
 | 
			
		||||
    std::reference_wrapper<util::prometheus::CounterInt> lastPublishSeconds_ = PrometheusService::counterInt(
 | 
			
		||||
        "etl_last_publish_seconds",
 | 
			
		||||
        {},
 | 
			
		||||
        "Seconds since epoch of the last published ledger"
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    std::optional<uint32_t> lastPublishedSequence_;
 | 
			
		||||
    mutable std::shared_mutex lastPublishedSeqMtx_;
 | 
			
		||||
@@ -232,8 +237,8 @@ public:
 | 
			
		||||
    std::chrono::time_point<std::chrono::system_clock>
 | 
			
		||||
    getLastPublish() const
 | 
			
		||||
    {
 | 
			
		||||
        std::shared_lock const lck(publishTimeMtx_);
 | 
			
		||||
        return lastPublish_;
 | 
			
		||||
        return std::chrono::time_point<std::chrono::system_clock>{std::chrono::seconds{lastPublishSeconds_.get().value()
 | 
			
		||||
        }};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -273,8 +278,9 @@ private:
 | 
			
		||||
    void
 | 
			
		||||
    setLastPublishTime()
 | 
			
		||||
    {
 | 
			
		||||
        std::scoped_lock const lck(publishTimeMtx_);
 | 
			
		||||
        lastPublish_ = std::chrono::system_clock::now();
 | 
			
		||||
        using namespace std::chrono;
 | 
			
		||||
        auto const nowSeconds = duration_cast<seconds>(system_clock::now().time_since_epoch()).count();
 | 
			
		||||
        lastPublishSeconds_.get().set(nowSeconds);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										89
									
								
								src/util/prometheus/Bool.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								src/util/prometheus/Bool.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,89 @@
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
/*
 | 
			
		||||
    This file is part of clio: https://github.com/XRPLF/clio
 | 
			
		||||
    Copyright (c) 2024, the clio developers.
 | 
			
		||||
 | 
			
		||||
    Permission to use, copy, modify, and distribute this software for any
 | 
			
		||||
    purpose with or without fee is hereby granted, provided that the above
 | 
			
		||||
    copyright notice and this permission notice appear in all copies.
 | 
			
		||||
 | 
			
		||||
    THE  SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
			
		||||
    WITH  REGARD  TO  THIS  SOFTWARE  INCLUDING  ALL  IMPLIED  WARRANTIES  OF
 | 
			
		||||
    MERCHANTABILITY  AND  FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
			
		||||
    ANY  SPECIAL,  DIRECT,  INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
			
		||||
    WHATSOEVER  RESULTING  FROM  LOSS  OF USE, DATA OR PROFITS, WHETHER IN AN
 | 
			
		||||
    ACTION  OF  CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 | 
			
		||||
    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
			
		||||
*/
 | 
			
		||||
//==============================================================================
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "util/Assert.hpp"
 | 
			
		||||
#include "util/prometheus/Gauge.hpp"
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <functional>
 | 
			
		||||
 | 
			
		||||
namespace util::prometheus {
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
concept SomeBoolImpl = requires(T a) {
 | 
			
		||||
    {
 | 
			
		||||
        a.set(0)
 | 
			
		||||
    } -> std::same_as<void>;
 | 
			
		||||
    {
 | 
			
		||||
        a.value()
 | 
			
		||||
    } -> std::same_as<int64_t>;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief A wrapped to provide bool interface for a Prometheus metric
 | 
			
		||||
 * @note Prometheus does not have a native bool type, so we use a counter with a value of 0 or 1
 | 
			
		||||
 */
 | 
			
		||||
template <SomeBoolImpl ImplType>
 | 
			
		||||
class AnyBool {
 | 
			
		||||
    std::reference_wrapper<ImplType> impl_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Construct a bool metric
 | 
			
		||||
     *
 | 
			
		||||
     * @param impl The implementation of the metric
 | 
			
		||||
     */
 | 
			
		||||
    explicit AnyBool(ImplType& impl) : impl_(impl)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Set the value of the bool metric
 | 
			
		||||
     *
 | 
			
		||||
     * @param value The value to set
 | 
			
		||||
     * @return A reference to the metric
 | 
			
		||||
     */
 | 
			
		||||
    AnyBool&
 | 
			
		||||
    operator=(bool value)
 | 
			
		||||
    {
 | 
			
		||||
        impl_.get().set(value ? 1 : 0);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Get the value of the bool metric
 | 
			
		||||
     *
 | 
			
		||||
     * @return The value of the metric
 | 
			
		||||
     */
 | 
			
		||||
    operator bool() const
 | 
			
		||||
    {
 | 
			
		||||
        auto const value = impl_.get().value();
 | 
			
		||||
        ASSERT(value == 0 || value == 1, "Invalid value for bool: {}", value);
 | 
			
		||||
        return value == 1;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Alias for Prometheus bool metric with GaugeInt implementation
 | 
			
		||||
 */
 | 
			
		||||
using Bool = AnyBool<GaugeInt>;
 | 
			
		||||
 | 
			
		||||
}  // namespace util::prometheus
 | 
			
		||||
@@ -83,6 +83,18 @@ struct AnyCounter : MetricBase, impl::AnyCounterBase<NumberType> {
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Set the value of the counter
 | 
			
		||||
     *
 | 
			
		||||
     * @param value The value to set the counter to
 | 
			
		||||
     */
 | 
			
		||||
    void
 | 
			
		||||
    set(ValueType value)
 | 
			
		||||
    {
 | 
			
		||||
        ASSERT(value >= this->value(), "Cannot decrease a counter {}", this->name());
 | 
			
		||||
        this->pimpl_->set(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Reset the counter to zero
 | 
			
		||||
     */
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,7 @@
 | 
			
		||||
 | 
			
		||||
#include "util/Assert.hpp"
 | 
			
		||||
#include "util/config/Config.hpp"
 | 
			
		||||
#include "util/prometheus/Bool.hpp"
 | 
			
		||||
#include "util/prometheus/Counter.hpp"
 | 
			
		||||
#include "util/prometheus/Gauge.hpp"
 | 
			
		||||
#include "util/prometheus/Histogram.hpp"
 | 
			
		||||
@@ -52,6 +53,13 @@ convertBaseTo(MetricBase& metricBase)
 | 
			
		||||
 | 
			
		||||
}  // namespace
 | 
			
		||||
 | 
			
		||||
Bool
 | 
			
		||||
PrometheusImpl::boolMetric(std::string name, Labels labels, std::optional<std::string> description)
 | 
			
		||||
{
 | 
			
		||||
    auto& metric = gaugeInt(std::move(name), std::move(labels), std::move(description));
 | 
			
		||||
    return Bool{metric};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CounterInt&
 | 
			
		||||
PrometheusImpl::counterInt(std::string name, Labels labels, std::optional<std::string> description)
 | 
			
		||||
{
 | 
			
		||||
@@ -175,6 +183,12 @@ PrometheusService::init(util::Config const& config)
 | 
			
		||||
    instance_ = std::make_unique<util::prometheus::PrometheusImpl>(enabled, compressReply);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
util::prometheus::Bool
 | 
			
		||||
PrometheusService::boolMetric(std::string name, util::prometheus::Labels labels, std::optional<std::string> description)
 | 
			
		||||
{
 | 
			
		||||
    return instance().boolMetric(std::move(name), std::move(labels), std::move(description));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
util::prometheus::CounterInt&
 | 
			
		||||
PrometheusService::counterInt(std::string name, util::prometheus::Labels labels, std::optional<std::string> description)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,7 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "util/config/Config.hpp"
 | 
			
		||||
#include "util/prometheus/Bool.hpp"
 | 
			
		||||
#include "util/prometheus/Counter.hpp"
 | 
			
		||||
#include "util/prometheus/Gauge.hpp"
 | 
			
		||||
#include "util/prometheus/Histogram.hpp"
 | 
			
		||||
@@ -54,6 +55,18 @@ public:
 | 
			
		||||
 | 
			
		||||
    virtual ~PrometheusInterface() = default;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Get a bool based metric. It will be created if it doesn't exist
 | 
			
		||||
     * @note Prometheus does not have a native bool type, so we use a counter with a value of 0 or 1
 | 
			
		||||
     *
 | 
			
		||||
     * @param name The name of the metric
 | 
			
		||||
     * @param labels The labels of the metric
 | 
			
		||||
     * @param description The description of the metric
 | 
			
		||||
     * @return The bool object
 | 
			
		||||
     */
 | 
			
		||||
    virtual Bool
 | 
			
		||||
    boolMetric(std::string name, Labels labels, std::optional<std::string> description = std::nullopt) = 0;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Get an integer based counter metric. It will be created if it doesn't exist
 | 
			
		||||
     *
 | 
			
		||||
@@ -176,6 +189,9 @@ class PrometheusImpl : public PrometheusInterface {
 | 
			
		||||
public:
 | 
			
		||||
    using PrometheusInterface::PrometheusInterface;
 | 
			
		||||
 | 
			
		||||
    Bool
 | 
			
		||||
    boolMetric(std::string name, Labels labels, std::optional<std::string> description = std::nullopt) override;
 | 
			
		||||
 | 
			
		||||
    CounterInt&
 | 
			
		||||
    counterInt(std::string name, Labels labels, std::optional<std::string> description) override;
 | 
			
		||||
 | 
			
		||||
@@ -242,6 +258,22 @@ public:
 | 
			
		||||
     */
 | 
			
		||||
    void static init(util::Config const& config = util::Config{});
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Get a bool based metric. It will be created if it doesn't exist
 | 
			
		||||
     * @note Prometheus does not have a native bool type, so we use a counter with a value of 0 or 1
 | 
			
		||||
     *
 | 
			
		||||
     * @param name The name of the metric
 | 
			
		||||
     * @param labels The labels of the metric
 | 
			
		||||
     * @param description The description of the metric
 | 
			
		||||
     * @return The bool object
 | 
			
		||||
     */
 | 
			
		||||
    static util::prometheus::Bool
 | 
			
		||||
    boolMetric(
 | 
			
		||||
        std::string name,
 | 
			
		||||
        util::prometheus::Labels labels,
 | 
			
		||||
        std::optional<std::string> description = std::nullopt
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Get an integer based counter metric. It will be created if it doesn't exist
 | 
			
		||||
     *
 | 
			
		||||
 
 | 
			
		||||
@@ -97,6 +97,7 @@ target_sources(
 | 
			
		||||
          util/BatchingTests.cpp
 | 
			
		||||
          util/LedgerUtilsTests.cpp
 | 
			
		||||
          # Prometheus support
 | 
			
		||||
          util/prometheus/BoolTests.cpp
 | 
			
		||||
          util/prometheus/CounterTests.cpp
 | 
			
		||||
          util/prometheus/GaugeTests.cpp
 | 
			
		||||
          util/prometheus/HistogramTests.cpp
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,6 @@
 | 
			
		||||
 | 
			
		||||
#include "util/TerminationHandler.hpp"
 | 
			
		||||
#include "util/TestGlobals.hpp"
 | 
			
		||||
#include "util/prometheus/Prometheus.hpp"
 | 
			
		||||
 | 
			
		||||
#include <gtest/gtest.h>
 | 
			
		||||
 | 
			
		||||
@@ -33,7 +32,6 @@ int
 | 
			
		||||
main(int argc, char* argv[])
 | 
			
		||||
{
 | 
			
		||||
    util::setTerminationHandler();
 | 
			
		||||
    PrometheusService::init();
 | 
			
		||||
    testing::InitGoogleTest(&argc, argv);
 | 
			
		||||
    TestGlobals::instance().parse(argc, argv);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,7 @@
 | 
			
		||||
#include "etl/impl/AmendmentBlock.hpp"
 | 
			
		||||
#include "util/FakeAmendmentBlockAction.hpp"
 | 
			
		||||
#include "util/Fixtures.hpp"
 | 
			
		||||
#include "util/MockPrometheus.hpp"
 | 
			
		||||
 | 
			
		||||
#include <boost/asio/io_context.hpp>
 | 
			
		||||
#include <gtest/gtest.h>
 | 
			
		||||
@@ -32,8 +33,7 @@
 | 
			
		||||
using namespace testing;
 | 
			
		||||
using namespace etl;
 | 
			
		||||
 | 
			
		||||
class AmendmentBlockHandlerTest : public NoLoggerFixture {
 | 
			
		||||
protected:
 | 
			
		||||
struct AmendmentBlockHandlerTest : util::prometheus::WithPrometheus, NoLoggerFixture {
 | 
			
		||||
    using AmendmentBlockHandlerType = impl::AmendmentBlockHandler<FakeAmendmentBlockAction>;
 | 
			
		||||
 | 
			
		||||
    boost::asio::io_context ioc_;
 | 
			
		||||
 
 | 
			
		||||
@@ -24,6 +24,7 @@
 | 
			
		||||
#include "etl/impl/FakeDiffProvider.hpp"
 | 
			
		||||
#include "util/Fixtures.hpp"
 | 
			
		||||
#include "util/MockCache.hpp"
 | 
			
		||||
#include "util/MockPrometheus.hpp"
 | 
			
		||||
#include "util/async/context/BasicExecutionContext.hpp"
 | 
			
		||||
#include "util/config/Config.hpp"
 | 
			
		||||
 | 
			
		||||
@@ -43,7 +44,7 @@ namespace {
 | 
			
		||||
 | 
			
		||||
constexpr auto SEQ = 30;
 | 
			
		||||
 | 
			
		||||
struct CacheLoaderTest : MockBackendTest {
 | 
			
		||||
struct CacheLoaderTest : util::prometheus::WithPrometheus, MockBackendTest {
 | 
			
		||||
    void
 | 
			
		||||
    SetUp() override
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,7 @@
 | 
			
		||||
#include "etl/impl/CursorProvider.hpp"
 | 
			
		||||
#include "etl/impl/FakeDiffProvider.hpp"
 | 
			
		||||
#include "util/Fixtures.hpp"
 | 
			
		||||
#include "util/MockPrometheus.hpp"
 | 
			
		||||
 | 
			
		||||
#include <gmock/gmock.h>
 | 
			
		||||
#include <gtest/gtest.h>
 | 
			
		||||
@@ -36,7 +37,7 @@ namespace {
 | 
			
		||||
 | 
			
		||||
constexpr auto SEQ = 30;
 | 
			
		||||
 | 
			
		||||
struct CursorProviderTest : MockBackendTestNaggy {
 | 
			
		||||
struct CursorProviderTest : util::prometheus::WithPrometheus, MockBackendTestNaggy {
 | 
			
		||||
    DiffProvider diffProvider;
 | 
			
		||||
};
 | 
			
		||||
struct ParametrizedCursorProviderTest : CursorProviderTest, WithParamInterface<std::size_t> {};
 | 
			
		||||
 
 | 
			
		||||
@@ -24,6 +24,7 @@
 | 
			
		||||
#include "util/MockExtractionDataPipe.hpp"
 | 
			
		||||
#include "util/MockLedgerFetcher.hpp"
 | 
			
		||||
#include "util/MockNetworkValidatedLedgers.hpp"
 | 
			
		||||
#include "util/MockPrometheus.hpp"
 | 
			
		||||
 | 
			
		||||
#include <gmock/gmock.h>
 | 
			
		||||
#include <gtest/gtest.h>
 | 
			
		||||
@@ -34,8 +35,7 @@
 | 
			
		||||
using namespace testing;
 | 
			
		||||
using namespace etl;
 | 
			
		||||
 | 
			
		||||
class ETLExtractorTest : public NoLoggerFixture {
 | 
			
		||||
protected:
 | 
			
		||||
struct ETLExtractorTest : util::prometheus::WithPrometheus, NoLoggerFixture {
 | 
			
		||||
    using ExtractionDataPipeType = MockExtractionDataPipe;
 | 
			
		||||
    using LedgerFetcherType = MockLedgerFetcher;
 | 
			
		||||
    using ExtractorType = etl::impl::Extractor<ExtractionDataPipeType, MockNetworkValidatedLedgers, LedgerFetcherType>;
 | 
			
		||||
@@ -48,7 +48,6 @@ protected:
 | 
			
		||||
 | 
			
		||||
    std::unique_ptr<ExtractorType> extractor_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    void
 | 
			
		||||
    SetUp() override
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,7 @@
 | 
			
		||||
#include "etl/impl/GrpcSource.hpp"
 | 
			
		||||
#include "util/Fixtures.hpp"
 | 
			
		||||
#include "util/MockBackend.hpp"
 | 
			
		||||
#include "util/MockPrometheus.hpp"
 | 
			
		||||
#include "util/MockXrpLedgerAPIService.hpp"
 | 
			
		||||
#include "util/TestObject.hpp"
 | 
			
		||||
#include "util/config/Config.hpp"
 | 
			
		||||
@@ -39,7 +40,9 @@
 | 
			
		||||
 | 
			
		||||
using namespace etl::impl;
 | 
			
		||||
 | 
			
		||||
struct GrpcSourceTests : NoLoggerFixture, unittests::util::WithMockXrpLedgerAPIService {
 | 
			
		||||
struct GrpcSourceTests : NoLoggerFixture,
 | 
			
		||||
                         util::prometheus::WithPrometheus,
 | 
			
		||||
                         unittests::util::WithMockXrpLedgerAPIService {
 | 
			
		||||
    GrpcSourceTests()
 | 
			
		||||
        : WithMockXrpLedgerAPIService("localhost:50051")
 | 
			
		||||
        , mockBackend_(std::make_shared<testing::StrictMock<MockBackend>>(util::Config{}))
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,7 @@
 | 
			
		||||
#include "etl/impl/LedgerPublisher.hpp"
 | 
			
		||||
#include "util/Fixtures.hpp"
 | 
			
		||||
#include "util/MockCache.hpp"
 | 
			
		||||
#include "util/MockPrometheus.hpp"
 | 
			
		||||
#include "util/MockSubscriptionManager.hpp"
 | 
			
		||||
#include "util/TestObject.hpp"
 | 
			
		||||
#include "util/config/Config.hpp"
 | 
			
		||||
@@ -49,7 +50,10 @@ static auto constexpr LEDGERHASH = "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A
 | 
			
		||||
static auto constexpr SEQ = 30;
 | 
			
		||||
static auto constexpr AGE = 800;
 | 
			
		||||
 | 
			
		||||
class ETLLedgerPublisherTest : public MockBackendTest, public SyncAsioContextTest, public MockSubscriptionManagerTest {
 | 
			
		||||
struct ETLLedgerPublisherTest : util::prometheus::WithPrometheus,
 | 
			
		||||
                                MockBackendTest,
 | 
			
		||||
                                SyncAsioContextTest,
 | 
			
		||||
                                MockSubscriptionManagerTest {
 | 
			
		||||
    void
 | 
			
		||||
    SetUp() override
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -25,6 +25,7 @@
 | 
			
		||||
#include "util/MockExtractionDataPipe.hpp"
 | 
			
		||||
#include "util/MockLedgerLoader.hpp"
 | 
			
		||||
#include "util/MockLedgerPublisher.hpp"
 | 
			
		||||
#include "util/MockPrometheus.hpp"
 | 
			
		||||
#include "util/StringUtils.hpp"
 | 
			
		||||
 | 
			
		||||
#include <gmock/gmock.h>
 | 
			
		||||
@@ -46,8 +47,7 @@ constexpr static auto RAW_HEADER =
 | 
			
		||||
    "3E2232B33EF57CECAC2816E3122816E31A0A00F8377CD95DFA484CFAE282656A58"
 | 
			
		||||
    "CE5AA29652EFFD80AC59CD91416E4E13DBBE";
 | 
			
		||||
 | 
			
		||||
class ETLTransformerTest : public MockBackendTest {
 | 
			
		||||
protected:
 | 
			
		||||
struct ETLTransformerTest : util::prometheus::WithPrometheus, MockBackendTest {
 | 
			
		||||
    using DataType = FakeFetchResponse;
 | 
			
		||||
    using ExtractionDataPipeType = MockExtractionDataPipe;
 | 
			
		||||
    using LedgerLoaderType = MockLedgerLoader;
 | 
			
		||||
@@ -64,7 +64,6 @@ protected:
 | 
			
		||||
 | 
			
		||||
    std::unique_ptr<TransformerType> transformer_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    void
 | 
			
		||||
    SetUp() override
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,7 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "util/Fixtures.hpp"
 | 
			
		||||
#include "util/MockPrometheus.hpp"
 | 
			
		||||
#include "util/MockWsBase.hpp"
 | 
			
		||||
#include "web/interface/ConnectionBase.hpp"
 | 
			
		||||
 | 
			
		||||
@@ -33,7 +34,7 @@
 | 
			
		||||
 | 
			
		||||
// Base class for feed tests, providing easy way to access the received feed
 | 
			
		||||
template <typename TestedFeed>
 | 
			
		||||
class FeedBaseTest : public SyncAsioContextTest, public MockBackendTest {
 | 
			
		||||
class FeedBaseTest : public util::prometheus::WithPrometheus, public SyncAsioContextTest, public MockBackendTest {
 | 
			
		||||
protected:
 | 
			
		||||
    std::shared_ptr<web::ConnectionBase> sessionPtr;
 | 
			
		||||
    std::shared_ptr<TestedFeed> testFeedPtr;
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,7 @@
 | 
			
		||||
#include "feed/FeedTestUtil.hpp"
 | 
			
		||||
#include "feed/SubscriptionManager.hpp"
 | 
			
		||||
#include "util/Fixtures.hpp"
 | 
			
		||||
#include "util/MockPrometheus.hpp"
 | 
			
		||||
#include "util/MockWsBase.hpp"
 | 
			
		||||
#include "util/TestObject.hpp"
 | 
			
		||||
#include "web/interface/ConnectionBase.hpp"
 | 
			
		||||
@@ -52,7 +53,9 @@ namespace json = boost::json;
 | 
			
		||||
using namespace feed;
 | 
			
		||||
using namespace feed::impl;
 | 
			
		||||
 | 
			
		||||
class SubscriptionManagerTest : public MockBackendTest, public SyncAsioContextTest {
 | 
			
		||||
class SubscriptionManagerTest : public util::prometheus::WithPrometheus,
 | 
			
		||||
                                public MockBackendTest,
 | 
			
		||||
                                public SyncAsioContextTest {
 | 
			
		||||
protected:
 | 
			
		||||
    std::shared_ptr<SubscriptionManager> SubscriptionManagerPtr;
 | 
			
		||||
    std::shared_ptr<web::ConnectionBase> session;
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,7 @@
 | 
			
		||||
#include "rpc/RPCHelpers.hpp"
 | 
			
		||||
#include "rpc/common/Types.hpp"
 | 
			
		||||
#include "util/Fixtures.hpp"
 | 
			
		||||
#include "util/MockPrometheus.hpp"
 | 
			
		||||
#include "util/TestObject.hpp"
 | 
			
		||||
 | 
			
		||||
#include <boost/asio/impl/spawn.hpp>
 | 
			
		||||
@@ -57,7 +58,7 @@ constexpr static auto INDEX1 = "E6DBAFC99223B42257915A63DFC6B0C032D4070F9A574B25
 | 
			
		||||
constexpr static auto INDEX2 = "E6DBAFC99223B42257915A63DFC6B0C032D4070F9A574B255AD97466726FC322";
 | 
			
		||||
constexpr static auto TXNID = "E6DBAFC99223B42257915A63DFC6B0C032D4070F9A574B255AD97466726FC321";
 | 
			
		||||
 | 
			
		||||
class RPCHelpersTest : public MockBackendTest, public SyncAsioContextTest {
 | 
			
		||||
class RPCHelpersTest : public util::prometheus::WithPrometheus, public MockBackendTest, public SyncAsioContextTest {
 | 
			
		||||
    void
 | 
			
		||||
    SetUp() override
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,6 @@
 | 
			
		||||
#include "rpc/common/Types.hpp"
 | 
			
		||||
#include "rpc/handlers/Subscribe.hpp"
 | 
			
		||||
#include "util/Fixtures.hpp"
 | 
			
		||||
#include "util/MockPrometheus.hpp"
 | 
			
		||||
#include "util/MockWsBase.hpp"
 | 
			
		||||
#include "util/TestObject.hpp"
 | 
			
		||||
#include "web/interface/ConnectionBase.hpp"
 | 
			
		||||
@@ -62,7 +61,7 @@ constexpr static auto PAYS20XRPGETS10USDBOOKDIR = "7B1767D41DBCE79D9585CF9D0262A
 | 
			
		||||
constexpr static auto INDEX1 = "1B8590C01B0006EDFA9ED60296DD052DC5E90F99659B25014D08E1BC983515BC";
 | 
			
		||||
constexpr static auto INDEX2 = "E6DBAFC99223B42257915A63DFC6B0C032D4070F9A574B255AD97466726FC321";
 | 
			
		||||
 | 
			
		||||
class RPCSubscribeHandlerTest : public util::prometheus::WithPrometheus, public HandlerBaseTest {
 | 
			
		||||
class RPCSubscribeHandlerTest : public HandlerBaseTest {
 | 
			
		||||
protected:
 | 
			
		||||
    void
 | 
			
		||||
    SetUp() override
 | 
			
		||||
 
 | 
			
		||||
@@ -24,6 +24,7 @@
 | 
			
		||||
#include "util/MockCounters.hpp"
 | 
			
		||||
#include "util/MockETLService.hpp"
 | 
			
		||||
#include "util/MockLoadBalancer.hpp"
 | 
			
		||||
#include "util/MockPrometheus.hpp"
 | 
			
		||||
#include "util/MockSubscriptionManager.hpp"
 | 
			
		||||
#include "util/log/Logger.hpp"
 | 
			
		||||
 | 
			
		||||
@@ -349,6 +350,7 @@ protected:
 | 
			
		||||
 */
 | 
			
		||||
template <template <typename> typename MockType = ::testing::NiceMock>
 | 
			
		||||
struct HandlerBaseTestBase : public MockBackendTestBase<MockType>,
 | 
			
		||||
                             public util::prometheus::WithPrometheus,
 | 
			
		||||
                             public SyncAsioContextTest,
 | 
			
		||||
                             public MockETLServiceTest {
 | 
			
		||||
protected:
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,7 @@
 | 
			
		||||
 | 
			
		||||
#include "util/Assert.hpp"
 | 
			
		||||
#include "util/config/Config.hpp"
 | 
			
		||||
#include "util/prometheus/Bool.hpp"
 | 
			
		||||
#include "util/prometheus/Counter.hpp"
 | 
			
		||||
#include "util/prometheus/Gauge.hpp"
 | 
			
		||||
#include "util/prometheus/Histogram.hpp"
 | 
			
		||||
@@ -81,6 +82,10 @@ using MockHistogramImplDouble = MockHistogramImpl<double>;
 | 
			
		||||
struct MockPrometheusImpl : PrometheusInterface {
 | 
			
		||||
    MockPrometheusImpl() : PrometheusInterface(true, true)
 | 
			
		||||
    {
 | 
			
		||||
        EXPECT_CALL(*this, boolMetric)
 | 
			
		||||
            .WillRepeatedly([this](std::string name, Labels labels, std::optional<std::string>) -> Bool {
 | 
			
		||||
                return Bool{getMetric<GaugeInt>(std::move(name), std::move(labels))};
 | 
			
		||||
            });
 | 
			
		||||
        EXPECT_CALL(*this, counterInt)
 | 
			
		||||
            .WillRepeatedly([this](std::string name, Labels labels, std::optional<std::string>) -> CounterInt& {
 | 
			
		||||
                return getMetric<CounterInt>(std::move(name), std::move(labels));
 | 
			
		||||
@@ -109,6 +114,7 @@ struct MockPrometheusImpl : PrometheusInterface {
 | 
			
		||||
            );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    MOCK_METHOD(Bool, boolMetric, (std::string, Labels, std::optional<std::string>), (override));
 | 
			
		||||
    MOCK_METHOD(CounterInt&, counterInt, (std::string, Labels, std::optional<std::string>), (override));
 | 
			
		||||
    MOCK_METHOD(CounterDouble&, counterDouble, (std::string, Labels, std::optional<std::string>), (override));
 | 
			
		||||
    MOCK_METHOD(GaugeInt&, gaugeInt, (std::string, Labels, std::optional<std::string>), (override));
 | 
			
		||||
@@ -252,7 +258,7 @@ struct WithPrometheus : virtual ::testing::Test {
 | 
			
		||||
 | 
			
		||||
    ~WithPrometheus() override
 | 
			
		||||
    {
 | 
			
		||||
        PrometheusService::init();
 | 
			
		||||
        PrometheusService::replaceInstance(nullptr);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										63
									
								
								unittests/util/prometheus/BoolTests.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								unittests/util/prometheus/BoolTests.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
/*
 | 
			
		||||
    This file is part of clio: https://github.com/XRPLF/clio
 | 
			
		||||
    Copyright (c) 2024, the clio developers.
 | 
			
		||||
 | 
			
		||||
    Permission to use, copy, modify, and distribute this software for any
 | 
			
		||||
    purpose with or without fee is hereby granted, provided that the above
 | 
			
		||||
    copyright notice and this permission notice appear in all copies.
 | 
			
		||||
 | 
			
		||||
    THE  SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
			
		||||
    WITH  REGARD  TO  THIS  SOFTWARE  INCLUDING  ALL  IMPLIED  WARRANTIES  OF
 | 
			
		||||
    MERCHANTABILITY  AND  FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
			
		||||
    ANY  SPECIAL,  DIRECT,  INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
			
		||||
    WHATSOEVER  RESULTING  FROM  LOSS  OF USE, DATA OR PROFITS, WHETHER IN AN
 | 
			
		||||
    ACTION  OF  CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 | 
			
		||||
    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
			
		||||
*/
 | 
			
		||||
//==============================================================================
 | 
			
		||||
 | 
			
		||||
#include "util/prometheus/Bool.hpp"
 | 
			
		||||
#include "util/prometheus/Gauge.hpp"
 | 
			
		||||
 | 
			
		||||
#include <gmock/gmock.h>
 | 
			
		||||
#include <gtest/gtest.h>
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
 | 
			
		||||
using namespace util::prometheus;
 | 
			
		||||
using testing::StrictMock;
 | 
			
		||||
 | 
			
		||||
struct BoolTests : public testing::Test {
 | 
			
		||||
    struct MockImpl {
 | 
			
		||||
        MOCK_METHOD(void, set, (int64_t), ());
 | 
			
		||||
        MOCK_METHOD(int64_t, value, (), ());
 | 
			
		||||
    };
 | 
			
		||||
    StrictMock<MockImpl> impl_;
 | 
			
		||||
    AnyBool<StrictMock<MockImpl>> bool_{impl_};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
TEST_F(BoolTests, Set)
 | 
			
		||||
{
 | 
			
		||||
    EXPECT_CALL(impl_, set(1));
 | 
			
		||||
    bool_ = true;
 | 
			
		||||
 | 
			
		||||
    EXPECT_CALL(impl_, set(0));
 | 
			
		||||
    bool_ = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_F(BoolTests, Get)
 | 
			
		||||
{
 | 
			
		||||
    EXPECT_CALL(impl_, value()).WillOnce(testing::Return(1));
 | 
			
		||||
    EXPECT_TRUE(bool_);
 | 
			
		||||
 | 
			
		||||
    EXPECT_CALL(impl_, value()).WillOnce(testing::Return(0));
 | 
			
		||||
    EXPECT_FALSE(bool_);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_F(BoolTests, DefaultValues)
 | 
			
		||||
{
 | 
			
		||||
    GaugeInt gauge{"test", ""};
 | 
			
		||||
    Bool realBool{gauge};
 | 
			
		||||
    EXPECT_FALSE(realBool);
 | 
			
		||||
}
 | 
			
		||||
@@ -70,6 +70,13 @@ TEST_F(AnyCounterTests, operatorAdd)
 | 
			
		||||
    counter += 42;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_F(AnyCounterTests, set)
 | 
			
		||||
{
 | 
			
		||||
    EXPECT_CALL(mockCounterImpl, value()).WillOnce(::testing::Return(4));
 | 
			
		||||
    EXPECT_CALL(mockCounterImpl, set(42));
 | 
			
		||||
    counter.set(42);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_F(AnyCounterTests, reset)
 | 
			
		||||
{
 | 
			
		||||
    EXPECT_CALL(mockCounterImpl, set(0));
 | 
			
		||||
@@ -82,6 +89,20 @@ TEST_F(AnyCounterTests, value)
 | 
			
		||||
    EXPECT_EQ(counter.value(), 42);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct AnyCounterDeathTest : AnyCounterTests {};
 | 
			
		||||
 | 
			
		||||
TEST_F(AnyCounterDeathTest, setLowerValue)
 | 
			
		||||
{
 | 
			
		||||
    testing::Mock::AllowLeak(&mockCounterImpl);
 | 
			
		||||
    EXPECT_DEATH(
 | 
			
		||||
        {
 | 
			
		||||
            EXPECT_CALL(mockCounterImpl, value()).WillOnce(::testing::Return(50));
 | 
			
		||||
            counter.set(42);
 | 
			
		||||
        },
 | 
			
		||||
        ".*"
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct CounterIntTests : ::testing::Test {
 | 
			
		||||
    CounterInt counter{"test_counter", R"(label1="value1",label2="value2")"};
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -128,10 +128,22 @@ TEST_F(GaugeIntTests, multithreadAddAndSubstract)
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_F(GaugeIntTests, DefaultValue)
 | 
			
		||||
{
 | 
			
		||||
    GaugeInt realGauge{"some_gauge", ""};
 | 
			
		||||
    EXPECT_EQ(realGauge.value(), 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct GaugeDoubleTests : ::testing::Test {
 | 
			
		||||
    GaugeDouble gauge{"test_Gauge", R"(label1="value1",label2="value2")"};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
TEST_F(GaugeDoubleTests, DefaultValue)
 | 
			
		||||
{
 | 
			
		||||
    GaugeDouble realGauge{"some_gauge", ""};
 | 
			
		||||
    EXPECT_EQ(realGauge.value(), 0.);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_F(GaugeDoubleTests, operatorAdd)
 | 
			
		||||
{
 | 
			
		||||
    ++gauge;
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,7 @@
 | 
			
		||||
#include "rpc/Errors.hpp"
 | 
			
		||||
#include "util/Fixtures.hpp"
 | 
			
		||||
#include "util/MockETLService.hpp"
 | 
			
		||||
#include "util/MockPrometheus.hpp"
 | 
			
		||||
#include "util/MockRPCEngine.hpp"
 | 
			
		||||
#include "util/Taggable.hpp"
 | 
			
		||||
#include "util/config/Config.hpp"
 | 
			
		||||
@@ -65,7 +66,9 @@ struct MockWsBase : public web::ConnectionBase {
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class WebRPCServerHandlerTest : public MockBackendTest, public SyncAsioContextTest {
 | 
			
		||||
class WebRPCServerHandlerTest : public util::prometheus::WithPrometheus,
 | 
			
		||||
                                public MockBackendTest,
 | 
			
		||||
                                public SyncAsioContextTest {
 | 
			
		||||
protected:
 | 
			
		||||
    void
 | 
			
		||||
    SetUp() override
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user